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使用exif获取图片旋转,压缩的示例代码
Dec 11 Vue.js
Vue中computed和watch有哪些区别
Dec 19 Vue.js
基于Vue2实现移动端图片上传、压缩、拖拽排序、拖拽删除功能
Jan 05 Vue.js
vuex的使用步骤
Jan 06 Vue.js
如何在vue中使用HTML 5 拖放API
Jan 14 Vue.js
基于vue-simple-uploader封装文件分片上传、秒传及断点续传的全局上传插件功能
Feb 23 Vue.js
如何使用vue3打造一个物料库
May 08 Vue.js
vue组件的路由高亮问题解决方法
May 11 Vue.js
vue实现水波涟漪效果的点击反馈指令
May 31 Vue.js
vue使用wavesurfer.js解决音频可视化播放问题
Apr 04 Vue.js
vue3种table表格选项个数的控制方法
Apr 14 Vue.js
Vue组件化(ref,props, mixin,.插件)详解
May 15 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
PHP的FTP学习(一)[转自奥索]
2006/10/09 PHP
杏林同学录(四)
2006/10/09 PHP
IIS环境下快速安装、配置和调试PHP5.2.0
2006/12/17 PHP
一个PHP数组应该有多大的分析
2009/07/30 PHP
PHP中文件读、写、删的操作(PHP中对文件和目录操作)
2012/03/06 PHP
PHP实现微信公众平台音乐点播
2014/03/20 PHP
PHP判断是否连接上网络的方法
2015/07/01 PHP
兼容多浏览器的iframe自适应高度(ie8 、谷歌浏览器4.0和 firefox3.5.3)
2009/11/04 Javascript
jquery实现图片左右间隔滚动特效(可自动播放)
2013/05/08 Javascript
怎么清空javascript数组
2013/05/11 Javascript
JQuery each打印JS对象的方法
2013/11/13 Javascript
js实现window.open不被拦截的解决方法汇总
2014/10/30 Javascript
SyntaxHighlighter 3.0.83使用笔记
2015/01/26 Javascript
基于jQuery实现最基本的淡入淡出效果实例
2015/02/02 Javascript
有关jquery与DOM节点操作方法和属性记录
2016/04/15 Javascript
JS命令模式例子之菜单程序
2016/10/10 Javascript
JavaScript中的await/async的作用和用法
2016/10/31 Javascript
EasyUI折叠表格层次显示detailview详解及实例
2016/12/28 Javascript
微信小程序 商城开发(ecshop )简单实例
2017/04/07 Javascript
jQuery Autocomplete简介_动力节点Java学院整理
2017/07/17 jQuery
详解VueJS应用中管理用户权限
2018/02/02 Javascript
element-ui 限制日期选择的方法(datepicker)
2018/05/16 Javascript
[50:04]DOTA2上海特级锦标赛D组小组赛#2 Liquid VS VP第二局
2016/02/28 DOTA
[16:01]夜魇凡尔赛茶话会 第二期01:你比划我猜
2021/03/11 DOTA
Python实现Tab自动补全和历史命令管理的方法
2015/03/12 Python
在Python中pandas.DataFrame重置索引名称的实例
2018/11/06 Python
python mqtt 客户端的实现代码实例
2019/09/25 Python
python实现获取单向链表倒数第k个结点的值示例
2019/10/24 Python
澳大利亚设计的优质鞋类和适合澳大利亚生活方式的服装:Rivers
2019/04/23 全球购物
美国探亲签证邀请信
2014/02/05 职场文书
护士岗前培训自我评鉴
2014/02/28 职场文书
岗位竞聘书范文
2014/03/31 职场文书
教师批评与自我批评剖析材料
2014/10/16 职场文书
公司车辆管理制度
2015/08/04 职场文书
java如何实现socket连接方法封装
2021/09/25 Java/Android
oracle删除超过N天数据脚本的方法
2022/02/28 Oracle