[英]Child component doesn't get updated when props changes
I am having trouble understanding how vue js's reactivity work.我无法理解 vue js 的反应性如何工作。 I am trying to make a component for all kinds of ajax call, the problem is when I change the props to be passed on to the component it doesn't get the changes in the data.
我正在尝试为各种 ajax 调用制作一个组件,问题是当我更改要传递给组件的道具时,它不会更改数据。
https://jsfiddle.net/8t4vx44r/34/ https://jsfiddle.net/8t4vx44r/34/
Vue.component('api-call-template', { template: '#api-call-templates', props: { apiCallParams: Object }, data () { return { result: [], loading: false } }, created() { console.log("entered?") console.log(this.apiCallParams); var vm = this; vm.loading = true; axios({ method: this.apiCallParams.method, url: this.apiCallParams.url, data: this.apiCallParams.params }).then(function(response) { vm.result = response.data; vm.loading = false; vm.$emit('get-response', response); }); console.log(vm.loading) } }); var vm = new Vue({ el: '#app', data: { apiCallParams: { url: '', method: '', params: {} }, author: 'aa' }, created() { this.apiCallParams.url = 'https://reqres.in/api/users/1'; this.apiCallParams.method = 'get'; console.log("passing this"); console.log(this.apiCallParams); }, methods: { search() { console.log("searching") this.url = 'https://reqres.in/api/users/2'; this.apiCallParams.method = 'get'; }, getResponse(response) { console.log("back to parent"); console.log(response); } } });
<script src="https://unpkg.com/axios@0.18.0/dist/axios.min.js"></script> <script src="https://unpkg.com/vue@2.5.13/dist/vue.js"></script> <div id="app"> try {{title}} <post :title="title" :author="author" :content="content"> </post> </div> <template id="post-template"> <h1>{{ title }}</h1> <h4>{{ author }}</h4> <p>{{ content }}</p> </template>
If you click the "next user button" it updates the data in the parent component but it doesn't call my api-call-template.如果您单击“下一个用户按钮”,它会更新父组件中的数据,但不会调用我的 api-call-template。
You are only calling one time because your logic is at created()
, which is called only once (when the component is created).您只调用一次,因为您的逻辑位于
created()
,它只调用一次(在创建组件时)。
Considering your component is:考虑您的组件是:
<api-call-template :api-call-params="apiCallParams" @get-response="getResponse">...
And you want to request every time api-call-params
changes.并且您想在每次
api-call-params
更改时进行请求。 What you could do is:你可以做的是:
created()
to a method, say performRequest()
created()
移到一个方法,比如performRequest()
this.performRequest()
on created()
created()
上调用this.performRequest()
created()
apiCallParams
propapiCallParams
道具添加一个观察者this.performRequest()
on apiCallParams
watcherapiCallParams
观察者上调用this.performRequest()
See demo below.请参阅下面的演示。
Vue.component('api-call-template', { template: '#api-call-templates', props: { apiCallParams: Object }, data() { return { result: [], loading: false } }, methods: { performRequest() { console.log("entered?") console.log(this.apiCallParams); var vm = this; vm.loading = true; axios({ method: this.apiCallParams.method, url: this.apiCallParams.url, data: this.apiCallParams.params }).then(function(response) { vm.result = response.data; vm.loading = false; vm.$emit('get-response', response); }); console.log(vm.loading) } }, created() { this.performRequest(); }, watch: { apiCallParams() { this.performRequest(); } } }); var vm = new Vue({ el: '#app', data: { apiCallParams: { url: '', method: '', params: {} } }, created() { this.apiCallParams = {url: 'https://reqres.in/api/users/1', method: 'get'} console.log("passing this"); console.log(this.apiCallParams); }, methods: { search() { console.log("searching") this.apiCallParams = {url: 'https://reqres.in/api/users/2', method: 'get'}; }, getResponse(response) { console.log("back to parent"); console.log(response); } } });
<script src="https://unpkg.com/axios@0.18.0/dist/axios.min.js"></script> <script src="https://unpkg.com/vue@2.5.13/dist/vue.js"></script> <div id="app"> <button @click="search">next user</button> <api-call-template :api-call-params="apiCallParams" @get-response="getResponse"></api-call-template> </div> <template id="api-call-templates"> <div> <main> <div v-if="loading">loading</div> <div class="wrapper"> <div class="row"> <div v-for="res in result" :key="res.id"> <div class="col-md-4 cards"> <div> results <h3>{{ res.first_name }}</h3> </div> </div> </div> </div> </div> </main> </div> </template>
There is only one caveat: to trigger the watch, change apiCallParams
at once, like:只有一个警告:要触发监视,请立即更改
apiCallParams
,例如:
this.apiCallParams = {url: 'https://reqres.in/api/users/2', method: 'get'};
Not property by property, like:不是逐个财产,例如:
this.apiCallParams.url = 'https://reqres.in/api/users/2'; // don't do like this
this.apiCallParams.method = 'get'; // don't do like this
As Vue won't pick up changes if you do it prop by prop.因为如果你逐个执行,Vue 不会接受更改。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.