Vue中父子及非父子组件之间的通信方法
Vue中父子及非父子组件之间的通信方法
父子组件之间的通信方法
父级->子级通信 (依赖单向数据绑定+props实现)
Vue.component('Father', { //注册了含有data属性的父组件template: '#father',data () {return {val : 100,sav : 555}},});Vue.component('Son', { //注册了没有data的子组件template: '#son',});
可见,父级中有val、sav两条数据,如果其子组件可以使用自身的数据,首先需要的就是在子组件内部添加props属性
Vue.component('Son', {template: '#son',//props:[数组内可有一个或多个参数] props: ['val','sav']//props声明即表示该组件会使用父组件的数据});
为了语义化提升代码的可读性,推荐将参数名与父组件的属性名相同。
在渲染模板上将相应的参数名绑定在子组件上即可:
<template id="father"><div><h4>我是父组件</h4><hr><!-- 将父组件数据分别绑定在props中声明的参数上 --><!-- :props参数名 = '父组件数据' --><Son :val = 'val' :sav = 'sav'></Son></div></template><template id="son"><h4>我是子组件,我拿到了父组件的val:{{val}},以及:{{sav}}</h4></template>
浏览器中结果如下:
子级 -> 父级通信 (依赖自定义事件)
和父子通信依靠props属性不同,在子父通信中我们需要使用自定义事件的方法。
Vue中的自定义事件
不同于点击事件、监听事件等等依托一个特定媒介去触发事件内部函数方法,
自定义事件依靠this.$emit()触发事件,例如:
<!-- 通过v-on事件绑定,我们在该标签上绑定了一个自定义方法test -->
<my-component v-on:test="any"></my-component>
//使用this.$emit()触发事件
this.$emit('test')
需要注意的是,Vue文档中提示自定义事件的事件名会在DOM模板中被自动转换为小写。
不同于组件和 prop,事件名不会被用作一个 JavaScript 变量名或属性名,所以就没有理由使用 camelCase 或 PascalCase 了。并且
v-on
事件监听器在 DOM 模板中会被自动转换为全小写 (因为 HTML 是大小写不敏感的),所以v-on:myEvent
将会变成v-on:myevent
——导致myEvent
不可能被监听到。
使用自定义事件实现子父通信
在父组件中设置自定义事件(父组件内部定义了一个byson方法)
Vue.component('Father', {template: '#father',data () {return {val : 100,sav : 555}},methods: {byson ( val ) { //定义方法this.val = val;}}});
DOM模板中设定自定义事件,为了更好区分关系自定义事件名设置为’bysons’
<template id="father"><div><input type="text" v-model = 'val'><h4>我是父组件</h4><hr>
<!-- 在父组件中的子组件上绑定自定义事件byson1,这样就可以在点击事件触发时通过 this.$emit()调用方法 --><Son @bysons = 'byson'></Son></div></template>
子组件中设定事件触发这个自定义事件(这里使用的是点击事件)
Vue.component('Son', {template: '#son',data() {return {son: 669}},methods: {press() {//this.$emit('时间名',可选参数) 此处将子组件私有的son作为参数传递给父组件this.$emit('byson1', this.son);}},props: ['getFather', 'getSav']});
将点击事件绑定在子组件后,即可实现子->父通信功能,逻辑如下:
父组件中设定自定义事件 -> 子组件设置点击事件,执行触发父组件中的自定义事件。
非父子组件之间的通信
通过ref链实现
ref是什么
在Vue实例对象下有一个refs属性,其内容包含了所以作用域内组件的具体信息,利用ref实现非父子组件通信的核心逻辑就是通过操作$refs作为一个中间件来进行数据交换。
简单例子:通过点击事件改变一个非父子关系组件的样式
<body><div id="app"><button @click = "getP">get</button><p ref = "box"> 123 </p> //在标签中添加ref = 'name'来添加标识<p ref > 123 </p><Hello ref = "hello"></Hello></div>
</body>
<script>Vue.component('Hello',{template: '<div></div>',data () {return {money: 1000}}})new Vue({el: '#app',methods: {getP () {//通过refs操作box的样式this.$refs.box.style.background = 'red'}}})
</script>
refs的特点:除了对组件有效,$refs对DOM元素也有效,但是它的性能较差,不推荐使用。
更方便高效的思路 — 事件总线
因为$refs性能低下的问题,所以产生了另外一条思路:将数据托管在一个公共(全局属性)的中间件上,这样无论是不是存在父子关系都可以访问的到其内部的数据。
如何实现?
全局定义一个公共的Vue实例对象bus,用于存储数据
利用自定义事件发布和触发,实现通信
下面例子中,通过中间件bus,实现了非父子组件之间数据的交换:
<body><div id="app"><key-in></key-in><print-out></print-out></div><template id="in"><!-- 和add属性双向绑定 --><input type="text" v-model="add" @keyup.enter="addNew" /></template><template id="out"><ul><li v-for="item in lists">{{ item.text }}</li></ul></template>
</body>
<script src="../../lib/vue.js"></script>
<script>// bus事件总线思维: 将new Vue() 的实例作为全局变量,用来联通非父子组件var bus = new Vue();//注册组件Vue.component("keyIn", {template: "#in",data() {return {add: ""};},methods: {addNew() {//触发bus上的自定义事件pushInbus.$emit("pushIn", this.add);this.add = "";}}});//输出组件上绑定有一个数据数组用于渲染列表Vue.component("printOut", {template: "#out",data() {return {lists: [{id: 1,text: "测试"}]};},mounted() {//保存指向该组件的this指针var _this = this;// $on关键词设定bus上的自定义事件,将新数据push进数组中bus.$on("pushIn", function (val) {var list = {id: _this.lists.length + 1,text: val};_this.lists.push(list);});}});new Vue({el: "#app"});
</script>
Vue中父子及非父子组件之间的通信方法相关推荐
- 「后端小伙伴来学前端了」Vue中Props配合自定义方法实现组件间的通信
校园的云 前言 废话: 上篇文章写了关于Vue 中的 props
- Vue中基于Vuex使用echarts组件动态数据绑定的方法
效果如下: 1.导入echarts组件,建议使用4.9.0版本,5.0.1可能会报错 npm uninstall echarts //卸载npm install echarts@4.9.0//引入特定 ...
- Vue组件通信:任意组件之间进行通信
之前一篇博客,我们介绍了子组件向父组件通信的方法,可以参考博客: 深度理解Vue组件的子组件向父组件传递数据的通信方式,全面详细,看这一篇就够了,推荐收藏_czjl6886的博客-CSDN博客 今天, ...
- Vue非父子组件之间的通信
文章目录 非父子组件的通信 1.Provide和Inject 1.1基本使用 1.2处理响应式数据(了解) 2.全局事件总线 非父子组件的通信 此篇讲解的是, 在学习状态管理之前, 非父子间通信的方案 ...
- Vue中关于父子组件之间的通信
父子组件之间的通信是vue中的基础知识,在此做一个简单的梳理. 总的来说父传子是通过props,子传父是通过$emit. 简单的一个demo来说说,先上代码 父组件: 如图,HelloWorld是一个 ...
- vue/父子组件之间的通信
父子组件之间的通信 父组件绑定数据在组件上子组件props属性接收 父组件内的data属性中待传的数据data1 => <cpn :data2="data1">& ...
- vue父子组件之间传值的方法
vue父子组件之间传值的方法 一.基本父子传值 父传子 方式: props 效果: 把父组件的fatherName属性传入子组件,在子组件中使用 父组件代码: <template>< ...
- vue的父子组件之间的通信详解
vue的父子组件之间的通信详解 一.父组件给子组件传值 父组件引入子组件,并对子组件进行监听 <!-- 父组件 --><template><div><h1&g ...
- VUE 2.0 父子组件之间的通信
父组件是通过props属性给子组件通信的来看下代码: 父组件: <parent><child :child-com="content"></child ...
最新文章
- Hibernate5.x Idea搭建
- Linux中look命令,如何在Linux上使用look命令 | MOS86
- 为什么python不出结果_Python 的 Checksum 为什么结果是一长串数字而不是如下效果...
- JZOJ 5305. 【NOIP2017提高A组模拟8.18】C
- 天天象棋 残局闯关 第15关
- .Net Core中使用ref和Spanamp;lt;Tamp;gt;提高程序性能
- 绘制几何图形——使用android.graphics类 onDraw
- 通过两个小栗子来说说Java的sleep、wait、notify、notifyAll的用法
- 玩转Android Camera开发(一):Surfaceview预览Camera,基础拍照功能完整demo
- Caffe学习:Blobs, Layers, and Nets
- 计算机打字键盘亮怎么设置,键盘指示灯亮着却不能打字的解决方法
- ubuntu20.04 NVIDIA显卡驱动安装教程(Y9000p)
- MBP清除NVRAM和PRAM
- 7-3 寻找大富翁 (50分)
- PDF文件怎么拆分页面
- 启动vidalia 时不用打开firefox
- 使用Unity3D制作Flappy Bird
- duet太香啦啦啦啦啦啦啦啦啦啦
- 对抗网络之PG-GAN,无条件下生成更真实的人脸图像
- 从打车到专车,滴滴们除了烧钱还有什么?