在Vue中组件是实现模块化开发的主要内容,而组件的通信更是vue数据驱动的重点,总结一下目前我了解的组件之间数据通信和访问的方法。
v-bind和props
父组件在子组件上使用v-bind绑定数据1
2
3<div>
<child :child-msg="msg"></child> //这里必须要用 - 代替驼峰
</div>
1 | data () { |
子组件通过props来接收数据1
<div>{{childMsg}}</div> //hello
1 | props: ['childMsg'] |
可以通过使用this.childMsg调用数据。
自定义事件和$emit
子组件要向父组件传递数据,需要使用触发事件的方式,使用$emit通知父组件改变数据1
<button @click='up'>发送</button>
1 | data () { |
父组件监听子组件触发的up事件,然后调用change方法1
2
3<div>
<child @getChildMsg="change"></child>
</div>
1 | methods: { |
v-model
在介绍了props
和$emit
之后,就可以根据它们来实现在自定义组件上使用v-model
来进行数据通信了。
首先简单的解释一下v-model
与二者的关系,以下两中写法实现的效果相同:1
2
3
4
5
6
7
8
9
10// 使用v-model
<component v-model='msg'></component>
// 使用props和$emit
<component :value='msg' @input='getMsg'></component>
……
getMsg(value){
this.msg = value;
}
对于v-model
绑定的变量,相当于在子组件上面绑定了一个value
属性,还可以通过接收子组件传递的input
属性来再次赋值。
这么解释太抽象了,下面是一个简单的封装input组件的例子:
父组件1
<my-input v-model='number'></my-input>
子组件1
2
3<div>
<input type="text" v-model='inputValue'>
</div>
1 | <script> |
路由传参
在路由页面跳转时,可以通过传递参数的方式拿到数据。
- router-link
1 | <router-link |
需要注意的是,path和query,name和params都是成对出现的,即使用path进行路由跳转时,params的值是拿不到的,只能设置query,反之亦然。
params和query都可以传递,区别在于后者会出现在url上,考虑到刷新页面的情况,建议使用query
- $router方式
1 | this.$router.push({ |
参数的规则和router-link相同
- 获取参数的方式
对于使用params
方式传递的参数1
this.$route.params.name
对于使用query
方式传递的参数1
this.$route.query.name
- 动态路由匹配
在定义router时使用动态路径参数,以冒号开头1
2
3
4
5const router = new VueRouter({
routes: [
{ path: '/user/:id', component: User }
]
})
这时/user/foo
和 /user/bar
都将映射到相同的路由,在路由页面中获取:1
this.$route.params.user
- props 路由传参
1 | const router = new VueRouter({ |
将路由的props
属性设置为true,在路由页就可以通过使用props拿到数据:1
props: ['id']
通过slot通信
关于slot的使用就不介绍了,下面简单举个栗子1
2
3
4
5
6
7
8
9// 子组件
<div>
<slot msg="hi"></slot>
</div>
// 父组件
<child>
<div slot-scope="scope">{{ scope.msg }}</div> // hi
</child>
在slot插槽上绑定的数据可以通过slot-scope
拿到,这里也支持解构的写法1
2
3<child>
<div slot-scope="{ msg }">{{ msg }}</div> // hi
</child>
设置中间件
创建一个事件中心,相当于中间件,可以用它来传递事件和接收事件1
var vm = new Vue();
发送数据的组件触发1
<button @click="send">发送</button>
1 | methods: { |
接收数据的组件1
2
3
4
5created() {
vm.$on('change', (msg) => {
this.msg = msg; //hello
});
}
在vue文件中需要使用中间件通信时,创建中间件,如下1
2
3import Vue from 'Vue';
export default new Vue();
使用时在组件中import导入即可
父组件访问子组件
当我们需要在父组件中访问子组件时,可以使用$children
或者$ref
1
2
3
4
5
6
7
8
9
10
11
12//子组件1
data () {
return {
msg: '这是子组件1的信息'
}
}
//子组件2
data () {
return {
msg: '这是子组件2的信息'
}
}
$children
返回所有子组件的实例,是一个数组
1 | <div> |
1 | methods: { |
- 使用
ref
为子组件指定一个索引ID,可以在父组件使用$refs
访问到
1 | <div id="count"> |
1 | methods: { |
在调用子组件方法时,可以通过传参的方式把数据传到子组件
1 | //父组件 |
Promise方式
子组件中定义父组件需要调用的方法,并返回一个promise对象1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20data () {
return {
msg : 'hello',
promise : {
resolve: null,
reject : null
}
}
}
methods: {
show() {
return new Promise((resolve, reject) => {
this.promise.resolve = resolve;
this.promise.reject = reject;
});
},
send () {
this.promise.resolve(this.msg);
}
}
调用send方法时,执行promise的resolve方法,向父组件返回msg,父组件调用show方法拿到返回值1
<child ref="child"></child>
1 | //调用的方法中 |
result就是子组件返回的数据,即msg
Vuex
将数据存放在store中,另一组件获取state中的数据,或者watch state中数据的变化,来进行相应的操作
‘Vuex简单入门’
子组件访问父组件
在子组件中使用$parent
可以获取到父组件的对象,使用方法同$children
访问根组件
使用$root
可以获取当前组件树的根Vue实例。如果当前实例没有父实例,此实例将会是其自已