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打开其他项目页面并传入数据详解
Nov 25 Vue.js
详解Vue的异步更新实现原理
Dec 22 Vue.js
vue中配置scss全局变量的步骤
Dec 28 Vue.js
vue中父子组件的参数传递和应用示例
Jan 04 Vue.js
解决vue使用vant轮播组件swipe + flex时文字抖动问题
Jan 07 Vue.js
vue使用过滤器格式化日期
Jan 20 Vue.js
vue浏览器返回监听的具体步骤
Feb 03 Vue.js
使用Vue.js和MJML创建响应式电子邮件
Mar 23 Vue.js
vue+spring boot实现校验码功能
May 27 Vue.js
vue打包时去掉所有的console.log
Apr 10 Vue.js
vue项目proxyTable配置和部署服务器
Apr 14 Vue.js
解决vue自定义组件@click点击失效问题
Apr 30 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 模拟post_验证页面的返回状态(实例讲解)
2013/10/28 PHP
两个php日期控制类实例
2014/12/09 PHP
提交表单后 PHP获取提交内容的实现方法
2016/05/25 PHP
PHP 文件上传限制问题
2019/09/01 PHP
往光标所在位置插入值的js代码
2013/09/22 Javascript
jQuery中对未来的元素绑定事件用bind、live or on
2014/04/17 Javascript
jquery 为a标签绑定click事件示例代码
2014/06/23 Javascript
JavaScript中对象property的删除方法介绍
2014/12/30 Javascript
使用jQueryMobile实现滑动翻页效果的方法
2015/02/04 Javascript
jquery验证邮箱格式是否正确实例讲解
2015/11/16 Javascript
jQuery判断元素是否显示 是否隐藏的简单实现代码
2016/05/19 Javascript
js cookie实现记住密码功能
2017/01/17 Javascript
jQuery.Ajax()的data参数类型详解
2017/07/23 jQuery
node结合swig渲染摸板的方法
2018/04/11 Javascript
vue中post请求以a=a&amp;b=b 的格式写遇到的问题
2018/04/27 Javascript
关于HTML5的data-*自定义属性的总结
2018/05/05 Javascript
vue+Vue Router多级侧导航切换路由(页面)的实现代码
2018/12/20 Javascript
vue.js指令v-for使用以及下标索引的获取
2019/01/31 Javascript
了解Javascript中函数作为对象的魅力
2019/06/19 Javascript
微信小程序在其他页面监听globalData中值的变化
2019/07/15 Javascript
vue-cli3跨域配置的简单方法
2019/09/06 Javascript
vue学习笔记之给组件绑定原生事件操作示例
2020/02/27 Javascript
javascript实现拖拽碰撞检测
2020/03/12 Javascript
[44:47]Ti4 循环赛第三日 iG vs NaVi
2014/07/12 DOTA
Django发送邮件功能实例详解
2019/09/02 Python
使用python的turtle函数绘制一个滑稽表情
2020/02/28 Python
python调用API接口实现登陆短信验证
2020/05/10 Python
PyTorch中clone()、detach()及相关扩展详解
2020/12/09 Python
Aveda美国官网:天然护发产品、洗发水、护发素和沙龙
2016/12/09 全球购物
世界上最值得信赖的多日游在线市场:TourRadar
2018/07/20 全球购物
Kaufmann Mercantile官网:家居装饰、配件、户外及更多
2018/09/28 全球购物
岗位竞聘演讲稿
2014/01/10 职场文书
学校献爱心活动总结
2014/07/08 职场文书
长城导游词300字
2015/01/30 职场文书
MYSQL 运算符总结
2021/11/11 MySQL
Python中如何处理常见报错
2022/01/18 Python