vue自定义组件使用v-model 双向绑定

1.常用例子:一些自定义组件例如radio,checkbox的封装,实现数据双向绑定

2.使用方法提炼:

export default {
    data(){
      return{
       }
    },
    model:{
        prop:'xxx',//接收v-model传入的值,this.xxx访问
        event:'xxxx'//emit发送出去定义的事件:this.$emit('xxxx',改变值)},
    }

以radio封装为例子

实现目标类似element 的raido写法:

在这里插入图片描述

父组件parent.vue

  <radio v-model="radio" name="radio" :label="1">足球</radio>
  <radio v-model="radio" name="radio" :label="2">篮球</radio>

子组件radio.vue

<template>
  <div class="radio" @click="handleClick">
    <input type="radio" :name="name" :checked="isChecked" />
    <slot></slot>
  </div>
</template>
<script>
export default {
  props: ["value", "label", "name"],
  model: {
    prop: "value",
    event: "change",
  },
  computed: {
    isChecked() {
      return this.value === this.label;
    },
  },

  methods: {
    handleClick() {
      if (!this.isChecked) {
        this.$emit("change", this.label);
      }
    },
  },
};
</script>
<style scoped>
</style>

进阶封装

嵌套radio-group,实现如下写法:

<radio-group v-model="radio" name="radiogroup">
      <radio  :label="1">中国</radio>
      <radio  :label="2">美国</radio>
      <radio  :label="3">俄罗斯</radio>
  </radio-group>

radio-group.vue

<template>
    <div class="radio-group" >
        <slot></slot>
    </div>
</template>
<script>
export default {
    props:['value','name'],
    model:{
        prop:'value',
        event:'change'
    },
    data(){
        return {

        }
    },
    provide(){
       return {
           radioGroup:this
       }
    },

}
</script>

radio.vue

<template>
  <div class="radio" @click="handleClick">
    <input type="radio" :name="getName" :checked="isChecked" />
    <slot></slot>
  </div>
</template>
<script>
export default {
  props: ["value", "label", "name"],
  inject: {
    radioGroupObj: {
      from: "radioGroup",
      default: "",
    },
  },
  model: {
    prop: "value",
    event: "change",
  },
  computed: {
    isChecked() {
      if (this.radioGroupObj) {
        return this.label === this.radioGroupObj.value;
      }

      return this.value === this.label;
    },
    getName() {
      return this.radioGroupObj.name || this.name || "radio";
    },
  },

  methods: {
    handleClick() {
      if (!this.isChecked) {
        if (this.radioGroupObj) {
          this.radioGroupObj.$emit("change", this.label);
        } else {
          this.$emit("change", this.label);
        }
      }
    },
  },
};
</script>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值