引言
本文为作者记录自身所理解的2.*与3.0差异,主要是帮助作者自身理解3.0,并非严谨的教学,如出现不准确的地方,请勿责怪,相互学习。
开始
首先根据自己阅读文档后,把整体在使用上的差异基于自己对Vue这个框架的理解分为了四个部分,后续本人讲根据顺序进行编写。
- 配置
- API
- 组件/指令
- 组合API
配置
app.config
先看官方介绍
然后我们即可在当前对象下挂载选项
- errorHandler
- warnHandler
- globalProperties
- isCustomElement
- optionMergeStrategies
- performance
其中与2.*版本存在差异的就是
globalProperties
与isCustomElement
globalProperties
根据官方的一个介绍情况,实际上就是来做一些全局属性方法的,可以代2.*原有的两种做法
- 全局 allmixin
// main.js
const allMixin = {
data () {
return {
someConfig: 'xxxx'
}
},
methods: {
someFn () {
console.log('I am someFn')
}
}
}
// 全局混入
Vue.mixin(allMixin)
// xxx.vue
console.log(`all mixin data have someConfig ${vm.someConfig}`)
// 输出'all mixin data have someConfig xxxx'
vm.someFn()
// 'I am someFn'
全局混入想要达到的目的就是在全局加入一些Vue的option配置,status
跟method
其实都是可以通过globalProperties
这个方式来进行替代
- 原型继承 Vue.property.xxxx
// main.js
Vue.prototype.$config = {
someConfig: 'xxxx',
someFn: () => {
console.log('I am someFn')
}
}
// xxx.vue
console.log(`all mixin data have someConfig ${vm.$config.someConfig}`)
// 输出'all mixin data have someConfig xxxx'
vm.$config.someFn()
// 'I am someFn'
这种相当于利用了JS原型继承的方式,让构造实例通过原型查找,找到对应的属性方法,相对来说跟我们今天要说的globalProperties
也是比较类似的,我们来看下globalProperties
的官方使用案例
app.config.globalProperties.foo = 'bar'
app.component('child-component', {
mounted() {
console.log(this.foo) // 'bar'
}
})
实际上会发现跟我们的第二种方式相当的接近,但是作者简单看了一下实现的做法上还是不太一样的,扫了一下源码应该是通过在this
或者我们的vm
上通过proxy
的get拦截进行的处理,直接进行的取值判断~,另一点globalProperties
的命名实际上也进行了一个语义传达,更加方便其他开发者阅读代码。
isCustomElement
首先我们先关注一下官方的介绍
从介绍看来,是提供了接口用来,传递一个过滤方法,方便Vue排查组件之外的自定义组件,作者会想起之前的某一应用场景,简单跟大家分享一下,我司存在微信引流的业务需求,需要从微信引流到具体APP,这里会涉及到微信开放平台中的能力微信内网页跳转APP功能,在进行开发的过程中机会发现无法直接在单文件组件中使用wx-open-launch-app
那么相当于在新能力下可以通过一下代码避免这个问题
app.config.isCustomElement = tag => tag.startsWith('wx-')
isCustomElement
相当于提供了第三方自定义组件的拓展,使得DOM整体结构更语义化~
emits
这个算是一个比较大的变动,原有在2.*中,子组件事件都是通过vm.$emit(...)
方式进行向上传递,但是事件命名本身是没有进行约定的,也没有对应的返回校验。如果是在这样的背景下针对event
所返回的参数实际上是需要校验的,毕竟在这个场景下,我们没有办法确保说给到的参数一定是我们预期的内容(当然你可以使用TS去做相关静态类型检查),但毕竟不是一个完善的方案。而3.0中所提供的emits
实际上来说就是变相的增加了我们整体组件的可靠性~,当然这个也是要基于大家遵守规范并使用起来的情况。
下面我们就来看一下emits
官方的具体使用案例
const app = Vue.createApp({})
// 数组语法
app.component('todo-item', {
emits: ['check'],
created() {
this.$emit('check')
}
})
// 对象语法
app.component('reply-form', {
emits: {
// 没有验证函数
click: null,
// 带有验证函数
submit: payload => {
if (payload.email && payload.password) {
return true
} else {
console.warn(`Invalid submit event payload!`)
return false
}
}
}
})
renderTracked
新声明周期,主要是在渲染阶段中数据被track一个情况,如下案例
vue.template
<template>
<div class="home">
{{test}}
{{test1}}
</div>
</template>
vm.option
export default defineComponent({
data () {
return {
test: '1',
test1: '2'
}
},
renderTracked (event) {
console.log(event)
}
})
那么我们在控制台可以得到以下输出内容
可以通过以上内容,在渲染阶段知道具体哪一个属性被具体track,就可以排查对应的比如不应该被track的元素被track 或者 应该被track的元素没有被track
renderTriggered
同理以上内容,当前生命周期也是表达了在渲染期间被triggered的属性
API
defineComponent
从命名上看,主要是用来定义某一个组件的,但实际上底层只是直接返回了对象内容或者是当成setup
声明周期进行构造
// packages/runtime-core/src/apiDefineComponent.ts
export function defineComponent(options: unknown) {
return isFunction(options) ? { setup: options, name: options.name } : options
}
作用上Vue官方实际上也做了响应说明
defineAsyncComponent
定义一个异步组件,实际上这里我们在接触Vue-router的懒加载的时候也有过类似体验,只不过Vue的这个api可以协助我们以更小的细粒度去定义相关组件,具体内容不做赘述,点击这里跳转官方文档
defineAsyncComponent, resolveDynamicComponent, resolveDirective
可以通过名称对相对应的内容进行一定的解析,但是目前来说用途不是特别明确,感兴趣的小伙伴可以自己翻阅官方文档,资深大佬欢迎留言教育
createRenderer
自定义render构造器,实际上个人人为这个就是为跨端留的口子。毕竟现有的宿主环境已经是比较多变啦,比如可以做weex这一类跨段的支持啊等,当然这个就是个人拙见,不同看法欢迎讨论
组件/指令
teleport
要理解<teleport>
,可以先简单的联想一下slot
的用法, <slot>
是一种从组件外部注入模版的方式如下
<!-- 子组件模版 children -->
<template>
<div class="children-wrap">
<slot />
</div>
</template>
<!-- 父组件模版 -->
<template>
<children>
<div>我来自父组件</div>
</children>
</template>
<!-- 最后渲染 -->
<div class="children-wrap">
<div>我来自父组件</div>
</div>
那么实际上就是<teleport>
就是反过来,从内部像外部透出~,但是经过本人测试,其实是没有像是类似slot
的效果的,主要是没有办法移动到父组件所定义的模版内,只能迁移到HTML文档内的class/id/tag中。当然也有一定的意义,比如官方提到说
当然除了模态框,也有其他的一些场景,比如布局上的一些操作,头部,底部,抽屉组件等。
v-is
这个指令官方的api已经说的比较清晰啦~,这里只做提及不做说明,点击这里查看
组合API
这个基本为3.0最大的转变,最好是专门的出一期进行使用记录~~
本期就先这样啦,大家再见~ 有问题欢迎留言讨论,按照本文进行技术学习的同学,概不负责!