vue.js组件之间的数据共享
一、组件之间的关系
在项目开发中,组件之间的最常见的关系分为如下两种:
①父子关系
②兄弟关系
二、组件之间的数据共享
父子组件之间的数据共享又分为
①父 -> 子共享数据
②子 -> 父共享数据
1、父组件向子组件共享数据
父组件向子组建共享数据需要使用自定义属性。事例代码如下:
子组件利用props自定义属性,父组件在调用子组件的时候使用这个自定义属性,并添加属性值,字组件就会接收到数据。
如果直接在子组件中修改prop,Vue会发出警告,因为prop属于单向数据流,即父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外改变父级组件的状态,所以这里有两种常见的方法在子组件中修改prop传递的值。
方法一: 先在子组件的data中定义一个变量并把prop作为初始值 js
- 本地定义一个变量,并将prop作为初始值
data: function () {
return {
message: this.msg
}
- prop 以一种原始的值传入且需要进行转换,在computed中定义
computed: {
normalizedSize: function () {
return this.size.trim().toLowerCase()
}
}
注:Prop 的大小写 (camelCase vs kebab-case)
HTML 中的 attribute 名是大小写不敏感的,所以浏览器会把所有大写字符解释为小写字符。这意味着当你使用 DOM 中的模板时,camelCase (驼峰命名法) 的 prop 名需要使用其等价的 kebab-case (短横线分隔命名) 命名:
Vue.component('blog-post', {
// 在 JavaScript 中是 camelCase 的
props: ['postTitle'],
template: '<h3>{{ postTitle }}</h3>'
})
<!-- 在 HTML 中是 kebab-case 的 -->
<blog-post post-title="hello!"></blog-post>
重申一次,如果你使用字符串模板,那么这个限制就不存在了。
例如:在开发中子组件定义自定义属性为驼峰命名法,如:
tempSwitch: {
type: Boolean,
default: false
},
在父组件中使用此属性时为了方便区分,将使用短横线分隔命名:
:temp-switch="tempSwitch"
2、子组件向父组件共享数据
子组件向父组件共享数据使用自定义事件。示例代码如下:
子组件是用$emit定义自定义事件的名称,并加上所要传递的值,父组件使用此事件,并在事件后面加上相应的函数方法,函数里面的传递的值,就是子组件要给父组件传递的值。
3、兄弟组件之间的数据共享
在 vue2.x 中,兄弟组件之间数据共享的方案是 EventBus
EventBus 的使用步骤:
① 创建 eventBus.js 模块,并向外共享一个 Vue 的实例对象
② 在数据发送方,调用 bus.$emit(‘事件名称’, 要发送的数据) 方法触发自定义事件
③ 在数据接收方,调用 bus.$on(‘事件名称’, 事件处理函数) 方法注册一个自定义事件
4、$parent 或$ root
通过共同祖辈$parent
或者$root
搭建通信桥连
兄弟组件
this.$parent.on('add',this.add)
另一个兄弟组件
this.$parent.emit('add')
5、$attrs 与$ listeners
- 适用场景:祖先传递数据给子孙
- 设置批量向下传属性
$attrs
和$listeners
- 包含了父级作用域中不作为
prop
被识别 (且获取) 的特性绑定 ( class 和 style 除外)。 - 可以通过
v-bind="$attrs"
传⼊内部组件
// child:并未在props中声明foo
<p>{{$attrs.foo}}</p>
// parent
<HelloWorld foo="foo"/>
// 给Grandson隔代传值,communication/index.vue
<Child2 msg="lalala" @some-event="onSomeEvent"></Child2>
// Child2做展开
<Grandson v-bind="$attrs" v-on="$listeners"></Grandson>
// Grandson使⽤
<div @click="$emit('some-event', 'msg from grandson')">
{{msg}}
</div>
6、provide 与 inject
- 在祖先组件定义
provide
属性,返回传递的值 - 在后代组件通过
inject
接收组件传递过来的值
祖先组件:
provide(){
return {
foo:'foo'
}
}
后代组件:
inject:['foo'] // 获取到祖先组件传递过来的值
7、vuex
- 适用场景: 复杂关系的组件数据传递
Vuex
作用相当于一个用来存储共享变量的容器
state
用来存放共享变量的地方getter
,可以增加一个getter
派生状态,(相当于store
中的计算属性),用来获得共享变量的值mutations
用来存放修改state
的方法。actions
也是用来存放修改state的方法,不过action
是在mutations
的基础上进行。常用来做一些异步操作