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

标签 javascript html vue.js vuejs2 vue-component

我有一个子组件:

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]

我在这里错过了什么?

最佳答案

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);
    },
  }  
})

如评论中所述,此选项有一点限制,但是,当从外部设置值时,更改不会反射(reflect)在组件内部。所以让我们解决这个问题。

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>

关于javascript - Vue - 使用 v-bind 和 props 对选择元素进行两种方式绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45093887/

相关文章:

javascript - Vue - 防止项目在网格中拖动

javascript - JavaScript 基础的简单 "this"问题

javascript - 为什么 JavaScript ES5 原型(prototype)继承中需要代理类?

javascript - 模态内的表单输入不可点击

Vue.js指令安装组件: Injection not found

javascript - 'props' 被分配了一个值但从未使用过 no-unused-vars vue3

javascript - NodeJS MongoDB 查找早于当前日期的帖子

Javascript 使用 RegExp 替换字符串模式?

jquery - 灵活的 DIV 容器(但不响应)

html - CSS,为什么地址是 "nav a"而不是 "li"?