如何从孩子向父母的父母发送数据

时间:2020-03-24 20:39:30

标签: javascript vue.js vuejs2 vue-component

我们将此称为my-input.vue组件

<input :value="value" v-on:input="input($event.target.value)" @focus="focus">

    export default {
        props: {
            value: {
                type: String,
                required: false,
                default: ''
            }
        },

        methods: {
            focus() {
                this.$emit('focus');
                this.$parent.$emit('focus');
            },
        }

    }

我们将此称为my-field.vue组件。

<div class="field-container" :class="{ focused, filled }">
    <slot />
</div>

export default {
        data(){
            return {
                focused: false,
            }
        },
        created() {
            this.$on('focus', () => {
                this.focused = true
            })
        }
    }

,我们将其称为final.vue组件。

<my-field>
     <my-input v-model="test"/>
</my-field>

事情在final.vue中,这是我遵循的技术。现在,我想不再使用this.$parent.emit('focus')组件中的my-input.vue,因为它们是紧密耦合的。对这个问题有什么好的解决办法吗?

2 个答案:

答案 0 :(得分:1)

您在这里有2个选择:

  1. 发射给父对象,然后再次从父对象发射。这是完全有效的选项,并且有效。 this。$ parent。$ emit不好,因为它假设会有祖父母在听,并且在某一点或另一点会变得一团糟。

  2. 向$ root发射:this.$root.$emit也是有效的选项,在发出一个以上级别的发射时很有用,但是请确保您只有一个侦听器,或者知道发射之间的差异-通常我们在顶级组件上使用这种方法。

更新
根据您的情况,您可以执行以下操作。

<my-field : focused="focused">
    <my-input v-model="test" @focus="onFocus" />
</my-field>

methods() {
    onFocus(){ this.focused = true }
}

也可以在这里查看:https://github.com/vuejs/vue/issues/4332
但是不幸的是,您选择的插槽非常有限。

答案 1 :(得分:1)

您可以通过以下方式避免两个 components 的紧密耦合

由于my-input基本组件,请避免将其限制为自定义attr / prop / event,因为它也有自己的attr /事件集,让我们bind 它们全部用于所有情况(通用)。

my-input.vue

<input v-bind="$attrs" v-on="$listeners">
export default {}

让我们将此作为无状态组件并由父级控制 通过props,这将使其更通用。

my-field.vue

<div class="field-container" :class="{ Focused }">
 <slot/>
</div>

export default {
   props: ["Focused"]
}

让它成为 intelligent 组件,由logic / state控制两者 哑巴 组件。

final.vue

<my-field :Focused="focused">
 <my-input v-model="test" @focus="focused = true" @blur="focused = false"/>
</my-field>

export default {
 data () {
  return {
   test: '',
   focused: false
  }
 }
}