插件及CompositionAPI中的Setup函数
插件
插件要解决的问题
把通用性的功能封装起来
插件的定义和使用
1. 定义插件
const myPlugin = {
install(app,options){
// app参数是vue的实例
// options是app.use的第二个参数"{msg:'Hell world'}"
}
}
2. 使用插件
app.use(myPlugin,{msg: "Hell world"})
【备注】
写插件也就是写一个对象,这个对象中必须要有install
方法
app.use的第二个参数"{msg:'Hell world'}"
这个方法接收2个参数,app
和options
,app
就是vue最外层的实例,options
是app.use
的第二个参数"{msg:'Hell world'}"
【敲代码】
const myPlugin = {
install(app, options) {
// 扩展全局的变量
app.provide('name', 'LeBron James');
// 扩展指令
app.directive('focus',{
mounted(el){
el.focus()
}
});
// 扩展mixin
app.mixin({
mounted(){
console.log('mixin');
}
});
// vue底层上拓展方法sayHello
app.config.globalProperties.$sayHello = 'hello world';
}
}
const app = Vue.createApp({
template: `
<my-title />
`
})
app.component('my-title', {
inject: ['name'],
mounted(){
console.log(this.$sayHello);
},
template: `
<div>
{{name}}
<input v-focus/>
</div>
`
})
app.use(myPlugin);
const vm = app.mount('#root')
【运行结果】
【备注】
- 由于参数app是app实例对象,因此我们就可以使用实例对象上的方法
provide
提供全局的数据,如果要使用这个数据就要使用inject
- 为什么会打印2个
mixin
?因为混入到vue实例中的钩子函数mounted
会在每个组件挂载到页面上都执行一次,包括根组件和子组件
app.mixin({
mounted(){
console.log('mixin');
}
})
- 主流的vue的拓展,包括
VueRouter、Vuex
都是通过插件plugin去扩展的
实现一个数据校验插件
1. 使用mixin实现
【敲代码】
const app = Vue.createApp({
data(){
return {
name: 'LeBrow James',
age: 28
}
},
// 如果年龄不大于25就执行warn中的警告信息
rules:{
age:{
validate: age => age > 25,
warn: 'too young ,too simple!'
},
name:{
validate: name => name.length >=4,
warn: 'name too short!'
}
},
template: `
<div>
name:{{name}}
age: {{age}}
</div>
`
})
app.mixin({
created(){
for(let key in this.$options.rules){
const item = this.$options.rules[key]
this.$watch(key,(value)=>{
const result = item.validate(value)
if(!result){
alert(item.warn)
}
})
}
}
})
const vm = app.mount('#root')
【过程】
- 在vue实例中定义一个rules,但是只是这样写vue是识别不不出来的,不会执行rules中的校验逻辑
- 定义一个mixin,在mixin中定义一个
created
钩子函数,表示组件初始化完毕后自动执行的函数,在这个钩子函数中可以通过this.this.$options.rules
获取到rule
- 遍历对象
rule
- 使用
this.$watch()
对vue对象的实例或者说根组件的实例上的内容做监控(rule
中的key,比如age),这样每次age发生改变就可以监听到
for(let key in this.$options.rules){
const item = this.$options.rules[key]
this.$watch(key,(value)=>{
const result = item.validate(value)
if(!result){
alert(item.warn)
}
})
}
- 代码中的value是监听的key更新了的新的值
- 监听age的改变,当age发生变化的时候,回调函数会接收到最新的age的值,接下来判断最新的值是否符合校验规则,如果不符合就打印warn中提示信息
2. 将mixin改为pluguin插件的形式
上面把rules
这样的校验规则通过mixin就很好的融入到vue的实例中,但是更加推荐使用插件Plugin的方式
【敲代码】
const app = Vue.createApp({
data() {
return {
name: 'LeBrow James',
age: 28
}
},
// 如果年龄不大于25就执行warn中的警告信息
rules: {
age: {
validate: age => age > 25,
warn: 'too young ,too simple!'
},
name: {
validate: name => name.length >= 4,
warn: 'name too short!'
}
},
template: `
<div>
name:{{name}}
age: {{age}}
</div>
`
})
const validatorPlugin = (app, options) => {
app.mixin({
created() {
for (let key in this.$options.rules) {
const item = this.$options.rules[key]
this.$watch(key, (value) => {
const result = item.validate(value)
if (!result) {
alert(item.warn)
}
})
}
}
})
}
app.use(validatorPlugin)
const vm = app.mount('#root')
Plugin对mixin做了封装,写了validatorPlugin
一眼就能看出写的是一个校验的插件,如果是用下面的mixin
的方式,虽然也能实现同样的功能,但是代码读起来就不能一眼知道在干什么
app.mixin({
created(){
for(let key in this.$options.rules){
const item = this.$options.rules[key]
this.$watch(key,(value)=>{
const result = item.validate(value)
if(!result){
alert(item.warn)
}
})
}
}
})
所以Plugin的方式在可读性和可拓展性比单独的minxin更好
Setup函数
为什么要用Composition
当组件变得越来越复杂的的时候,vue示例中的内容也会越来越长,如vue实例中有data、methods、computed、directives、mixin、template、
,当我们想看template
想看某个变量相关的逻辑的时候,就要不停的往上翻去data、methods、computed、directives、mixin、等
中查找和这个变量相关的逻辑,就是产生混乱和困难的感觉
这样传统的定义data、methods、computed、directives、mixin、template、
的方式,就会显得可维护性有些问题
Vue3引入Composition API后就可以解决上面的问题,让代码更加容易的聚合到一起,具备更好的可维护性
Setup函数用法
Setup函数是在钩子函数created
实例被完全初始化之前执行的函数
【敲代码】
const app = Vue.createApp({
template: `
<div @click="handleClick">
{{name}}
</div>
`,
methods:{
test(){
console.log(this.$options.setup());
}
},
mounted() {
this.test()
},
setup(props, context) {
return {
name: 'LeBrow James',
handleClick() {
alert(123)
}
}
}
})
const vm = app.mount('#root')
【备注】
- setup函数中返回的变量或者函数等,都会暴露在外面,模板中可以直接使用
- setup中没法使用this,因为Setup函数是在实例被完全初始化之前执行的函数,此时还没有vue实例因此也就没有this
- setup函数中没法调vue实例上的methods,但是在外部的methods或者生命周期函数中可以调用setup方法,通过
this.$options.setup()
,如下图打印的this.$options
转载自:https://juejin.cn/post/7244840680384479289