简体   繁体   English

道具更改时子组件不会更新

[英]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:你可以做的是:

  • Move your logic from created() to a method, say performRequest()将你的逻辑从created()移到一个方法,比如performRequest()
  • Call this.performRequest() on created()created()上调用this.performRequest() created()
  • Add a watcher to apiCallParams propapiCallParams道具添加一个观察者
  • Call 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM