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

Nak*_*ura 4 html javascript vue.js vue-component vuejs2

我有一个子组件:

select(v-model="selectedItem", @change="emitChange")
  option(:value="{id: '123', value: 'foo'}") 123
  option(:value="{id: '456', value: 'bar'}") 456
Run Code Online (Sandbox Code Playgroud)
data: {
  selectedItem: '',
},
methods: {
  emitChange() {
    this.$emit('change', this.selectedItem);
  },
}
Run Code Online (Sandbox Code Playgroud)

上面一个工作正常。


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

所以我执行以下操作:

select(:value="selectedItem", @change="emitChange")
  option(:value="{id: '123', value: 'foo'}") 123
  option(:value="{id: '456', value: 'bar'}") 456
Run Code Online (Sandbox Code Playgroud)
props: ['selectedItem'],
methods: {
  emitChange(e) {
    this.$emit('change', e.target.value);
  },
}
Run Code Online (Sandbox Code Playgroud)

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

但这不起作用。e.target.value会像[object Object].

我在这里缺少什么?

Ber*_*ert 5

e.target是一个 DOM 值,并且e.target.value是一个字符串。这就是为什么它显示为[object Object],这就是将对象转换为字符串时得到的结果。

当您使用v-modelVue 时,它​​会在存储实际 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);
    },
  }  
})
Run Code Online (Sandbox Code Playgroud)

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

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) }
    }
  }  
})
Run Code Online (Sandbox Code Playgroud)

在这里,我们将选项传递给组件,并使用计算属性 withv-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);
    },
  }  
})
Run Code Online (Sandbox Code Playgroud)
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) }
    }
  }  
})
Run Code Online (Sandbox Code Playgroud)