【问题标题】:Vue.js: correct way of changing a component prop from inside its methodVue.js:从其方法内部更改组件道具的正确方法
【发布时间】:2018-03-21 23:17:27
【问题描述】:

我有以下 Vue.js 组件的代码:

var list = Vue.component('list', {
  props: ['items', 'headertext', 'placeholder'],
  template: `
    <div class="col s6">
      <div class="search">
        <searchbox v-bind:placeholder=placeholder></searchbox>

        <ul class="collection with-header search-results">
          <li class="collection-header"><p>{{ headertext }}</p></li>
          <collection-item
            v-for="item in items"
            v-bind:texto="item.nome"
            v-bind:link="item.link"
            v-bind:key="item.id"
          >
          </collection-item>
        </ul>
      </div>
    </div>`,

  methods: {
    atualizaBibliografiasUsandoHipotese: function (value) {
      var query = gql`query {
        allHipotese(nome: "${value}") {
          id
          nome
          bibliografiasDestaque {
            id
            nome
            link
            descricao
          }
        }
      }`;
      client.query({ query }).then(function(results) {
        this.items = results['data']['allHipotese'][0]['bibliografiasDestaque'];
      }.bind(this));
    },
  }

});

在组件之外,在另一个 javascript 文件中,我调用 atualizaBibliografiasUsandoHipotese 方法对后端 (GraphQL) 进行查询,并更新组件。这工作正常,但是我从 Vue 收到警告消息说

[Vue 警告]:避免直接改变一个 prop,因为它的值是 每当父组件重新渲染时被覆盖。相反,使用 基于道具值的数据或计算属性。道具存在 变异:“项目”

我多次尝试修复此警告,但均未奏效。任何人都可以帮助我解决这个警告吗?谢谢

【问题讨论】:

  • 由于您正在修改从父组件传递下来的道具,因此您应该修改作为道具传递给子组件的父组件中的数据(因此您不会改变继承道具,但作为道具传递的预先存在的父数据)。换个角度想一想:继承的 prop 来自一个“事实来源”,即来自父级。所以更新父级是有意义的。
  • Vue.js Changing props的可能重复

标签: javascript vue.js vuejs2 vue-component


【解决方案1】:

这就是你要找的:

https://vuejs.org/v2/guide/components.html#One-Way-Data-Flow

它甚至说:

这意味着你不应该尝试改变孩子内部的道具 零件。如果你这样做了,Vue 会在控制台中警告你。

【讨论】:

    【解决方案2】:

    如前所述,您不应该改变 props,而是可以这样做:

    var list = Vue.component('list', {
        props: ['items', 'headertext', 'placeholder'],
        template: `
          <div class="col s6">
            <div class="search">
              <searchbox v-bind:placeholder=placeholder></searchbox>
              <ul class="collection with-header search-results">
                <li class="collection-header"><p>{{ headertext }}</p></li>
                <collection-item 
                  v-for="item in myItems"
                  v-bind:texto="item.nome"
                  v-bind:link="item.link"
                  v-bind:key="item.id"
                >
                </collection-item>
              </ul>
            </div>
          </div>`,
    
        data: ()=> { return { 
                myItems: this.items
            }
        },
    
        methods: {
            atualizaBibliografiasUsandoHipotese: function (value) {
                // Your Code
                this.myItems = results['data']['allHipotese'][0]['bibliografiasDestaque'];
            }.bind(this));
        },
    });
    

    注意v-for 现在在myItems 中循环items。

    【讨论】:

    • 成功了!最后我的问题是v-for:我使用的是v-for="item in items",而我应该使用v-for="item in myItems",正如你在sn-p中演示的那样。谢谢大佬!
    • @Vini.g.fer 我应该强调v-for 应该循环覆盖myItems
    猜你喜欢
    • 2014-03-07
    • 1970-01-01
    • 2021-05-26
    • 2015-10-18
    • 2018-03-13
    • 2021-05-21
    • 2017-06-05
    相关资源
    最近更新 更多