我正在try 用一组单选按钮设置一个简单的Vue实例.目标是,如果用户单击已选中的单选按钮,它将取消选中相应的单选按钮.但我还不能用Vue来做这件事.以下是我目前的代码:

HTML:

<div id="app">
    <div v-for="(val, key) in list">
        <input type="radio" name="radio" :value="val" v-model="selected" :id="val">
        <label :for="val" @click="uncheck( val )">{{ val }}</label>
    </div>
    <button @click="uncheckAll">Uncheck all</button>
</div>

JS:

var app = new Vue({
        el: '#app',
        data : {
            list: [ 'one', 'two', 'three' ],
            selected: 'two',
        },
        methods : {
            uncheck: function( val ){
                console.log( val, this.selected );
                if ( val == this.selected ){
                    this.selected = false;
                }
            },
            uncheckAll: function(){
                this.selected = false;
            }
        }
})

似乎调用了uncheck方法,但单选按钮会触发change事件,然后再次更新selected的值.uncheckAll方法按预期工作,可能是因为它与使用v-model的数据无关.

有什么建议可以让这一切顺利进行吗?这是我为这个例子创建的一支钢笔:https://codepen.io/diegoliv/pen/JrPBbG

推荐答案

困难在于,v-model在改变selected的值之前,你可以判断它,看看它之前的值是什么.你需要另一个变量.

这个 idea 是:当你点击一个项目时,它会判断它是否匹配previouslySelected(而不是selected).如果匹配,取消 Select .然后将previouslySelected设置为selected.

click处理器应该在输入上,而不是标签上;无论如何,标签的功能是将点击转发到输入.

var app = new Vue({
  el: '#app',
  data: {
    list: ['one', 'two', 'three'],
    selected: 'two',
    previouslySelected: 'two'
  },
  methods: {
    uncheck: function(val) {
      if (val === this.previouslySelected) {
        this.selected = false;
      }
      this.previouslySelected = this.selected;
    },
    uncheckAll: function() {
      this.selected = false;
    }
  }
})
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.min.js"></script>
<div id="app">
  <div v-for="(val, key) in list">
    <input type="radio" name="radio" :value="val" v-model="selected" :id="val" @click="uncheck(val)">
    <label :for="val">{{ val }}</label>
  </div>
  <button @click="uncheckAll">Uncheck all</button>
</div>
Note: the below method does not work with Vue 2.5 or later because clicking an already-selected radio does not cause a set to happen. (thanks to Vlad T. in the comments)

更接近它的一种数据方式是,根据您 Select 的数据计算一个,并让其设置程序进行重新 Select 的判断.没有点击处理程序.一切都是在设定值的正常过程中处理的.

var app = new Vue({
  el: '#app',
  data: {
    list: ['one', 'two', 'three'],
    d_selected: 'two'
  },
  computed: {
    selected: {
      get() {
        return this.d_selected;
      },
      set(v) {
        if (v === this.d_selected) {
          this.d_selected = false;
        } else {
          this.d_selected = v;
        }
      }
    }
  },
  methods: {
    uncheckAll: function() {
      this.d_selected = false;
    }
  }
})
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.min.js"></script>
<div id="app">
  <div v-for="(val, key) in list">
    <input type="radio" name="radio" :value="val" v-model="selected" :id="val">
    <label :for="val">{{ val }}</label>
  </div>
  <button @click="uncheckAll">Uncheck all</button>
</div>

Vue.js相关问答推荐

Vue 3使用计算(computed)属性对象获取图像信息,在模板中呈现值时变为NaN

当用户在嵌套路由中时激活链接

VueJS CKeditor5 上传图片

从数据库中删除后,Vue.js $remove 不删除元素

Vue:根元素内容和内容分发槽

如何解决 Vue.js 中的相邻 JSX 元素必须包含在封闭标记中问题

使用 v-slot:body 时 Vuetify v-data-table 没有响应

如何在 Laravel 中包含 Bootstrap-Vue

Express.js + lint 出错

使用 vee-validate 在 vue js 中进行验证有错误

vuejs中watch方法和计算方法有什么区别

为什么Vue.js 使用单字标签

在 SPA VueJS 中全局声明 mapState 和 mapMutations

如何禁用 nuxt 默认错误重定向

如何将数据传递给 Vue.js 中的路由视图

如何在 vuetify 中将工具提示添加到数据表标题?

如何将数据属性设置为从 Vuex getter 返回的值

Vue路由在新页面上回到顶部

VueJS 路由 - 使用子路由和 Vuetify 时如何停止多个活动路由(active routes)?

Mapbox 事件监听器