一、vue
的传值方式
1、父向子传递
属性Props
//child
porops:{msg:String}
//parent
<Helloworld msg="我是传递给child的" />
2、子向你传递
引用refs
//child
data(){
return {
hw:"我是子类父类可以调用"
}
}
//parent
<Helloworld ref="hw" />
this.$refs.hw
3.provide
和inject
实现袓孙传值
provide:就相当于加强版父组件prop
inject:就相当于加强版子组件的props
只要在上一层级的声明的provide,那么下一层级无论多深都能够通过inject来访问到provide的数据
提示:
provide
和inject
绑定并不是可响应的。这是刻意为之的。然而,如果你传入了一个可监听的对象,那么其对象的属性还是可响应的。如果需要传可响应的值,请使用
引用类型
的数值,比如{}||[]
等。
- 袓组件
<template>
<div id="app">
<Child />
</div>
</template>
<script>
import Child from 'Child'
export default{
components:{
Child
},
provide(){
return {
msg:"我是祖组件要给孙组件准备的"
}
},
data(){
return {
}
},
methods:{
}
}
</script>
- 儿组件
<template>
<div>
<Child1 />
</div>
</template>
<script>
import Child1 from 'Child1'
export default{
components:{
Child1
},
data(){
return {
}
},
methods:{
}
}
</script>
- 孙组件
<template>
<div>
<p>{{msg}}</p>
</div>
</template>
<script>
export default{
inject:['msg']
data(){
return {
}
},
methods:{
}
}
</script>
二、vue的事件方式
1、子向父传递
//child
this.$emit('add',good)
//parent
<Helloworld @add="add($event)"/>
2、兄弟之间
A组件
<template>
<div>
<span @click="postBrotherMsg">Brother</span>
</div>
</template>
<script>
export default {
name: "BrotherA",
methods: {
postBrotherMsg() {
this.$parent.$emit("foo", "我是兄长,弟弟收好了");
}
}
};
</script>
B组件
<template>
<div>
<span @click="postBrotherMsg">Brother</span>
</div>
</template>
<script>
export default {
name: "BrotherB",
mounted() {
this.$nextTick(() => {});
this.$parent.$on("foo", val => console.log('兄长,弟弟收到了。你的信息是:',val));
}
};
</script>
<style lang="scss" scoped>
</style>
父组件
<template>
<div id="app">
<BrotherA />
<BrotherB />
</div>
</template>
3、袓孙之间(隔辈之间)传递
1.使用$attrs
和$listeners
实现袓孙组件之间数据传递
本质探索
$attrs:包含了父作用域不作为prop被识别(且获取)的特性绑定(class和style除外),就是说,他获取到的除了prop里的可以收到和元素自有属性之外的所有自定义属性
$listeners:包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on=”$listeners” 传入内部组件——在创建更高层次的组件时非常有用。
孙组件
<template>
<div>
<p @click="test2">$attrs:{{$attrs['two']}}</p>
</div>
</template>
<script>
import Child1 from 'Child1'
export default{
inheritAttrs: false,
data(){
return {
}
},
methods:{
test2(){
this.$emit('test2','我是孙子组件')
}
}
}
</script>
儿组件
<template>
<div>
<p @click="test1">$attrs:{{$attrs['one']}}</p>
<Child1 v-bind="$attrs" v-on="$listeners"/>
</div>
</template>
<script>
import Child1 from 'Child1'
export default{
components:{
Child1
},
inheritAttrs: false,
data(){
return {
}
},
methods:{
test1(){
this.$emit('test1','我是儿子组件')
}
}
}
</script>
袓组件
<template>
<div id="app">
<Child :one="child1" :two="child2" @test1="onTest1" @test2="onTest2"/>
</div>
</template>
<script>
import Child from 'Child'
export default{
components:{
Child
},
data(){
return {
one:"我是child1",
two:"我是child2"
}
},
methods:{
onTest1(val){
conosle.log("我是父亲接收到的test1事件回调",val)
},
onTest2(val){
conosle.log("我是父亲接收到的test2事件回调",val)
}
}
}
</script>
总结:可以用于传值和事件从后代组件
2.使用dispatch
函数实现后代向祖先传值
//main.js里
Vue.prototye.dispatch = dispatch;
/**
eventName 派发事件名称
data 派发的数据
**/
function dispatch(eventName,data){
let parent = this.$parent
while(parent){
parent.$emit(eventName,data)
parent = parent.$parent;
}
}
- 后代组件
<template>
<div>
<p @click="dispatch('hello','hello world')">{{msg}}</p>
</div>
</template>
<script>
export default{
data(){
return {
}
},
methods:{
}
}
</script>
- 祖组件
<template>
<div id="app">
<Child />
</div>
</template>
<script>
import Child1 from 'Child1'
export default{
components:{
Child1
},
data(){
return {
}
},
mounted(){
this.$on('hello',(val)=>console.log(val))
},
methods:{
}
}
</script>
3.使用事件总线
- main.js
class Bus{
constructor(){
this.callbacks = {}
}
$on(name,fn){
this.callbacks[name] = this.callbacks[name] || []
this.callbacks[name].push(fn)
}
$emit(name,args){
if(this.callbacks[name]){
this.callbacks[name].forEach(cb=>cb(args))
}
}
}
Vue.prototype.$bus = new Bus()
- A组件
<template>
<div>
<p @click="test1">{{msg}}</p>
</div>
</template>
<script>
export default{
name:"ComA",
data(){
return {
}
},
methods:{
test1(){
this.$bus.$emit('foo')
}
}
}
</script>
- B组件
<template>
<div id="app">
<ComA />
</div>
</template>
<script>
export default{
data(){
return {
}
},
mounted(){
this.$on('msg',(val)=>console.log(val))
},
methods:{
}
}
</script>
最后一种使用Vuex,但vuex比较大,后续会跟上,敬请期待