非父子组件的通信
数据共享用的最多的还是Vuex
这里主要介绍两种方式:
Provide/Inject
Mitt全局事件总线
Provide/Inject
Provide父组件提供,Inject子孙组件使用
推荐:provide默认写成函数
App下有Home,Home下有HomeContent。App给HomeContent传数据
App.vue
export default {
components: {
Home
},
// 1.如果引用data相关的数据,把provide里的改成函数
provide() {
return {
name: "why",
age: 18,
//2.provide的数据变成响应式,用到computedAPI
length: computed(() => this.names.length) // ref对象 .value
//computed返回ref对象,取值用value
}
},
data() {
return {
names: ["abc", "cba", "nba"]
}
}
}
HomeContent.vue
<div>
<!--computed返回ref对象,取值用value-->
HomeContent: {{name}} - {{age}} - {{length.value}}
</div>
全局事件总线mitt库
1.安装
npm install mitt
2.可以封装一个工具eventbus.js
import mitt from 'mitt';
const emitter = mitt();
export default emitter;
App Home 和About
Home下有HomeContent,点击About在HomeContent下进行监听
//取消emitter中所有的监听
emitter.all.clear()
//定义一个函数
function onFoo() { }
emitter.off('foo', onFoo) //销毁foo事件,传OnFoo引用
emitter.on('foo', onFoo)//监听foo事件
插槽
可以决定某一块区域到底放什么内容和元素
抽取共性、预留不同
将共同的元素、内容依然在组件内进行封装
将不同的元素使用slot作为占位符,让外部决定到底显示什么样的元素
<slot>
为封装组件开启一个插槽。该插槽插入什么内容取决于父组件如何使用。
插槽基本使用
有个组件MySlotCpn.vue:组件中插槽<slot>
放入需要显示的内容
App.vue中使用它们:可以插入普通内容、html元素、组件元素
插槽的默认内容
<slot>
<h2>插槽默认显示内容</h2>
</slot>
具名插槽的使用
具名插槽:给插槽起名
一个不带name的slot,会带有隐含的名字default
动态插槽名
我们之前使用的插槽名是固定的,比如v-slot:left、v-slot:center等
v-slot:[动态插槽名]
方式绑定一个动态名称
具名插槽使用缩写
v-slot: 缩写为 #
渲染作用域
父级模板里的所有内容都是在父级作用域中编译的
子模板里的所有内容都是在子作用域中编译的
ChildCpn.vue可以访问自己作用域中title内容,但在App.vue中访问不了ChildCpn.vue中的内容,因为它们是跨作用域的访问
作用域插槽
第三方库、自己封装组件,用到很多