Vue - 使用 v-bind 和 props 对选择元素进行两种方式绑定

Posted

技术标签:

【中文标题】Vue - 使用 v-bind 和 props 对选择元素进行两种方式绑定【英文标题】:Vue - Two way binding for select element using v-bind and props 【发布时间】:2017-12-19 00:27:12 【问题描述】:

我有一个子组件:

select(v-model="selectedItem", @change="emitChange")
  option(:value="id: '123', value: 'foo'") 123
  option(:value="id: '456', value: 'bar'") 456

data: 
  selectedItem: '',
,
methods: 
  emitChange() 
    this.$emit('change', this.selectedItem);
  ,

上面的工作正常。


但我想让<select> 的值取决于父级。

所以我做了以下事情:

select(:value="selectedItem", @change="emitChange")
  option(:value="id: '123', value: 'foo'") 123
  option(:value="id: '456', value: 'bar'") 456

props: ['selectedItem'],
methods: 
  emitChange(e) 
    this.$emit('change', e.target.value);
  ,

父母将在哪里捕获事件并更改selectedItem

但这不起作用。 e.target.value 将类似于 [object Object]

我在这里错过了什么?

【问题讨论】:

【参考方案1】:

e.target 是一个 DOM 值,e.target.value 是一个字符串。这就是为什么它以[object Object] 出现的原因,这是您将对象转换为字符串时得到的。

当你使用 v-model 时,Vue 会在元素上查找它存储实际 javascript 对象的不同属性。

既然如此,只需在组件中使用v-model

Vue.component("custom-select",
  props: ['selectedItem'],
  template:`
    <select v-model="selected" @change="emitChange">
      <option :value="id: '123', value: 'foo'">123</option>
      <option :value=" id: '456', value: 'bar'">123</option>
    </select>
  `,
  data()
    return
      selected: this.selectedItem,
    
  ,
  methods: 
    emitChange(e) 
      this.$emit('change', this.selected);
    ,
    
)

正如 cmets 中提到的,这个选项有一点限制,但是,当从外部设置值时,更改不会反映在组件内部。所以让我们解决这个问题。

Vue.component("custom-select",
  props: ['value', "options"],
  template:`
    <select v-model="selected">
      <option v-for="option in options" :value="option">option.id</option>
    </select>
  `,
  computed: 
    selected: 
      get() return this.value ,
      set(v) this.$emit('input', v) 
    
    
)

在这里,我们将选项传递给组件,并使用带有v-model 的计算属性来发出更改。这是一个工作示例。

console.clear()

const options = [
  id: '123', value: 'foo',
  id: '456', value: 'bar'
]

Vue.component("custom-select",
  props: ['value', "options"],
  template:`
    <select v-model="selected">
      <option v-for="option in options" :value="option">option.id</option>
    </select>
  `,
  computed: 
    selected: 
      get() return this.value ,
      set(v) console.log(v); this.$emit('input', v) 
    
    
)

new Vue(
  el:"#app",
  data:
    selectedItem: null,
    options
  
)
<script src="https://unpkg.com/vue@2.2.6/dist/vue.js"></script>
<div id="app">
  <custom-select v-model="selectedItem" :options="options"></custom-select>
  <div>
    Selected value: selectedItem
  </div>
  <button @click="selectedItem = options[0]">Change from parent</button>
</div>

【讨论】:

在这种情况下,当我从 parent 更改 props 值时,更改不会传播到组件中。您能否提出一种方法来实现这一点,或者实际上是不可能的? @Nakamura 可能,但您使用的是硬编码对象。在您的真实代码中,选项值是否来自某个地方?因为为了从外部设置它,对象需要是 same 对象。 @Nakamura 更新。 很好的例子。像魅力一样工作。

以上是关于Vue - 使用 v-bind 和 props 对选择元素进行两种方式绑定的主要内容,如果未能解决你的问题,请参考以下文章

vue中prop传值时加不加v-bind(冒号:)

vue实现属性透传 v-bind="$attrs"

vue.js将一个对象的所有属性作为prop进行传递

Vue v-bind

如何正确使用 v-bind (vue.js)

Vue中的v-bind指令