【问题标题】:Vuejs - How to communicate changes between parent and child in scoped slotsVuejs - 如何在作用域插槽中传达父子之间的更改
【发布时间】:2017-09-29 16:44:58
【问题描述】:

我正在尝试创建一个有两个插槽的组件。第二个插槽根据第一个插槽中的项目数重复。我已经使用作用域插槽实现了这一点,但是,当数据在第一个插槽上更新时,第二个插槽不会自动更新它,直到触发事件,例如:单击调用方法的按钮。

有没有办法让第二个插槽在第一个插槽上的数据发生更改时更新其视图?

这是我的例子:

Jsfiddle:https://jsfiddle.net/89vykm75/1/

new Vue({
	el: '#app',
  components: {
  	'repeat-for-each-item': {
      data: function() {
          return {
              items: []
          }
      },
    	template: `<div>
          <slot name="item" v-for="item in items" :item="item"></slot>
          <button @click="addItem()">Add item</button>
          <slot name="repeat" v-for="item in items" :item="item"></slot>
      </div>
      `,
      methods: {
        addItem() {
          this.items.push({});
        }
      }
    }
  }
});
<div id="app">
  <repeat-for-each-item>
    <template slot="item" scope="props">
      <div>
        <input type="text" v-model="props.item.name">
      </div>
    </template>
    
    <template slot="repeat" scope="props">
      <div>
        <label>
            <span v-if="props.item.name">{{props.item.name}}:</span>
            <span v-else>No Name:</span>
        </label>
        <input type="text">
      </div>
    </template>
  </repeat-for-each-item>
</div>

【问题讨论】:

    标签: javascript vue.js vuejs2


    【解决方案1】:

    我通过调用 keyup 上的方法找到了解决方案。

    基本上,我在插槽上添加了@keyup 事件

    <input type="text" v-model="props.item.name" @keyup="props.onchange()">
    

    并且在组件模板上,将onchange方法传递给槽

    <slot name="item" v-for="item in items" :item="item" :onchange="onchange"></slot>
    

    然后有onchange函数强制重新渲染

    onchange:() => {
        // hack to trigger changes
        this.$set(this.items, 0, this.items[0]);
    }
    

    这是完整的工作 JsFiddle:https://jsfiddle.net/89vykm75/2/

    我想知道是否有更清洁的解决方案?

    【讨论】:

      【解决方案2】:

      你陷入了 Vue change detection caveat。这里的问题是,如果您将属性添加到在对象添加到 Vue 数据之前不存在的对象,那么 Vue 无法检测到更改。问题来了:

      this.items.push({})
      

      您正在添加一个没有属性的对象,然后将v-model 绑定到该对象的name 属性,该属性不存在。 Vue 无法检测到更改,并且不会更新绑定到该属性的其他项。

      如果您改为这样做:

      this.items.push({name: null})
      

      您会发现您的代码有效。这是更新后的fiddle

      【讨论】:

      • 这太棒了,非常感谢!我还有很多东西要学:)
      猜你喜欢
      • 2018-03-14
      • 2018-02-21
      • 2019-07-17
      • 2018-11-11
      • 2019-04-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-24
      相关资源
      最近更新 更多