【问题标题】:Vue - v-model inside a component within a componentVue - 组件内组件内的 v-model
【发布时间】:2020-06-07 20:37:25
【问题描述】:

我现在正尝试将我的项目分成组件,以便在调整为响应式应用程序时使代码可读。问题是从 base-select -> child -> parent 传递v-model。如何将选择的数据存储到Parent.vueitems: ''?下面是我的代码。

Parent.vue

<template>
  <child></child>
</template>

<script>
import Child from './components/Child'

export default {
  components: { 
    Child,
  },
  data: ()=> ({
    item: ''
  })
}
</script>

Child.vue

<template>
  // Random HTML
  // Random HTML 2
  <base-select 
  :items="select"
  >
</template>

<script>
import BaseSelect from '@/components/BaseSelect'

export default {
  components: { 
    BaseSelect,
  },
  data: ()=> ({
    select: ['Select 1', 'Select 2']
  })
}
</script>

BaseSelect.vue

<template>
  <v-select
    v-bind="$attrs"
    v-on="$listeners"
    class="body-2"
    solo
    dense
    clearable
  />
</template>

【问题讨论】:

    标签: vue.js


    【解决方案1】:

    您需要使用 $emit (documentation) 将数据传递回父组件。或者你可以开始使用Vuex(Vue.js 的状态管理器)。

    您也可以查看现场演示here

    【讨论】:

    • 我完全忘记了 vuex。我有尽可能少地使用 vuex 并在组件中包含方法的原则。我会去阅读文档,如果我无法实现它,我会使用 vuex。谢谢大佬!
    【解决方案2】:

    要实现v-model,您需要为每个子组件添加value 属性。每个组件还需要发出一个input 事件,以便父组件可以接收更改(阅读更多here)。请注意,如果您通过太多组件向下传递数据,您可能应该考虑使用Vuex,但在这种情况下它可能仍然没问题。

    您的组件必须看起来像这样才能将 v-model 一直传递给基础组件:

    Parent.vue

    <template>
      <!-- Pass the data item below -->
      <child v-model="item"></child>
    </template>
    
    <script>
    import Child from './components/Child'
    
    export default {
      components: { 
        Child,
      },
      data: ()=> ({
        item: ''
      })
    }
    </script>
    

    Child.vue

    <template>
      // Random HTML
      // Random HTML 2
      <base-select 
        :items="select"
        value="value"
        @input="e => $emit('input', e)"
      >
    </template>
    
    <script>
    import BaseSelect from '@/components/BaseSelect'
    
    export default {
      components: { 
        BaseSelect,
      },
      // We add the value prop below to work with v-model
      props: {
        value: String
      },
      data: ()=> ({
        select: ['Select 1', 'Select 2']
      }),
    }
    </script>
    

    BaseSelect.vue

    <template>
      <v-select
        v-bind="$attrs"
        v-on="$listeners"
        value="value"
        @input="e => $emit('input', e)"
        class="body-2"
        solo
        dense
        clearable
      />
    </template>
    
    <script>
    export default {
      props: {
        value: String
      }
    }
    </script>
    

    您可以找到我在here 所做的类似工作示例。

    【讨论】:

    • 从组件到组件的传递看起来更复杂。是的,就像@dreyhiflden 所说的那样,你说得对,vuex 让它变得更简单。非常感谢您!