vue自定义组件实现v-model双向绑定数据的实例代码

 更新时间:2021年10月08日 10:13:44   作者:折月  
vue中父子组件通信,都是单项的,直接在子组件中修改prop传的值vue也会给出一个警告,接下来就用一个小列子一步一步实现了vue自定义的组件实现v-model双向绑定,需要的朋友可以参考下

项目中会遇到自定义公共组件供项目调用,正常情况可以使用 props定义参数接收父组件传的参数,然后通过子组件的$emits()方法回传数据给父组件。

类似如下:

父组件

<common-checkbox :checked="goodsSelected" class="left" :height="'16px'" :width="'16px'"  @checkChange="checkChange"></common-checkbox>

     /**
     * 接收子组件回传进行处理
     */
    checkChange(value) {
      this.goodsSelected=value//子组件数据赋值给父组件
    }

子组件

    /**
     * 切换选中回传
     */
    toggleCheck(value) {
      this.$emit('changeCheck', value)//回传方法,把子组件变化后的数据回传给父组件处理
    }

但是这种写法需要调用公共组件的页面额外写处理的方法,而且显得太low,我们可不可以像是框架自带的公共组件一样去声明直接v-model双向绑定呢?接下来提供项目中实际遇到这种情况的处理方法

第一种方式:

正常情况下当你在父组件里给子组件绑定 v-model属性时,子组件中会默认的将 v-model绑定的数据,付给子组件 名为 value的props属性,value依然需要提前在子组件props中声明,否则接收不到。

当 value修改后,并不会立即双向回传给父组件。如果想回传实现同步更新父组件的v-model需要如下操作

 this.$emit('input', value) 

当未声明双向绑定回传的事件时,默认通过input事件回传,为什么说 “当未声明双向绑定回传的事件”,这个便是第二种方式,下面会讲到。

简单来说,第一种方式的实现,首先是v-model绑定父组件数据 ,然后子组件value 的props属性自动接收,最后当数据更改后调用this.$emit('input', value) 回传父组件,这样父组件不需要额外实现子组件的回传就可以实现双向绑定

第二种方式:

前面提到 “当未声明双向绑定回传的事件” 默认使用 input回传,既然这样说了那就存在,如果我不用input呢?这就需要了解vue的一个特殊的属性:model,这个属性可以用来声明 子组件用哪个字段去接收双向绑定的数据,以及用哪个方法回调更新父组件v-model的数据,写法如下:

export default {
  name: 'CommonCkeckBox',
  model: {
    prop: 'checked',
    event: 'changeCheck'
  },
    props: {
    checked: {
      type: Boolean,
      default: false,
    }, // 选中状态
  }
  }

这种写法就意味着,父组件 双向绑定的数据会绑定到子组件名为checked的props属性,并且,当子组件调用this.$emit('changeCheck', value)时,会同步的更新父组件的数据,实现双向绑定。

接下来附一段自定义checkbox的代码以作参考:

<template>
<div class="check-box-container"  @click="toggleCheck()" :style="{width:width,height:height}">
        <div class="checkbox-icon">
              <!-- 三种状态 选中  未选  禁用 -->
              <img alt :src="`${$cdnImageUrl}/cart/icon-selected.png`" :width="width" :height="height" key="select" v-if="checked&&!disabled"/>
              <img alt :src="`${$cdnImageUrl}/cart/icon-unselected.png`" :width="width" :height="height" key="unselected" v-if="!checked&&!disabled" />
              <img alt :src="`${$cdnImageUrl}/cart/icon-unselected.png`" :width="width" :height="height" class="disabled" key="unselected"  v-if="disabled"/>
            </div>
        <slot></slot>
</div>
</template>
<script>
/**
 * 全局统一弹窗
 */
export default {
  name: 'CommonCkeckBox',
  model: {
    prop: 'checked',
    event: 'changeCheck'
  },
  props: {
    checked: {
      type: Boolean,
      default: false,
    }, // 选中状态
    disabled: {
      type: Boolean,
      default: false,
    }, // 是否禁用
    width: {
      type: String,
      default: '16px',
    }, // 按钮默认宽度
    height: {
      type: String,
      default: '16px',
    }, // 按钮默认高度
  },
  created() {
  },
  data() {
    return {
    }
  },
  methods: {
    /**
     * 切换选中回传
     */
    toggleCheck() {
      this.$emit('changeCheck', !this.checked)
      this.$emit('toggleCheck')
    }
  },
  watch: {
    checked: {
      handler(newValue, oldValue) {
      // 开放状态变更事件
        this.$emit('onChange')
      },
      deep: true
    }
  },
}
</script>
<style lang="scss"  scoped>
.check-box-container{
    display: inline-block;
    .checkbox-icon{
        img{
          transform: translateZ(0);
          will-change: auto;
        }
        .disabled{
          background-color:#f5f5f5;
          border-radius: 50%;
        }
    }
}
</style>

父组件:

      <common-checkbox v-model="item.goodsSelected" class="left" :width="'16px'"  :height="'16px'"></common-checkbox>

具体用哪种方式根据项目场景选择,若第一种不满足需求,可以尝试第二种实现。

总结

到此这篇关于vue自定义组件实现v-model双向绑定数据的文章就介绍到这了,更多相关vue v-model双向绑定数据内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Vue实现关联页面多级跳转(页面下钻)功能的完整实例

    Vue实现关联页面多级跳转(页面下钻)功能的完整实例

    这篇文章主要给大家介绍了关于Vue实现关联页面多级跳转(页面下钻)功能的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-03-03
  • Vue开发指南之重点知识梳理

    Vue开发指南之重点知识梳理

    这篇文章主要介绍了Vue开发指南之重点知识梳理,对Vue框架感兴趣的同学,可以参考下
    2021-05-05
  • vant/vue跨域请求解决方案

    vant/vue跨域请求解决方案

    这篇文章主要介绍了vant/vue跨域请求解决方案,需要的朋友可以参考下
    2022-12-12
  • vue+vue-meta-info动态设置meta标签教程

    vue+vue-meta-info动态设置meta标签教程

    这篇文章主要介绍了vue+vue-meta-info动态设置meta标签教程,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-04-04
  • Vue项目使用localStorage+Vuex保存用户登录信息

    Vue项目使用localStorage+Vuex保存用户登录信息

    这篇文章主要为大家详细介绍了Vue项目使用localStorage+Vuex保存用户登录信息,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-05-05
  • vue中el-upload上传图片到七牛的示例代码

    vue中el-upload上传图片到七牛的示例代码

    这篇文章主要介绍了vue中el-upload上传图片到七牛的示例代码,实现思路其实也很简单,需要从后台获取七牛token上传图片到七牛,具体示例代码大家跟随小编一起学习吧
    2018-10-10
  • 解决vue 退出动画无效的问题

    解决vue 退出动画无效的问题

    这篇文章主要介绍了解决vue 退出动画无效的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-08-08
  • Vue双向绑定实现原理与方法详解

    Vue双向绑定实现原理与方法详解

    这篇文章主要介绍了Vue双向绑定实现原理与方法,结合实例形式详细分析了发布者-订阅者模式、脏值检查、数据劫持与双向绑定相关实现技巧,需要的朋友可以参考下
    2020-05-05
  • Vue 组件(component)教程之实现精美的日历方法示例

    Vue 组件(component)教程之实现精美的日历方法示例

    组件是我们学习vue必须会的一部分,下面这篇文章主要给大家介绍了关于Vue 组件(component)教程之实现精美的日历的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。
    2018-01-01
  • vue3+vite+TS中使用element-plus按需引入ElLoading、ElMessage样式失效解决

    vue3+vite+TS中使用element-plus按需引入ElLoading、ElMessage样式失效解决

    在项目中使用elementui确实是很方便的一件事,下面这篇文章主要给大家介绍了关于vue3+vite+TS中使用element-plus按需引入ElLoading、ElMessage样式失效解决的相关资料,需要的朋友可以参考下
    2023-02-02

最新评论