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 的 v-model用法实例
Nov 23 Vue.js
在Vue中使用CSS3实现内容无缝滚动的示例代码
Nov 27 Vue.js
vue实现验证用户名是否可用
Jan 20 Vue.js
vue首次渲染全过程
Apr 21 Vue.js
解读Vue组件注册方式
May 15 Vue.js
vue-cropper插件实现图片截取上传组件封装
May 27 Vue.js
vue基于Teleport实现Modal组件
May 31 Vue.js
Vue vee-validate插件的简单使用
Jun 22 Vue.js
Vue实现导入Excel功能步骤详解
Jul 03 Vue.js
Vue全局事件总线你了解吗
Feb 24 Vue.js
vue中this.$http.post()跨域和请求参数丢失的解决
Apr 08 Vue.js
vue中data里面的数据相互使用方式
Jun 05 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
BBS(php &amp; mysql)完整版(八)
2006/10/09 PHP
mysql 性能的检查和优化方法
2009/06/21 PHP
163的邮件用phpmailer发送(实例详解)
2013/06/24 PHP
PHP数组相关函数汇总
2015/03/24 PHP
Yii模型操作之criteria查找数据库的方法
2016/07/15 PHP
TNC vs IO BO3 第一场2.13
2021/03/10 DOTA
更优雅的事件触发兼容
2011/10/24 Javascript
JavaScript Memoization 让函数也有记忆功能
2011/10/27 Javascript
js select option对象小结
2013/12/20 Javascript
禁用JavaScript控制台调试的方法
2014/03/07 Javascript
通过JS判断联网类型和连接状态的实现代码
2015/04/01 Javascript
JavaScript深度复制(deep clone)的实现方法
2016/02/19 Javascript
基于jQuery实现数字滚动效果
2017/01/16 Javascript
react-native-fs实现文件下载、文本存储的示例代码
2017/09/22 Javascript
使用vuex缓存数据并优化自己的vuex-cache
2018/05/30 Javascript
Node.js在图片模板上生成二维码图片并附带底部文字说明实现详解
2019/08/07 Javascript
浅谈Vue为什么不能检测数组变动
2019/10/14 Javascript
原生js实现弹窗消息动画
2020/11/20 Javascript
Python发送Email方法实例
2014/08/21 Python
Python中用于去除空格的三个函数的使用小结
2015/04/07 Python
Python实现保证只能运行一个脚本实例
2015/06/24 Python
Python爬虫获取整个站点中的所有外部链接代码示例
2017/12/26 Python
python脚本生成caffe train_list.txt的方法
2018/04/27 Python
python基于物品协同过滤算法实现代码
2018/05/31 Python
python3中关于excel追加写入格式被覆盖问题(实例代码)
2020/01/10 Python
python图形界面开发之wxPython树控件使用方法详解
2020/02/24 Python
pycharm配置安装autopep8自动规范代码的实现
2021/03/02 Python
东南亚地区最大的购物网站Lazada新加坡站点:Lazada.sg
2016/07/17 全球购物
巴西宠物店在线:Geração Pet
2017/05/31 全球购物
国际经济贸易专业推荐信
2013/11/06 职场文书
我们的节日清明节活动总结
2014/04/30 职场文书
捐书倡议书
2014/08/29 职场文书
汤姆索亚历险记读书笔记
2015/06/29 职场文书
SqlServer 垂直分表(减少程序改动)
2021/04/16 SQL Server
Node-Red实现MySQL数据库连接的方法
2021/08/07 MySQL
vue使用watch监听属性变化
2022/04/30 Vue.js