【问题标题】:Using v-model on a button?在按钮上使用 v-model?
【发布时间】:2020-07-07 08:03:33
【问题描述】:

当一个按钮被点击时,我希望将它的name 推送到一个数组中。当按钮未被点击时,我想从数组中删除它的name

我知道如何使用@click 来推动/拼接数组。

我想知道是否有一种简单的方法可以将按钮的点击绑定到数组,就像复选框如何与v-model 一起使用一样。我知道您不能在 button 上使用 v-model,但如果我们要制作 button 它是自己的组件并在其上使用 v-model...

<custom-button v-model="myArray"></custom-button>

有没有办法让它工作?

【问题讨论】:

  • 记住v-model 只是v-bind:value="something" v-on:input="something = $event.target.value" 的语法糖。在custom-button 中,只需一个道具value 并使用新值发出一个事件input
  • 谢谢 - 我已经尝试过了,但它只是覆盖了绑定模型中的值,我怎样才能让它推送到数组?
  • 你需要发送一个数组作为 prop 和 $emit updated Array 作为输入。

标签: vue.js vuejs2


【解决方案1】:

我会为自定义按钮组件创建结构,例如:

    ...,
    props: {
     originalArray: {

        required: true
      }
    },
    data(){
    return {
      modifiedArray: this.originalArray.map(x => ({...x}))
      }

   },

  methods: {

     yourMethod()
      {
      //do your logic on the modifiedArray
      this.$emit('changed',this.modifiedArray);
    }

   }

那么你可以像这样使用它:

<custom-button :original-array="this.myArray" @changed="newArray => this.myArray = newArray" />

【讨论】:

  • 如果你像这样改变this.modifiedArray,你也会修改prop originalArray,因为它是一个浅拷贝。
【解决方案2】:

我会这样做:

const CBtn = {
  template: '#c-btn',
  props: ['array', 'label'],
  data(){
    return {
      ncTimeout: -1
    }
  },
  computed:{
    arr_proxy: {
      get(){
        // shallow copy to not modify parent array indices
        return this.array.slice()
      }
    }
  },
  methods: {
    update(){
        
        this.notClicked()
        if(!this.arr_proxy.includes(this.label))
           this.$emit('update:array', this.arr_proxy.concat(this.label))
    },
    notClicked(){
      clearTimeout(this.ncTimeout)
      this.ncTimeout = setTimeout(()=>{
        let index = this.arr_proxy.findIndex(v => v === this.label)
        
        if(index>=0){
          this.arr_proxy.splice(index, 1)
          this.$emit('update:array', this.arr_proxy)
        }
      }, 1000)
    }
  }
}

new Vue({
  components: {
   CBtn
  },
  template: '#main',
  data(){
    return {arr: []}
  }
}).$mount('#app')
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<template id="c-btn">
  <button
   @click="update"
   v-on="$listeners"
   v-bind="$attrs"
  >
    {{label}}  
  </button>
</template>

<template id="main">
  <div>
  <c-btn label="1" :array.sync="arr" ></c-btn>
  <c-btn label="2" :array.sync="arr" ></c-btn>
  <c-btn label="3" :array.sync="arr" ></c-btn>
  {{arr}}
  <div>
</template>

<div id="app"></div>

所以是的,您可以使用 v-model 和 model 中定义的选项 value: [propName]event: [eventName].sync modifier'update:[propName]' 事件。

【讨论】:

  • 不回答问题 re: v-model
  • 你有例子吗?
猜你喜欢
  • 2020-03-31
  • 2020-09-13
  • 2018-05-22
  • 2020-05-26
  • 2018-08-31
  • 2021-12-08
  • 1970-01-01
  • 2021-02-09
相关资源
最近更新 更多