使用 v-model 和 select 作为外部组件

1 vue.js vue-component vuejs2

我想创建一个选择框组件,它有一个预定义的标记,可以在我的系统中的任何地方使用。
我在理解v-model属性以及它如何同步来自父组件的预定义值和选择框内部值方面遇到困难。

这是我的例子:http : //jsfiddle.net/eywraw8t/60103/

我希望我的根组件预先选择一个值,Selectbox 组件可以更改该值。我的示例按预期工作,但$emit在选择框中使用事件的方式感觉不对。

const Selectbox = {
    props: {
        value: String
    },

    methods: {
        select($event, value) {
        	// The example works but having
            // $event.target.value here seems very wrong
            this.$emit('input', $event.target.value);
        }
    },
    
    template: `
        <div>
            <select :value="value" @change="select($event, value)">
                <option value="1">Option 1</option>
                <option value="2">Option 2</option>
                <option value="3">Option 3</option>
            </select>
            <div>The value is {{ value }}.</div>
        </div>`
};

new Vue({
  el: "#app",
  components: { Selectbox },
  data: () => ({
  	selectboxValue: 1
  }),
  template: `
    <div>
        <selectbox v-model="selectboxValue" />
    </div>
  `
})
Run Code Online (Sandbox Code Playgroud)
body {
  padding: 50px;
}

label {
  display: block;
}
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>
<div id="app">
</div>
Run Code Online (Sandbox Code Playgroud)

Ber*_*ert 5

正如我在上面的评论中提到的,您基本上做对了,但是将一些参数传递给您并不真正需要的 select 方法。在组件中 select 元素的更改事件中,您实际上不必传递任何内容,因为event如果您只指定一个函数,对象将自动传递。

在您的模板中:

<select :value="value" @change="select">
Run Code Online (Sandbox Code Playgroud)

还有你的事件处理程序:

select(evt) {
  this.$emit('input', evt.target.value);
}
Run Code Online (Sandbox Code Playgroud)

<select :value="value" @change="select">
Run Code Online (Sandbox Code Playgroud)
select(evt) {
  this.$emit('input', evt.target.value);
}
Run Code Online (Sandbox Code Playgroud)
const Selectbox = {
    props: {
        value: String
    },

    methods: {
        select(evt) {
            this.$emit('input', evt.target.value);
        }
    },
    
    template: `
        <div>
            <select :value="value" @change="select">
                <option value="1">Option 1</option>
                <option value="2">Option 2</option>
                <option value="3">Option 3</option>
            </select>
            <div>The value is {{ value }}.</div>
        </div>`
};

new Vue({
  el: "#app",
  components: { Selectbox },
  data: () => ({
  	selectboxValue: 1
  }),
  template: `
    <div>
        <selectbox v-model="selectboxValue" />
    </div>
  `
})
Run Code Online (Sandbox Code Playgroud)

对于像这样的输入组件,我通常喜欢做的就是在内部使用计算属性作为组件的模型。

<select v-model="selected">
  <option value="1">Option 1</option>
  <option value="2">Option 2</option>
  <option value="3">Option 3</option>
</select>
Run Code Online (Sandbox Code Playgroud)

和这样的计算:

computed:{
  selected:{
    get() {return this.value},
    set(v) {this.$emit('input', v)}
  }
},
Run Code Online (Sandbox Code Playgroud)

body {
  padding: 50px;
}

label {
  display: block;
}
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>
<div id="app">
</div>
Run Code Online (Sandbox Code Playgroud)
<select v-model="selected">
  <option value="1">Option 1</option>
  <option value="2">Option 2</option>
  <option value="3">Option 3</option>
</select>
Run Code Online (Sandbox Code Playgroud)