深入浅析Vue不同场景下组件间的数据交流


Posted in Javascript onAugust 15, 2017

正文

浅谈Vue不同场景下组件间的数据“交流” 

Vue的官方文档可以说是很详细了。在我看来,它和react等其他框架文档一样,讲述的方式的更多的是“方法论”,而不是“场景论”,这也就导致了:我们在阅读完文档许多遍后,写起代码还是不免感到有许多困惑,因为我们不知道其中一些知识点的运用场景。这就是我写这篇文章的目的,探讨不同场景下组件间的数据“交流”的Vue实现

父子组件间的数据交流

父子组件间的数据交流可分为两种:

1.父组件传递数据给子组件

2.子组件传递数据给父组件

父组件传递数据给子组件——props

这是组件数据沟通中最常见的场景:你让父组件掌握了数据源,然后传递给子组件,供子组件使用

深入浅析Vue不同场景下组件间的数据交流

许多人会说,这很简单!用props嘛! 对,正因如此,它不是我要讲的主要内容,不过我们还是用代码简单过一遍:

父组件

<template>
 <div id="father">
 {{ '我是父组件' }}
 <son :text = "text"></son>
 </div>
</template>
<script>
import son from './son.vue'
export default {
 data: function () {
 return {
 text: '从父组件传来的数据'
 }
 },
 components: {
 son: son
 }
}
</script>
<style scoped>
</style>

子组件:

<template>
 <div>
 {{ '我是子组件,我接收了' + text }}
 </div>
</template>
<script>
export default {
 props: {
 text: { type: String, default: '' }
 }
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>

demo:

深入浅析Vue不同场景下组件间的数据交流

在这个demo里面,我们把“从父组件传来的数据”这一个字符串通过props传递给了子组件 

如果我们希望在子组件中改变父组件的数据的话,可以在父组件中定义一个能改变父组件数据的函数,然后通过props将该函数传递给子组件,并在子组件在适当时机调用该函数——从而起到在子组件中改变父组件数据的效果

子组件传递数据给父组件

子组件传递数据给父组件   方式一:回调传参

父组件:

<template>
 <div id="father">
 {{ '我是父组件,名称是' + componentName }}
 <son :changeComponentName = "changeComponentName"></son>
 </div>
</template>
<script>
import son from './son.vue'
export default {
 data: function () {
 return {
 componentName: '组件A'
 }
 },
 methods: {
 changeComponentName: function (newComponentName) {
 this.componentName = newComponentName
 }
 },
 components: {
 son: son
 }
}
</script>
<style scoped>
 #father div{
 padding: 10px;
 margin: 10px;
 border: 1px solid gray;
 }
</style>

子组件:

<template>
 <div>
 <p>我是子组件:一个button</p>
 <button @click="() => changeComponentName(newComponentName)">
 把父组件的名称修改为:彭湖湾的组件
 </button>
 </div>
</template>
<script>
export default {
 data: function () {
 return {
 newComponentName: '彭湖湾的组件'
 }
 },
 props: {
 changeComponentName: {
 type: Function,
 default: () => { }
 }
 }
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>

demo:

点击前:

深入浅析Vue不同场景下组件间的数据交流

点击后:

深入浅析Vue不同场景下组件间的数据交流

图解:

深入浅析Vue不同场景下组件间的数据交流

点击子组件(按钮)的时候,将父组件的名称从“A”修改为“彭湖湾的组件”

我们从父组件向子组件传递了一个函数(changeComponentName)。并在子组件调用这个函数的时候,以参数的形式传递了一个子组件内部的数据(newComponentName)给这个函数,这样,在父组件中定义的函数(changeComponentName)就可以取得子组件传来的参数了 

【PS】 命名太长不好意思

子组件传递数据给父组件   方式二:自定义事件

父组件:

<template>
 <div id="father">
 <div>
 {{ '我是父组件,我的名称是:' + fatherComponentName }}
 <son v-on:changeComponentName = "changeComponentName"></son>
 </div>
 </div>
</template>
<script>
import son from './son.vue'
export default {
 data: function () {
 return {
 fatherComponentName: 'A组件'
 }
 },
 methods: {
 changeComponentName: function (componentName) {
 this.fatherComponentName = componentName
 }
 },
 components: {
 son: son
 }
}
</script>
<style scoped>
 #father div{
 padding: 10px;
 margin: 10px;
 border:1px solid grey;
 }
</style>

子组件:

<template>
 <div>
 <p>我是子组件:一个按钮</p>
 <button @click="clickCallback">
 修改父组件的名称为:彭湖湾的组件
 </button>
 </div>
</template>
<script>
export default {
 data: function () {
 return {
 fatherComponentName: '彭湖湾的组件'
 }
 },
 methods: {
 clickCallback: function () {
 this.$emit('changeComponentName', this.fatherComponentName)
 }
 }
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>

 demo:

点击前:

深入浅析Vue不同场景下组件间的数据交流

点击后:

深入浅析Vue不同场景下组件间的数据交流

 图解:

深入浅析Vue不同场景下组件间的数据交流

通过$emit(event, [...参数]),所有的参数将被传递给监听器回调,也就是我们在父组件中定义的changeComponentName方法,从而实现从子组件中给父组件传参

兄弟组件间的数据交流(有共同父组件的兄弟组件)

父组件:

<template>
 <div id="father">
 <div>
 {{ '我是父组件:father' }}
 <eldest-son :text = "text"></eldest-son>
 <youngest-son :changeText="changeText"></youngest-son>
 </div>
 </div> 
</template>
<script>
import eldestSon from './eldestSon.vue'
import youngestSon from './youngestSon.vue'
export default {
 data: function () {
 return {
 text: '我是一行文本'
 }
 },
 methods: {
 changeText: function () {
 this.text = '我是经过改动的一行文本'
 }
 },
 components: {
 eldestSon: eldestSon,
 youngestSon: youngestSon
 }
}
</script>
<style>
 #father div{
 border: 1px solid grey;
 padding: 10px;
 margin: 10px;
 }
</style>

兄弟组件1:

<template>
 <div>
 <p>我是兄弟组件:eldestSon</p>
 <p>我有一个可变数据text:{{ text }}</p>
 </div>
</template>
<script>
export default {
 props: {
 text: {
 type: String,
 default: ''
 }
 }
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>

兄弟组件2:

<template>
 <div>
 <p>我是兄弟组件:youngestSon</p>
 <button @click="changeText">更改eldestSon兄弟组件中的文本</button>
 </div>
</template>
<script>
export default {
 props: {
 changeText: {
 type: Function,
 default: () => {}
 }
 }
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>

 点击前:

深入浅析Vue不同场景下组件间的数据交流

点击后:

深入浅析Vue不同场景下组件间的数据交流

 图解:

深入浅析Vue不同场景下组件间的数据交流

如果两个兄弟组件间存在这种数据关系的话,我们可以尝试寻找其共同的父组件,使数据和相关方法“提升”到父组件内部,并向下传给两个子组件 

这样,其中一个子组件取得了数据,另外一个子组件取得了改变数据的方法,便可以实现上述的数据沟通 

【注意】这种场景存在局限性,它要求两个组件有共同父组件。对于这种场景之外的处理方法,请看下文

全局组件间的数据交流——Vuex

我上述的许多场景里面,都运用到了props或者函数传参的方式去处理组件间的数据沟通。然而在稍大型的应用里面,它们都不约而同地给我们带来了很大的麻烦

例如:

1.通过props从父组件向子组件传递数据

对于直接的父子关系的组件,数据流显得很简洁明确,但在大型应用里面,我们上下嵌套许多个组件的时候,这就会导致我们的代码非常地繁琐,并难以维护 

2.对于没有共同的父组件的兄弟组件,函数传参的数据传递方式也无能为力了,Vue文档里介绍到,你可以通过以$emit和$on函数为基础的“事件总线”沟通数据,但它无法应对更加大型的应用 

这个时候Vuex就成为了实现全局组件间数据交流的最佳方案了

Vuex拥有一个包含全部顶层状态的单一数据源(state)

1.所有的组件都可以使用这个单一数据源里面的数据

2.所有的组件都可以通过派发 动作(actions)修改这个单一数据源里的数据 

深入浅析Vue不同场景下组件间的数据交流

原本要“走很多弯路”才能实现沟通的数据流,一下子就找到了最短的捷径 

实现View层的数据和model层的解耦

在1,2小节中处理的数据(Vue)和第三小节中处理的数据(Vuex),在很多时候是两种不同类型的数据,前者是属于View层,仅负责单纯的UI展示,而model层的大多是从后端取得后注入的数据。 

一点建议:

1.Vue部分的代码负责构建View层

2.Vuex部分的代码负责构建model层

(上述的Vue指的是Vuex之外的框架体系)

以上述两点为基础,决定某部分的代码到底要写进Vue里面还是写进Vuex里面,并尽量将两者分开,从而实现View层和model层的解耦,提高前端代码的可维护性和扩展性

总结

以上所述是小编给大家介绍的Vue不同场景下组件间的数据交流,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
jQuery+css+html实现页面遮罩弹出框
Mar 21 Javascript
Javascript 数组排序详解
Oct 22 Javascript
jquery实现简单的全选和反选功能
Jan 02 Javascript
Bootstrap框架下下拉框select搜索功能
Mar 26 Javascript
JS实现漂亮的时间选择框效果
Aug 20 Javascript
详解js的事件处理函数和动态创建html标记方法
Dec 16 Javascript
bootstrap table插件的分页与checkbox使用详解
Jul 23 Javascript
使用Vue.js开发微信小程序开源框架mpvue解析
Mar 20 Javascript
vue使用ElementUI时导航栏默认展开功能的实现
Jul 04 Javascript
vue+element模态框中新增模态框和删除功能
Jun 11 Javascript
mui js控制开关状态、修改switch开关的值方法
Sep 03 Javascript
vue中组件通信详解(父子组件, 爷孙组件, 兄弟组件)
Jul 27 Javascript
React应用中使用Bootstrap的方法
Aug 15 #Javascript
JavaScript函数中的this四种绑定形式
Aug 15 #Javascript
详解react使用react-bootstrap当轮子造车
Aug 15 #Javascript
JScript实现表格的简单操作
Aug 15 #Javascript
AngularJS日程表案例详解
Aug 15 #Javascript
jQuery实现菜单栏导航效果
Aug 15 #jQuery
js实现网页的两个input标签内的数值加减(示例代码)
Aug 15 #Javascript
You might like
php 广告调用类代码(支持Flash调用)
2011/08/11 PHP
采用memcache在web集群中实现session的同步会话
2014/07/05 PHP
PHP生成指定长度随机数最简洁的方法
2014/07/14 PHP
Yii2.0使用阿里云OSS的SDK上传图片、下载、删除图片示例
2017/09/20 PHP
laravel框架模型和数据库基础操作实例详解
2020/01/25 PHP
js的逻辑运算符 ||
2010/05/31 Javascript
JS 图片缩放效果代码
2010/06/09 Javascript
node.js入门教程
2014/06/01 Javascript
完美兼容各大浏览器的jQuery仿新浪图文淡入淡出间歇滚动特效
2014/11/12 Javascript
JS实现向表格行添加新单元格的方法
2015/03/30 Javascript
js实现温度计时间样式代码分享
2015/08/21 Javascript
基于JavaScript实现通用tab选项卡(通用性强)
2016/01/07 Javascript
JS中的二叉树遍历详解
2016/03/18 Javascript
jQuery ajax MD5实现用户注册即时验证功能
2016/10/11 Javascript
纯JavaScript手写图片轮播代码
2016/10/20 Javascript
jQuery基本筛选选择器实例代码
2017/02/06 Javascript
ES6新特性二:Iterator(遍历器)和for-of循环详解
2017/04/20 Javascript
BootStrap 表单控件之单选按钮水平排列
2017/05/23 Javascript
5分钟学会Vue动画效果(小结)
2018/07/21 Javascript
Node.js EventEmmitter事件监听器用法实例分析
2019/01/07 Javascript
在vue+element ui框架里实现lodash的debounce防抖
2019/11/13 Javascript
jQuery实现聊天对话框
2020/02/08 jQuery
Python中的引用和拷贝浅析
2014/11/22 Python
浅谈Python 中整型对象的存储问题
2016/05/16 Python
Python操作mysql数据库实现增删查改功能的方法
2018/01/15 Python
python3.4实现邮件发送功能
2018/05/28 Python
python库lxml在linux和WIN系统下的安装
2018/06/24 Python
Python程序暂停的正常处理方法
2019/11/07 Python
Python破解BiliBili滑块验证码的思路详解(完美避开人机识别)
2020/02/17 Python
分厂厂长岗位职责
2013/12/29 职场文书
应届生找工作求职信
2014/06/24 职场文书
县委班子四风对照检查材料思想汇报
2014/09/29 职场文书
2015年大学班级工作总结
2015/04/28 职场文书
2016年中学清明节活动总结
2016/04/01 职场文书
MongoDB orm框架的注意事项及简单使用
2021/06/20 MongoDB
Python实现滑雪小游戏
2021/09/25 Python