I am having trouble understanding how vue js's reactivity work. 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.
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.
You are only calling one time because your logic is at created()
, which is called only once (when the component is 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. What you could do is:
created()
to a method, say performRequest()
this.performRequest()
on created()
apiCallParams
propthis.performRequest()
on apiCallParams
watcherSee 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:
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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.