道具更改时子组件不会更新
Posted
技术标签:
【中文标题】道具更改时子组件不会更新【英文标题】:Child component doesn't get updated when props changes 【发布时间】:2018-08-09 01:18:42 【问题描述】:我无法理解 vue js 的反应性如何工作。我正在尝试为各种 ajax 调用制作一个组件,问题是当我更改要传递给组件的道具时,它不会得到数据的更改。
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>
如果您单击“下一个用户按钮”,它会更新父组件中的数据,但不会调用我的 api-call-template。
【问题讨论】:
【参考方案1】:您只调用一次,因为您的逻辑位于created()
,它只被调用一次(在创建组件时)。
考虑到您的组件是:
<api-call-template :api-call-params="apiCallParams" @get-response="getResponse">...
并且您想在每次api-call-params
更改时请求。你可以做的是:
created()
移动到一个方法,例如performRequest()
致电this.performRequest()
created()
为apiCallParams
prop 添加观察者
在apiCallParams
观察者上致电this.performRequest()
请看下面的演示。
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>
只有一个警告:可以触发手表,立即更改apiCallParams
,例如:
this.apiCallParams = url: 'https://reqres.in/api/users/2', method: 'get';
不是逐个属性,例如:
this.apiCallParams.url = 'https://reqres.in/api/users/2'; // don't do like this
this.apiCallParams.method = 'get'; // don't do like this
因为如果你逐个属性地做,Vue 不会接受更改。
【讨论】:
以上是关于道具更改时子组件不会更新的主要内容,如果未能解决你的问题,请参考以下文章
高阶组件状态正在正确更新,但接收道具的包装组件不会在状态更改时重新渲染