父子组件通信
prop
event
style和class
natvie修饰符
$listeners
v-model
sync修饰符
$parent和$children
$slots和$scopedSlots
ref
跨组件通信
Provide和Inject
router
vuex
store模式
eventbus
父子组件通信
prop
最常见的组件通信方式,由父组件向子组件传递。prop可接收一个数组或对象
//子组件
<script>
export default {
name: "Comp",
//数组方式 props:[....]
// ↓ 对象方式
props: {
datas: {
type: Object,
default: () => {
return {};
}
},
}
</script>
event
子组件向父组件发送通知,并传递参数
子组件
methods:{
// 通过 $emit向父组件发送一个通知
handleEvent(){
this.$emit('eventMsg', option)
}
}
父组件
methods:{
// 监听子组件定义的方法
eventMsg(option){
console.log(option);
}
}
style 和 class
父组件可以向子组件传递style 和 class ,style 和 class将合并到子组件根元素上
父组件
<template>
<div id="app">
<HelloWorld
style="color:red"
class="hello"
msg="Welcome to Your Vue.js App"
/>
</div>
</template>
<script>
import HelloWorld from "./components/HelloWorld.vue";
export default {
components: {
HelloWorld,
},
};
</script>
子组件
<template>
<div class="world" style="text-align:center">
<h1>{{msg}}</h1>
</div>
</template>
<script>
export default {
name: "HelloWorld",
props: {
msg: String,
},
};
</script>
最终渲染结果
<div id="app">
<div class="hello world" style="color:red; text-aling:center">
<h1>Welcome to Your Vue.js App</h1>
</div>
</div>
attribute
父组件在使用子组件时,在子组件上定义一些属性,这些属性将作用于子组件的根元素上,但是不包括style和class
父组件
<HelloWorld data-a="1" data-b="2" msg="Welcome to Your Vue.js App" />
子组件
<template>
<div>
<h1>{{msg}}</h1>
</div>
</template>
<script>
export default {
name: "HelloWorld",
props: {
msg: String,
},
created() {
// 通过$attrs获取父组件定义的 attribute
console.log(this.$attrs); // {"data-a":"1","data-b":"2"}
},
};
</script>
最终渲染结果
<div id="app">
<div data-a="1" data-b="2">
<h1>Welcome to Your Vue.js App</h1>
</div>
</div>
Tip:子组件可以通过定义 inheritAttrs:false 来紧张 attribute 附着在子组件根元素上 但不影响通过 $attrs 获取数据
natvie修饰符
在注册事件时,父组件可以通过 navite 修饰符,将事件注册到子组件根元素上
父组件
<template>
<div id="app">
<HelloWorld @click.native="handleClick" />
</div>
</template>
<script>
import HelloWorld from "./components/HelloWorld.vue";
export default {
components: {
HelloWorld,
},
methods: {
handleClick() {
console.log(1);
},
},
};
</script>
子组件
<template>
<div>
<h1>Hello World</h1>
</div>
</template>
最终渲染结果
<template>
<div id="app">
<h1>Hello World</h1>
</div>
</template>
// 当点击app时。会触发父组件定义的 handleClick 方法
$listeners
子组件可以通过 $listeners 获取父组件传递过来的所有处理函数
v-model
父组件在使用子组件时,可以在子组件上绑定v-model,子组件通过定义model的prop和event还获取父组件定义的值
父组件
`
<Compn v-model="datas" />
`
子组件
<script>
export default {
//分类筛选组件
name: "sortFilter",
//定义实现v-modal的属性与事件
model: {
prop: "value",
event: "change"
},
props: {
//绑定的值
value: {
type: [String, Number],
default: ""
}
},
created() {
console.log(this.value)
},
</script>
sync 修饰符
和 v-model类似,用于双向数据绑定,不同点在于 v-model只能针对一个数据进行绑定,而 sync 修饰符没有限制
子组件
<template>
<div>
<p>
<button @click="$emit(`update:num1`, num1 - 1)">-</button>
{{ num1 }}
<button @click="$emit(`update:num1`, num1 + 1)">+</button>
</p>
<p>
<button @click="$emit(`update:num2`, num2 - 1)">-</button>
{{ num2 }}
<button @click="$emit(`update:num2`, num2 + 1)">+</button>
</p>
</div>
</template>
<script>
export default {
props: ["num1", "num2"],
};
</script>
父组件
<template>
<div id="app">
<Numbers :num1.sync="n1" :num2.sync="n2" />
<!-- 等同于 -->
<Numbers
:num1="n1"
@update:num1="n1 = $event"
:num2="n2"
@update:num2="n2 = $event"
/>
</div>
</template>
<script>
import Numbers from "./components/Numbers.vue";
export default {
components: {
Numbers,
},
data() {
return {
n1: 0,
n2: 0,
};
},
};
</script>
$parent 和 $children
在组件内部,可以通过$parent 和$children属性,分别获取当前组件的父组件和子组件实例
<template>
<div class="hello">
<button @click="handelParent">获取父组件实例</button>
<button @click="handelChild">获取子组件实例</button>
<Child />
</div>
</template>
<script>
import Child from "./Children.vue";
export default {
name: "HelloWorld",
props: {
msg: String,
},
components: {
Child,
},
methods: {
handelParent() {
console.log("父组件实例:", this.$parent);
},
handelChild() {
console.log("子组件实例", this.$children);
},
},
};
</script>
ref
在使用组件时,可以通过在组件上定义ref来获取组件实例
<template>
<div class="hello">
<button @click="handelChild">获取子组件实例</button>
<Child ref="child" />
</div>
</template>
<script>
import Child from "./Children.vue";
export default {
name: "HelloWorld",
props: {
msg: String,
},
components: {
Child,
},
methods: {
handelChild() {
console.log("子组件实例", this.$refs.child);
},
},
};
</script>
跨组件通信
provide 和 Inject
provide和inject 可以实现深层组件通信,顶层组件只需定义provide,底层组件通过inject接受数据
顶层组件
// 父组件
provide(){
msg:'hello Children'
},
// 子组件
inject: ['msg']
created () {
console.log(this.msg) // hello Children
}
router
如果一个组将改变了地址栏,所有监听地址栏的组将都会做出相应的改变,
//监听路由变化
watch:{
$route(to,from) {
console.log(to,from);
}
}
vuex
vuex 过于笨重,通常不建议在小型项目中使用,小型项目可以使用store 或 eventbus代替vuex,vuex本质上就是一个数据仓库。在此不做过多赘述,先挖一个坑,下回再叙。
store 模式
store模式其实就是一个普通的js模块,各组件可以导入该模块,将数据放到data里面,此时store就具有响应式了。
// 导出一个 store.js模块
export default {
userInfo:{...},
loginInfo:{...}
}
// A子组件导入 store模块
import store from './store.js'
export default {
name:'Acompon',
data(){
userInfo: store.userInfo
}
}
// B子组件导入 store模块
import store from './store.js'
export default {
name:'Bcompon',
data(){
loginInfo: store.loginInfo
}
}
tip: store模式的缺点是无法跟踪数据的改变,因为所有组件都可以更改数据
eventbus
eventbus事件总线相当于一个桥梁,作为所有组将的一个事件中心,所有组件皆可往eventbus里面注册事件,也可以监听事件。
// 定义一个eventbus模块
import Vue from 'vue'
export const EventBus = new Vue()
// 在main.js里导入该模块并挂载到全局
// main.js
import eventbus from './eventbus.js'
Vue.prototype.$eventBus = eventbus
所有子组件向eventbus里组 注册 或者 监听 事件
// 组件A 通过 $emit()注册事件
sendMsg() {
this.$eventBus.$emit("aMsg", 'from A');
}
// 组件B 通过 $on 监听事件
this.$eventBus.$on("aMsg", (msg) => {
// A发送来的消息
console.log(msg) // from A
})
// 通过 $off() 可以关闭事件
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。