如何在VueJs中的独立子组件中设置值?

时间:2017-06-12 04:03:53

标签: vue.js vuejs2 vue-component vuex

我有一个内联编辑组件,与其他组件没有任何依赖关系。在一种情况下,我希望从父组件触发组件的编辑视图。

该组件使用一个名为editing的变量来切换编辑视图

// my-parent-component template
<div>
    <editable v-for="item in items" v-model="item" type="text">
    </editable>
</div>

// my-editing-component template
<div>
    <div v-if="!editing" v-text="value" @click="edit"></div>
    <div v-if="editing"><input v-model="value" @keydown.enter="done"/></div>
</div>

可编辑组件

export default {
    name : 'editable',
    props: ['value','type']
    data : function(){
        return {
            editing: false;
        }
    }
    methods : {
        edit(){
            this.editing = true;
        },
        done(){
            this.editing = false;
        }
    }

}

现在的挑战是我有一个enter密钥的全局监听器,我在父组件中维护“活动”项的索引。

当用户点击进入时,我想触发编辑活动的“项目”。

我可以将其作为

传递
<editable v-for="(item,index) in items" v-model="item" :editing="index == active" ></editable>

但是,支持“编辑”不会出现在我使用可编辑组件的其他地方

可以像这样从父级设置属性:this.$refs.editable.editing = true

从文档中我了解到无法将事件发送到子组件。

这样做的最佳方式是什么?

1 个答案:

答案 0 :(得分:2)

通常你应该将道具传递给子组件以控制它们的状态。但是如果你想要一个hacky访问子状态,有几种解决方法:

  1. 对儿童使用ref指针(虽然它需要实际放置ref),

  2. 使用this.$children访问组件的子女。

  3. this.$children可能需要一些额外的逻辑,您可以决定需要访问的数组索引。这取决于你的申请。

    用法示例:

    &#13;
    &#13;
    new Vue({
      el: '#app',
      methods: {
        toggleChild: function() {
          this.$refs['editMe'].editable = !this.$refs['editMe'].editable;
          // different approach without 'ref':
          // this.$children[0].editable = !this.$children[0].editable;
        }
      },
      components: {
        'child' : {
          template: `<p>{{ editable }}</p>`,
          data: function() {
          	return {
              editable: false
            }
          }
        }
      }
    });
    &#13;
    <script src="https://unpkg.com/vue/dist/vue.js"></script>
    
    <div id="app">
      <child ref="editMe"></child>
      <button @click="toggleChild">Toggle editable inside child</button>
    </div>
    &#13;
    &#13;
    &#13;