vue自定义组件实现双向绑定


Posted in Vue.js onJanuary 13, 2021

场景:

我们比较常用的父子组件之间的交互方式:
父组件通过props将数据流入到子组件;
子组件通过$emit将更新后的数组发送的父组件;

今天,我们通过另一种方式实现交互,参考input框的v-model,实现自定义组件的双向数据绑定。
即:父组件值改变,子组件的值跟着改变;反之,子组件值发生变化,父组件值随之变化

子组件定义:

由于不能直接修改props属性值,我们这里定义valueData,通过监听实时接收value值,通过click方法修改valueData。
这里注意model语法糖prop 是接收的props属性value,保持一致。event是先上传递的事件名。

代码如下:

<template>
  <div>
    <div>{{ `子组件值: ${value}` }}</div>
    <div @click="click">点击此处修改值</div>
  </div>
</template>

<script>
export default {
  name: "",
  model: {
    prop: "value",
    event: "change"
  },
  props: {
    value: Number
  },
  components: {},
  data() {
    return {
      valueData: ""
    };
  },
  watch: {
    value(newValue, oldValue) {
      this.valueData = newValue;
      console.log(`子组件值:${newValue}`);
    }
  },
  created() {
  },
  mounted() {
  },
  methods: {
    click() {
      this.valueData++;
      this.$emit("change", this.valueData);
    }
  }
};
</script>
<style lang='less' scoped>
</style>

父组件定义:

父组件通过v-model绑定text值,名称不一定是value,可以是其他任意符合命名规范的字符串,这里是text。
子组件通过change事件更新数据后,v-mode绑定值随之变化。
或者父组件修改text值后,子组件value值随之变化。

代码如下:

<template>
  <div>
    <div>{{ `父组件值:${text}` }}</div>
    <div @click="click">点击此处修改值</div>


    <span>-----------------------------------------------------------</span>

    <test-children v-model="text"></test-children>

  </div>
</template>

<script>
import TestChildren from "@/views/TestChildren";

export default {
  name: "",
  components: { TestChildren },
  data() {
    return {
      text: 1
    };
  },
  created() {
  },
  mounted() {
  },
  watch: {
    text(newValue, oldValue) {
      console.log(`父组件值:${newValue}`);
    }
  },
  methods: {
    click() {
      this.text--;

    }
  }
};
</script>
<style lang='less' scoped>
</style>

结果:

直接copy代码到自己项目测试。无论是通过父组件改变值,还是子组件改变值。两个组件通过v-mode绑定的值始终保持一致。

答疑:

有同学就问了 ,这不是和通过props向下流入数据,再通过$emit方式向上传递数据一样么也能实现我这种双向绑定的效果。 其实不然,如果不通过v-model,那么我们势必会在父组件写这样的代码:

<test-children @change="changeText"></test-children>

然后在通过定义changeText方法修改text值。

试想,当我们的页面比较复杂,引用组件量比较庞大,页面中就需要多定义这样十几、二十几个方法。可阅读行大大降低,增加了维护成本。

扩展:

vue2.3之后提供了sync方式,也能实现双向绑定

父组件中的写法:

<test-children :value.sync="text"></test-children>

子组件中不需要使用下面model定义,直接删除即可。

model: {
prop: “value”,
event: “change”
},

向父组件传递数据使用如下方式:

this.$emit("update:value", this.valueData);

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Vue.js 相关文章推荐
Vue如何跨组件传递Slot的实现
Dec 14 Vue.js
vue中如何添加百度统计代码
Dec 19 Vue.js
Vue实现随机验证码功能
Dec 29 Vue.js
vue实现防抖的实例代码
Jan 11 Vue.js
详解为什么Vue中的v-if和v-for不建议一起用
Jan 13 Vue.js
浅谈Vue开发人员的7个最好的VSCode扩展
Jan 20 Vue.js
vue-cli 3如何使用vue-bootstrap-datetimepicker日期插件
Feb 20 Vue.js
vue3.0 项目搭建和使用流程
Mar 04 Vue.js
vue3获取当前路由地址
Feb 18 Vue.js
Vue3中toRef与toRefs的区别
Mar 24 Vue.js
vue实现列表垂直无缝滚动
Apr 08 Vue.js
vue判断按钮是否可以点击
Apr 09 Vue.js
Vue页面渲染中key的应用实例教程
Jan 12 #Vue.js
Vue项目中使用mock.js的完整步骤
Jan 12 #Vue.js
vue 页面跳转的实现方式
Jan 12 #Vue.js
Vue过滤器,生命周期函数和vue-resource简单介绍
Jan 12 #Vue.js
详解template标签用法(含vue中的用法总结)
Jan 12 #Vue.js
Vue中ref和$refs的介绍以及使用方法示例
Jan 11 #Vue.js
vue实现防抖的实例代码
Jan 11 #Vue.js
You might like
欧美媒体选出10年前最流行的17部动画
2017/01/18 日漫
php正则表达匹配中文问题分析小结
2012/03/25 PHP
php 解压rar文件及zip文件的方法
2014/05/05 PHP
PHP之正则表达式捕获组与非捕获组(详解)
2015/07/29 PHP
大家在抢红包,程序员在研究红包算法
2015/08/31 PHP
PHP+Ajax实现无刷新分页实例详解(附demo源码下载)
2016/04/07 PHP
yii2的restful api路由实例详解
2019/05/14 PHP
jquery 模拟雅虎首页的点击对话框效果
2010/04/11 Javascript
jQuery EasyUI API 中文文档 - Menu菜单
2011/10/03 Javascript
JS实现的省份级联实例代码
2013/06/24 Javascript
jquery Tab效果和动态加载的简单实例
2013/12/11 Javascript
jQuery实现左右切换焦点图
2015/04/03 Javascript
使用Object.defineProperty实现简单的js双向绑定
2016/04/15 Javascript
使用jquery给指定的table动态添加一行、删除一行
2016/10/13 Javascript
以v-model与promise两种方式实现vue弹窗组件
2018/05/21 Javascript
jQuery动态操作表单示例【基于table表格】
2018/12/06 jQuery
js 执行上下文和作用域的相关总结
2021/02/08 Javascript
Python爬虫DOTA排行榜爬取实例(分享)
2017/06/13 Python
python中如何使用正则表达式的非贪婪模式示例
2017/10/09 Python
Python中的defaultdict与__missing__()使用介绍
2018/02/03 Python
对python中的iter()函数与next()函数详解
2018/10/18 Python
Flask框架工厂函数用法实例分析
2019/05/25 Python
Django logging配置及使用详解
2019/07/23 Python
django框架基于queryset和双下划线的跨表查询操作详解
2019/12/11 Python
基于Python3.7.1无法导入Numpy的解决方式
2020/03/09 Python
Python实现爬取并分析电商评论
2020/06/19 Python
打印机墨盒:123Inkjets
2017/02/16 全球购物
火灾现场处置方案
2014/05/28 职场文书
医院保洁服务方案
2014/06/11 职场文书
员工保密协议书
2014/09/27 职场文书
2015清明节祭奠英烈寄语大全
2015/03/04 职场文书
社区禁毒宣传活动总结
2015/05/07 职场文书
南京南京观后感
2015/06/02 职场文书
幼儿园大班教师随笔
2015/08/14 职场文书
2019年个人工作总结范文
2019/03/25 职场文书
Element-ui Layout布局(Row和Col组件)的实现
2021/12/06 Vue.js