【问题标题】: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。

【问题讨论】:

    标签: javascript vue.js vuejs2 vue-component axios


    【解决方案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 不会接受更改。

    【讨论】:

      猜你喜欢
      • 2020-01-19
      • 1970-01-01
      • 2020-06-17
      • 2021-02-25
      • 2019-03-03
      • 1970-01-01
      • 1970-01-01
      • 2020-05-01
      • 2021-09-01
      相关资源
      最近更新 更多