vue小知识~实现父子组件双向数据绑定
vue的数据是单向数据流动,在子组件中是不可以修改父组件的数据的,但是还是可以通过其他方式间接修改父组件的数据。
核心思想:数据在哪个组件,就在哪个组件修改。
1,方式一:通过向子组件传递方法
这个方式主要是在父组件内定义一个改变父组件数据的方法,然后将方法转入大子组件内。由于vue数据是单向流动的,父组件的数据只能通过父组件直接修改,而子组件只能间接修改,子组件间接修改的方式就是获取到父组件传递过来的方法,向该方法传入一个值以修改父组件的数据。
代码流程如下:
父组件:
<template>
<div id="app">
<div>{{ numbers }}</div>
<boy :changNumber="changNumber"></boy>
</div>
</template>
<script>
import boy from './components/boy.vue';
export default {
components: {
boy
},
data() {
return {
numbers: 0
};
},
methods: {
changNumber(value) {
this.numbers = value;
}
}
};
</script>
<style>
</style>
这里我们需要修改的数据是numbers,在父组件定义一个修改该组件的方法changNumber(参数就需要在子组件内传入),将这个方法传入子组件。
<boy :changNumber="changNumber"></boy>
子组件:
<template>
<div class="checked-box">
<input v-model="num" />
<button @click="change">改变</button>
</div>
</template>
<script>
export default {
props: ['changNumber'],
data() {
return {
num: 1
};
},
methods: {
change() {
this.changNumber(this.num);
}
}
};
</script>
<style scoped></style>
子组件首先使用props接收父组件转过来的方法:
props: ['changNumber'],
什么了这个方式之后,相对于在该组件的数据中以及存在changNumber方法的索引,此时相当于在子组件的data中存在changNumber这个方法变量(引用),所以取值得时候需要使用this来取。
随后在子组件内定义一个方法来实现间接改变父组件内的数据。

2,方式二,使用$emit来触发绑定在子组件的方法。
该方式主要是在父组件引入组件时,在引入的组件标签上绑定一个方法,这时子组件的$emit实例上就会有该方法,可用在子组件中使用$emit触发绑定在它的方法上,来实现修改父组件的数据。值得注意的是,在子组件标签上需要绑定被修改的变量,将这个变量传入子组件内并接收。
代码:父组件
<template>
<div id="app">
<div>{{ numbers }}</div>
<boy :nums="numbers" @changNumber="changNumber"></boy>
</div>
</template>
<script>
import boy from './components/boy.vue';
export default {
components: {
boy
},
data() {
return {
numbers: 0
};
},
methods: {
changNumber(value) {
this.numbers = value;
}
}
};
</script>
<style></style>
子组件:
<template>
<div class="checked-box">
<input v-model="num" />
<button @click="change">改变</button>
</div>
</template>
<script>
export default {
props: ['nums'],
data() {
return {
num: 1
};
},
methods: {
change() {
this.$emit('changNumber', this.num);
}
}
};
</script>
<style scoped></style>
运行结果:

这里可能会有人不了解,为什么子组件还需要接收父组件的数据而不是接收绑定的方法。
这里要注意的是,子组件标签已经绑定了方法,在它的实例上已经存在了,只需要通过$emit来触发该方法执行就可以了,但是需要传入父组件中需要修改的数据,这是需要通知子组件的的方法,要修改的是哪个数据。
this.$emit('changNumber', this.num);
相当于:
this.$emit(
changNumber(value) {
this.numbers = value;
},
this.num
);
如果不传入父组件的数据numbers ,子组件将会报undefined的错。
以上代码中。父组件可以简写为:
<template>
<div id="app">
<div>{{ numbers }}</div>
<boy :nums="numbers" @changNumber="changNumber=>thischangNumber=changNumber"></boy>
</div>
</template>
<script>
import boy from './components/boy.vue';
export default {
components: {
boy
},
data() {
return {
numbers: 0
};
},
methods: {
}
};
</script>
<style></style>
3,方式三,使用v-model实现父子组件双向数据绑定。
还记得方式而中的这段吗?
<boy :nums="numbers" @changNumber="changNumber=>thischangNumber=changNumber">
我们给标签绑定一个方法和传入一个参数,就可以实现父子组件双向数据绑定了,如果这个标签是一个html标签呢?
啊!
这个是不是和v-model实现的功能类似?
其实,这个就是v-model的实现原理,我们在一个标签使用v-model的时候,渲染过程中会把v-model渲染成名为:value和@input。
<boy :value="numbers" @input="changNumber=>thischangNumber=changNumber"></boy>
等价于
<boy v-model="numbers"></boy>
所以就清晰了。
父组件:
<template>
<div id="app">
<div>{{ numbers }}</div>
<boy v-model="numbers"></boy>
</div>
</template>
<script>
import boy from './components/boy.vue';
export default {
components: {
boy
},
data() {
return {
numbers: 0
};
}
};
</script>
<style></style>
子组件:
<template>
<div class="checked-box">
<input v-model="num" />
<button @click="change">改变</button>
</div>
</template>
<script>
export default {
props: ['value'],
data() {
return {
num: 1
};
},
methods: {
change() {
this.$emit('input', this.num);
}
}
};
</script>
<style scoped></style>
效果图:

需要注意的是,子组件中的props接收的名称不一定是叫value,$emit触发的方法必须是input(不会报错,但是数据不会改变)
如下:
子组件:
<template>
<div class="checked-box">
<input v-model="num" />
<button @click="change">改变</button>
</div>
</template>
<script>
export default {
props: ['shdfnf'],
data() {
return {
num: 1
};
},
methods: {
change() {
this.$emit('input', this.num);
}
}
};
</script>
<style scoped></style>
效果为:

说明
props: ['shdfnf'],
可以接收任意变量名。而改变input名呢?
子组件:
<template>
<div class="checked-box">
<input v-model="num" />
<button @click="change">改变</button>
</div>
</template>
<script>
export default {
props: ['value'],
data() {
return {
num: 1
};
},
methods: {
change() {
this.$emit('input1234', this.num);
}
}
};
</script>
<style scoped></style>
效果图:

它既不报错,怎么点击按钮,值也无法跟着变化。
写了这么多,讲的这么细,难道不知道您点个赞吗?

vue小知识~实现父子组件双向数据绑定的更多相关文章
- Vue父子组件双向数据绑定
[本文出自天外归云的博客园] 简介 Vue版本:2.9.6 Element版本:2.4.8 问题描述:子组件对Element中el-select进行封装,父组件中把选中的值selected和所有选项o ...
- vue小故事之父子(上下级)通信之父传子props
vue小故事之父子(上下级)通信之父传子props vue 父子(上下级)通信 props 或许你对父子通信有点迷糊,为什么这样那样父子之间就可以通信了,以下通过一个小故事来进行解说,故事模型或许有 ...
- Angular中父子组件双向绑定传值
下面为大家展示一个较为简单的ng父子组件双向绑定传值,下面是父组件页面 这个页面的大概功能就是父组件(红色)通过输入框输入内容反映到子组件上进行展示,并且进行了投影, 子组件(橙黄色)通过Input输 ...
- vue 父子组件双向绑定
vue组件有2大特性: 1.全局组件和局部组件 2.父子组件的数据传递 接下来直接用demo直接看如何传值(静态传值) father.vue <template> <div> ...
- vue v-io 父子组件双向绑定多个数据
vue-io-directive 可以减少使用emit,组件自带的v-model好像也只能设置一个 安装 npm i vue-io-directive 使用 import Vue from 'vue' ...
- 三大前端框架(react、vue、angular2+)父子组件通信总结
公司业务需要,react.vue.angular都有接触[\无奈脸].虽然说可以拓展知识广度,但是在深度上很让人头疼.最近没事的时候回忆各框架父子组件通信,发现很模糊,于是乎稍微做了一下功课,记录于此 ...
- 详细讲解vue.js里的父子组件通信(props和$emit)
在进入这个话题之前,首先我们先来想一下在vue里,如何写一个父子组件.为了简单起见,下面的代码我都没用脚手架来构建项目,直接在html文件里引入vue.js来作为例子.父子组件的写法如下: <d ...
- vue3.x自定义组件双向数据绑定v-model
vue2.x 语法 在 2.x 中,在组件上使用 v-model 相当于绑定 value prop 并触发 input 事件: <ChildComponent v-model="pag ...
- Vue基础-渲染函数-父子组件-传递数据
Vue 测试版本:Vue.js v2.5.13 做了个 demo,把父子组件的数据都绑定到 Vue 实例 app 上,注释中的 template 相对好理解些 <div id="app ...
- 2-4 Vue中的属性绑定和双向数据绑定
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
随机推荐
- c# - 如何在圆角 WPF 窗体中创建圆角矩形?
我正在 WPF 中创建一个应用程序,我想要圆角.收到.现在窗体是无边框的,我正在尝试创建一个圆角矩形并将其放在顶部,使其看起来像 Windows 应用程序的顶部栏. 我做不到. 这是我的代码: < ...
- IOS Video Tool Box后台解码失败
---恢复内容开始--- 1.VideoToolBox硬件解码H264流的过程中,如果App从前台按Home键进入后台,会立马产生一个-12903的错误 如果这个时候重置解码器,继续解码,会遇到 - ...
- TIM_Cmd()函数引发的思考
在使用定时器的输入捕获进行频率测量时发现用TIM_Cmd()函数关闭定时器后,输入捕获中断还是会被触发,这就很奇怪了,输入捕获是定时器的一种模式,关闭定时器不就意味着输入捕获捕获也被关闭了吗?可是实际 ...
- uniapp 跳转指定的tab导航页面
考察的知识点:1.uniapp的页面跳转方法:uni.navigateTo2.页面跳转传值的方法:'?名称=值' 的方式3.参数的接收 onload(option){} 第一个页面的写法: toCom ...
- Atlas快速入门
先说一些废话 之前的公司在数据中台的项目上调研决定启用了Atlas作为我们数据血缘管理的工具,让我给大家写了一份Atlas快速入门的文档,所以在这里我将这篇文档以一个纯新手视角的方式再一次优化,希望能 ...
- SELinux 安全模型——MLS
首发公号:Rand_cs SELinux 安全模型--MLS BLP 模型:于1973年被提出,是一种模拟军事安全策略的计算机访问控制模型,它是最早也是最常用的一种多级访问控制模型,主要用于保证系统信 ...
- 对pta的总结_1
前言 这三次pta难度在不断上升的同时,要求我们线上慕课+自主学习来了解更多的java中的各种方法,如:正则表达式 List Map等.与此同时要求我们展开尝试并熟练类的构造,类的引用,链表的基本运用 ...
- log4net info 方法 根据不同业务创建不同的文件名
log4net info 方法 根据不同业务创建不同的文件名 <configuration> <!-- ... 其他配置 ... --> <configSections& ...
- edge 书签栏 收藏夹栏 字体大小
WIN10中,edge收藏夹栏字体太大,如果收藏数目多,得多翻好几页. 解决方法: 地址栏中输入: edge://flags/#edge-pc-ui-integration Enable Window ...
- JS 中 == 和 === 区别是什么?
a.对于string,number等基础类型,==和===有区别:不同类型间比较,==之比较"转化成同一类型后的值"看"值"是否相等,===如 果类型不 ...