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+iview实现文件上传
Nov 17 Vue.js
vue中watch的用法汇总
Dec 28 Vue.js
vue实现登录功能
Dec 31 Vue.js
jenkins自动构建发布vue项目的方法步骤
Jan 04 Vue.js
vue+echarts实现中国地图流动效果(步骤详解)
Jan 27 Vue.js
手写Vue2.0 数据劫持的示例
Mar 04 Vue.js
Vue.js 带下拉选项的输入框(Textbox with Dropdown)组件
Apr 17 Vue.js
Vue实现导入Excel功能步骤详解
Jul 03 Vue.js
vue使用Google Recaptcha验证的实现示例
Aug 23 Vue.js
vue3使用vuedraggable实现拖拽功能
Apr 06 Vue.js
使用vue判断当前环境是安卓还是IOS
Apr 12 Vue.js
vue特效之翻牌动画
Apr 20 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中如何在有限的内存中读取大文件
2013/07/02 PHP
php去除数组中重复数据
2014/11/18 PHP
php+jQuery+Ajax实现点赞效果的方法(附源码下载)
2020/07/21 PHP
使用php完成常见的文件上传功能(推荐)
2017/01/13 PHP
CakePHP框架Model函数定义方法示例
2017/08/04 PHP
PHP中抽象类,接口功能、定义方法示例
2019/02/26 PHP
Laravel 集成微信用户登录和绑定的实现
2019/12/27 PHP
jquery淡化版banner异步图片文字效果切换图片特效
2014/04/08 Javascript
JS获取屏幕高度的简单实现代码
2016/05/24 Javascript
Jquery UI实现一次拖拽多个选中的元素操作
2020/12/01 Javascript
浅谈React + Webpack 构建打包优化
2018/01/23 Javascript
vue进行图片的预加载watch用法实例讲解
2018/02/07 Javascript
vue路由拦截及页面跳转的设置方法
2018/05/24 Javascript
解决layui 复选框等内置控件不显示的问题
2018/08/14 Javascript
微信小程序button标签open-type属性原理解析
2020/01/21 Javascript
在Python中利用Pandas库处理大数据的简单介绍
2015/04/07 Python
剖析Python的Twisted框架的核心特性
2016/05/25 Python
python回调函数中使用多线程的方法
2017/12/25 Python
Python实现的三层BP神经网络算法示例
2018/02/07 Python
python3 读取Excel表格中的数据
2018/10/16 Python
Python SMTP发送邮件遇到的一些问题及解决办法
2018/10/24 Python
Python面向对象之类的封装操作示例
2019/06/08 Python
远程部署工具Fabric详解(支持Python3)
2019/07/04 Python
python 基于selectors库实现文件上传与下载
2020/12/31 Python
css3通过scale()、rotate()实现放大、旋转
2020/03/19 HTML / CSS
CSS3 box-shadow属性实例详解
2020/06/19 HTML / CSS
比驿:全球酒店比价网
2018/06/20 全球购物
技术总监个人的自我评价范文
2013/12/18 职场文书
机械设计毕业生自荐信
2014/02/02 职场文书
教育专业毕业生推荐信
2014/07/10 职场文书
房地产销售经理岗位职责
2015/02/02 职场文书
关于开学的感想
2015/08/10 职场文书
导游词之云南-元阳梯田
2019/10/08 职场文书
MySQL学习总结-基础架构概述
2021/04/05 MySQL
MySQL中rank() over、dense_rank() over、row_number() over用法介绍
2022/03/23 MySQL
MySQL三种方式实现递归查询
2022/04/18 MySQL