带有动态单选按钮列表的 Vue.js v-model

新手上路,请多包涵

我正在尝试制作一个可重用的 vue 单选按钮组件,它将采用变量名称和一个包含标签和值的对象,然后使用 v-for 呈现单选按钮列表。

我已经成功解决了问题的每一半,但还没有设法将它们结合起来:

  1. 我可以制作一组绑定到数据模型的单选按钮,其中按钮是在模板中静态定义的,但我不知道如何使列表动态化。下面是代码:
 //component
const Radio = {
	template: '#test',
  prop: ['value'],
  data () {
    return {
      selected: this.value
    }
  },
  model: {
	  prop: 'value',
      event: 'change'
  },
  methods: {
    handleClickInput (e) {
      this.$emit('change', this.selected)
    }
  }
}

//app
var app2 = new Vue({
  el: '#app2',
  data: {
  		door: '',
			doorOptions: {
				'Yes': 1,
				'No': 0,
			}
	},
  components: { Radio, }
})
 <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app2">
  <radio v-model="door"></radio>
  <p>
    door = {{door}}
  </p>
</div>

<template id="test">
  <div>
    <input type="radio" value="0" v-model="selected" @change="handleClickInput">0
    <input type="radio" value="1" v-model="selected" @change="handleClickInput">1
  </div>
</template>
  1. 我可以根据“选项”对象制作一个动态的单选按钮列表,但找不到将它们绑定到数据模型的方法。下面是代码:
 // component
Vue.component('radio-set', {
  template: '#radio-set',
  props: {
			'label-name': '',
			'variable': '',
			'options': '',
		},
  methods: {
    clicked: function(variable, key, value) {
    // none of this is right, it doesn't update the vue data model
		window[variable] = value; //assign the new value to the dynamic variable name
		selected = value;
		this.$emit("click-event", variable) //create the click event for model updating by the parent
    }
  },
})

//app
var app = new Vue({
  el: '#vueApp',
  data: {
    door:'initial value',
		doorOptions: {
		  'Yes':1,
		  'No':0,
      'Maybe':5,
      'A new option':25
		},

  },
  methods: {
		buttonClick: function(p1){
			console.log(p1+': '+window[p1]); //the variable was assigned inside the child component
		}
  }
});
 <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="vueApp">
	<radio-set
		label-name="Radio button set"
		variable="door"
		:options="doorOptions"
		@click-event="buttonClick"
	>door: {{door}}
	</radio-set>
</div>

<template id="radio-set">
	<div>
		<label>{{labelName}}:</label>
		<button
      type="button"
      v-for="(val, key) in options"
      @click="clicked(variable, key, val)"
      >
      {{ key }}
		</button>
	 </div>
</template>

谁能就我如何前进提供一些建议?

原文由 Tom 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 597
2 个回答

正如@PierreSaid 提到的,您可以阅读更多关于 v-model 在自定义组件上的用法。

这是另一个使用 input[type="radio"] 并将更改事件发回父组件的示例。

 // component
Vue.component('radio-set', {
  template: '#radio-set',
  props: {
    'label-name': '',
    'value': '',
    'options': '',
  }
})

//app
var app = new Vue({
  el: '#vueApp',
  data() {
    return {
      door: null,
      doorOptions: {
        'Yes': 1,
        'No': 0,
        'Maybe': 5,
        'A new option': 25
      }
    };
  }
});
 <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
<div id="vueApp">
  <radio-set label-name="Radio button set" v-model="door" :options="doorOptions"></radio-set>
  door: {{door}}
</div>

<template id="radio-set">
  <div>
    <div>{{labelName}}:</div>
    <label v-for="(val, key) in options" :key="val">
      <input type="radio"
        :name="labelName"
        :value="val"
        :checked="val == value"
        @change="$emit('input', val)">
      {{ key }}
    </label>
  </div>
</template>

原文由 Ja9ad335h 发布,翻译遵循 CC BY-SA 4.0 许可协议

首先:对于您的选择,拥有一个数组会更容易。

       doorOptions: [
        { key: "Yes", value: 1 },
        { key: "No", value: 0 },
        { key: "Maybe", value: 5 },
        { key: "A new option", value: 25 }
      ]
    };

这样你就可以迭代它。

在您的自定义组件和您的应用程序之间同步所选值的另一个好方法是使用 v-model

实现 v-model 的教程

这样我们就可以创建一个像这样的可重用组件:

 <template>
  <div>
    <label>{{labelName}}:</label>
    <button
      type="button"
      v-for="(val, idx) in options"
      :key="idx"
      @click="clicked(val)"
    >{{ val.key }}</button>
  </div>
</template>

<script>
export default {
  props: ["value", "options", "labelName"],
  methods: {
    clicked(val) {
      this.$emit("input", val);
    }
  }
};
</script>

并像这样使用它

<template>
  <div id="app">
    <radio-set v-model="selected" label-name="Radio button set" :options="doorOptions"/>
    Selected : {{selected.key}}
  </div>
</template>

<script>
import RadioSet from "./components/RadioSet";

export default {
  name: "App",
  components: {
    RadioSet
  },
  data() {
    return {
      selected: null,
      doorOptions: [
        { key: "Yes", value: 1 },
        { key: "No", value: 0 },
        { key: "Maybe", value: 5 },
        { key: "A new option", value: 25 }
      ]
    };
  }
};
</script>

现场演示

原文由 Pierre Said 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题