Vue组件
基本使用
通过 Vue.extend
来创建组件构造器对象
const cpnC = Vue.extend({
template:`<div>
<h2>hhhhh</h2>
<p>xxxxxx</p>
</div> `
});
全局注册组件
Vue.component('my-cpn',cpnC);
局部注册组件,在对应的vue实例中去注册即可
const app = new Vue({
el: '#app',
data: {
message: 'helloWorld!'
},
components:{
cpn:cpnC
}
});
全局注册语法糖
Vue.component('cpn',{
template:`
<div>
<h2>我是哈哈ha</h2>
<p>我是内容</p>
</div>
`
});
局部注册语法糖
const app = new Vue({
el: '#app',
data: {
message: 'helloWorld!'
},
components:{
'cpn2':{
template:`
<div>
<h2>我是哈哈ha</h2>
<p>我是内容hhhh</p>
</div>
`
}
}
});
组件通信
1. 父传子
通过props
方式
2. 子传父
通过$emit
方式
组件访问
1. 父访问子
$children
父组件调用$children
会获取一个包含所有子组件的数组,可以通过该方式获取子组件的一些方法与属性
$refs
对象类型,默认是一个空对象。当有组件标签上加上了ref="xxx"
,这时这个对象才会返回这个组件的一些属性,可以用来操作一些DOM行为
2. 子访问父
通过$parent
方式
provide/inject
如果我们需要跨层级传递,上述介绍的方式使用起来就会很繁琐而且维护性不高
如上图,我们需要通过A组件为最底层各个组件传递属性或者方法就可以采用 provide/inject
方式
A组件:
provide() {
return {
theme: {
//这里设置的color不是响应式的,
color: this.color
}
};
},
//下面就能实现响应式(提供了响应式的数据)
provide() {
return {
theme: this
};
},
如果实在不想把整个实例查传过去,可以使用Vue.observable
它能将对象变成响应式
provide() {
//另类实现响应式
this.theme = Vue.observable({
color: "blue"
});
return {
theme: this.theme
};
},
vue3推出的新api computed也可以实现响应式
//需要从vue中引入一个函数
import { computed } from "vue"
provide() {
return {
theme:computed(() => this.color)
}
}
后代组件通过inject
获取 theme
对象
inject: {
theme: {
default: () => ({})
}
},
函数式组件(没有上下文对象)获取inject
方式
<template functional>
<div class="border2">
<!-- 函数式组件取得inject的方式,因为没有上下文 -->
<h3 :style="{ color: injections.theme.color }">I 结点</h3>
</div>
</template>
<script>
export default {
inject: {
theme: {
default: () => ({})
}
}
};
</script>
通过computed处理过的数据在子组件中的访问方式与其他的不同,因为computed返回的是一个ref对象,需要通过 .value
方式去取数据
注意,inject
的方式是类似与冒泡的方式去查找父级的provide
以最近的为准
事件总线
vue3移除掉了$on
$off
$once
等方法,这里使用一个第三方库 mitt
来实现
下载
npm install mitt -S
使用方式:
创建一个文件夹 eventBus.js
//导入
import mitt from 'mitt'
//创建一个emitter对象
const emitter = mitt();
export default emitter;
例如 A B组件互为兄弟组件,A想向B组件发送一些数据
A组件
import emitter from "@/eventBus.js"
//发出一个自定义事件
emitter.emit('zhang', {name:'san', age:'18'});
B组件
import emitter from "@/eventBus.js"
//监听事件
emitter.on('zhang', (info) => {
console.log(info)
})
//监听所有事件,这里参数有两个,一个是事件类型,一个是数据
emitter.on('*', (type, info) => {
console.log(info)
})
事件的取消
//取消所有事件监听
emitter.all.clear();
//取消特定的事件
//我们这里监听事件就要传入一个函数的引用了
function fn() {}
emitter.on('zhang', fn);//监听
emitter.off('zhang', fn);//取消
动态组件
有时候我们需要在一个页面切换不同的组件,我们可以使用 v-if来条件渲染,也可以使用路由来进行切换,当然还可以使用 动态路由来实现
动态路由使用vue内置组件component
通过一个属性 is
来实现
<component
:is="currentTab"
@pageClick="pageClick"
name="zhangsan"
:age="20"
></component>
is
填写组件的内容可以为component函数注册的组件,也可以是在一个组件对象的components对象中注册的组件。
对于组件间传值和自定义事件也是和普通组件一样没有变化
另外,如果我们在切换组件的时候想要将组件的状态缓存,可以使用内置组件 keep-alive
<keep-alive>
<component
:is="currentTab"
@pageClick="pageClick"
name="zhangsan"
:age="20"
></component>
</keep-alive>
包裹在外层即可
keep-alive
属性
- include - string | RegExp | Array 只有匹配的组件才会被缓存
- exclude - string | RegExp | Array 任何名称匹配的组件都不会被缓存
- max - number | string 最多可以缓存多少组件实例,一旦达到这个数字,那么缓存组件中最近没有被访问的实例会被销毁
include
和 exclude
都可以使用逗号分隔字符串,匹配首先检查组件自身的name
属性