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 ...
随机推荐
- phpstorm配置laravel语法提示
摘自:https://cloud.tencent.com/developer/article/1426699 phpstorm配置laravel语法提示 2019-05-15阅读 1930 用习惯 ...
- uni-app前端图表组件库,折线图横屏android失败的解决办法
网址:https://www.ucharts.cn/v2/#/demo/index,需要登录,微信就可以 我在使用折现图时,业务需要把曲线图在点击全屏时横屏全屏显示.就做个全屏页面,点击后,把opti ...
- .NET Core应用程序每次启动后使用string.GetHashCode()方法获取到的哈希值(hash)不相同
前言 如标题所述,在ASP.NET Core应用程序中,使用string.GetHashCode()方法去获取字符串的哈希值,但每次重启这个ASP.NET Core应用程序之后,同样的字符串的哈希值( ...
- vue3组件通信与props
title: vue3组件通信与props date: 2024/5/31 下午9:00:57 updated: 2024/5/31 下午9:00:57 categories: 前端开发 tags: ...
- react props进阶 children属性
children属性,表示组件标签的子节点,当组件标签有子节点时,props就会有该属性,与与普通的props一样,其值可以使任意类型. # 父组件 class App extends React.C ...
- C#.NET MySql8.0 EF db first
.net framework 4.5.2,winform 程序. mysql 8.0 1.nuget中引用EntityFramework,6.4.4 2.nuget中引用MySql.Data.Enti ...
- Vue学习:16.组件通信
组件通信就是指组件之间的数据传递.由于组件的数据是独立的,无法直接访问其他组件的数据,所以想要使用其他组件数据必须通过 组件通信! 在Vue.js中,组件之间的通信可以通过多种方式实现,包括 prop ...
- RequestBodyAdvice和注解方式进行统一参数处理demo
RequestBodyAdvice和注解方式进行统一参数处理demo @Target({ ElementType.METHOD, ElementType.TYPE }) @Retention(Rete ...
- 高级前端开发需要知道的 25 个 JavaScript 单行代码
1. 不使用临时变量来交换变量的值 例如我们想要将 a 于 b 的值交换 let a = 1, b = 2; // 交换值 [a, b] = [b, a]; // 结果: a = 2, b = 1 这 ...
- 调用了这么久的JS方法是长在对象、类、值本身还是原型链上?
调用了这么久的JS方法是长在对象.类.值本身还是原型链上? JavaScript这门语言总是能带给我惊喜,在敲代码的时候习以为常的写法,退一步再看看发现自己其实对很多基操只有表面的使用,而从来没思考过 ...