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#实现的一个图片切割工具
效果如图: 工具代码: using System.Drawing; using System.Drawing.Imaging; class ImageCutterConfig { /// <su ...
- Java中的变量分类(按照位置分类)
变量按位置分 通过上面类的建立我们又得到了新的概念:成员变量和局部变量 成员变量: 可以使用基本数据类型,也可以使用引用数据类型. java中的变量在使用时必须初始化,成员变量可以不对其初始化,系统会 ...
- 探索Native Plugins:开启大模型的技能之门
前言 上一章节我们了解了一下Semantic Kernnel中Plugins插件的概念以及学习了的 Semantic Kernel 模板插件的创建,本章节我们来学习 Native Plugins 原生 ...
- C#.NET X509Certificate2 该项不适于在指定状态下使用
X509Certificate2 x509 = new X509Certificate2(lblPfxPath.Text,txtPfxPwd.Text.Trim() ); string xmlpri= ...
- 在.NET Core,除了VB的LikeString,还有其它方法吗?(四种LikeString实现分享)
Like运算符很好用,特别是它所提供的其中*.?这两种通配符,在Windows文件系统和各类项目中运用非常广泛. 但Like运算符仅在VB中支持,在C#中,如何实现呢? 以下是关于LikeString ...
- 串口收发UART(Verilog HDL)
UART(Universal Asynchronous Receiver Transmitter,通用异步收发器)是一种异步串行通信协议,主要用于计算机和嵌入式系统之间的数据交换. 实现UART通信的 ...
- 深入了解身份认证和授权机制,看看API请求到底发生了什么?
前段时间写了一篇基于.NetCore环境使用IdentityServer4为API接口鉴权的文章,更多的是从快速上手的角度描述了IdentityServer4的使用.后续使用过程中,自己有了一些其他想 ...
- Python 安装 matlabengin 时遇到报错:setup.py install is deprecated. !! 以及 Cannot update time stamp of directory 'dist\matlabengine.egg-info' 的解决方案
目录 Python 安装 matlabengin 时遇到报错:setup.py install is deprecated. !! 以及 Cannot update time stamp of dir ...
- Golang线程池gpool
背景 golang中使用并发要考虑很多问题,如控制并发量.等待Goroutine执行完毕等. 看下面一段代码: var wg sync.WaitGroup count := 10 wg.Add(cou ...
- Jetpack Compose(7)——触摸反馈
目录 一.点按手势 1.1 Modifier.clickable 1.2 Modifier.combinedClickable 二.滚动手势 2.1 滚动修饰符 Modifier.verticalSc ...