当道具改变时,子组件不会更新

问题描述 投票:1回答:1

我无法理解vue js的反应性如何起作用。我正在尝试为各种ajax调用创建一个组件,问题是当我更改要传递给组件的props时,它不会获得数据中的更改。

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/[email protected]/dist/axios.min.js"></script>
<script src="https://unpkg.com/[email protected]/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。

javascript vue.js vuejs2 vue-component axios
1个回答
1
投票

您只调用一次,因为您的逻辑位于created(),只调用一次(创建组件时)。

考虑到您的组件是:

<api-call-template :api-call-params="apiCallParams" @get-response="getResponse">...

并且您想要每次api-call-params变化请求。你能做的是:

  • 将你的逻辑从created()移到一个方法,比如performRequest()
  • this.performRequest()上打电话给created()
  • 添加观察者到apiCallParams道具
  • this.performRequest()观察者上打电话给apiCallParams

见下面的演示。

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/[email protected]/dist/axios.min.js"></script>
<script src="https://unpkg.com/[email protected]/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将不会接受改变。

© www.soinside.com 2019 - 2024. All rights reserved.