
点击上方“蓝字”关注咱们react
做者 | 王冠淇
webpack
编辑 | 张婵web

概念数组

组合式 API(Composition API),其本质是为了更方便实现逻辑的组合而产生的。浏览器

Vue2 中存在的问题缓存

Vue2 中若是想给全部组件都添加公共逻辑,好比果添加防抖,主要的实现方式是利用 Mixins来注入,可是这种实现有一个弊端,光看模板很难分清一个属性是从哪来的,并且一旦这种注入的逻辑增多,不管是对代码阅读,仍是维护来讲,都有较大的困难。服务器

Vue2 中的代码微信

首先先看一下:app
constApp={
函数template:`
<button @click='click'>{{message}}</button>
`,
data(){
return{
message:'Hello Vue 3!!'
}
},
methods:{
click(){
console.log('click ....',this.message)
this.message =this.message.split('').reverse().join('')
}
}
}
let vm =newVue({
render: h => h(App)
}).$mount('#app')
经典的 Vue API 能够概括成 options API,是基于配置的方式声明逻辑的 API,可是业务逻辑一旦复杂的话,就会出现必定的问题,一旦逻辑复杂你就不能给他写成一大坨,就须要考虑哪些部分须要抽离出来,须要考虑共有逻辑,否则程序维护难度太大。

Vue3 中的代码

第一段逻辑是尤大的逻辑鼠标位置监听逻辑:
function useMouse(){
const state = reactive({
x:0,
y:0
})
const update = e =>{
state.x = e.pageX
state.y = e.pageY
}
onMounted(()=>{
window.addEventListener('mousemove', update)
})
onUnmounted(()=>{
window.removeEventListener('mousemove', update)
})
return toRefs(state)
}
咱们还想组合另一段逻辑,好比随时刷新的时间逻辑:
function useOtherLogic(){
const state = reactive({
time:''
})
onMounted(()=>{
setInterval(()=>{
state.time =newDate()
},1000)
})
return toRefs(state)
}
在实际的工做中咱们能够认为这两个逻辑可能被不少组件复用,若是你使用 Mixin 将会十分麻烦,可是若是利用组合式 API,只需引入这两段逻辑便可。
constMyComponent={
template:`<div>x:{{ x }} y:{{ y }} z:{{ time }} </div>`,
setup(){
const{
x,
y
}= useMouse()
// 与其它函数配合使用
const{
time
}= useOtherLogic()
return{
x,
y,
time
}
}
}
createApp().mount(MyComponent,'#app')

API 介绍

咱们先看看 Vue3 的基础 API 都有哪些?
const{
createApp,
reactive,// 建立响应式数据对象
ref,// 建立一个响应式的数据对象
toRefs,// 将响应式数据对象转换为单一响应式对象
isRef,// 判断某值是不是引用类型
computed,// 建立计算属性
watch,// 建立watch监听
// 生命周期钩子
onMounted,
onUpdated,
onUnmounted,
}=Vue

setup 使用 composition API 的入口

setup 函数会在 beforeCreate 以后 created 以前执行
setup(props,context){
console.log('setup....',)
console.log('props',props)// 组件参数
console.log('context',context)// 上下文对象
}
reactive
reactive() 函数接受一个普通对象 返回一个响应式数据对象
const state = reactive({
count:0,
plusOne: computed(()=> state.count +1)
})
ref 与 isRef
ref 将给定的值(确切的说是基本数据类型 ini 或 string)建立一个响应式的数据对象
isRef 其实就是判断一下是否是ref生成的响应式数据对象
toRefs
toRefs 能够将 reactive 建立出的对象展开为基础类型
// 若是不用toRefs
const state = reactive({
count:0,
plusOne: computed(()=> state.count +1)
})
return{
state
}
// 模板渲染要这样写
template:`
<div>
<div>count is {{ state.count }} </div>
<div>plusOne is {{ state.plusOne }}</div>
</div>
`
// 咱们再看看用了toRefs
const state = reactive({
count:0,
plusOne: computed(()=> state.count +1)
})
return{
...toRefs(state)
}
// 模板渲染要这样写
template:`
<div>
<div>count is {{ count }} </div>
<div>plusOne is {{ plusOne }}</div>
</div>
`

watch 定义监听器

同 Vue2 只是写法略有不一样:
watch(()=> state.count *2, val =>{ console.log(`count * 2 is ${val}`)})

effect 反作用函数

响应式对象修改会触发这个函数:
effect(()=>{
console.log('数值变化了..',state.count)
})
effect 是响应式的副产物,在 get 的时候收集 effect,并在 set 时候触发,和 Vue2 中 dep.notify() 相似。

computed 计算属性

同 Vue2:
const state = reactive({
count:0,
plusOne: computed(()=> state.count +1)
})

生命周期钩子 Hooks

Vue2 |
Vue3 |
beforeCreate |
setup(替代) |
created |
setup(替代) |
beforeMount |
onBeforeMount |
mounted |
onMounted |
beforeUpdate |
onBeforeUpdate |
updated |
onUpdated |
beforeDestroy |
onBeforeUnmount |
destroyed |
onUnmounted |
errorCaptured |
onErrorCaptured |

Vue3 中的数据绑定

最后,再来分别看一下 Vue2 和 Vue3 中针对数据双向绑定绑定分别作的处理。
Vue2 中数据绑定是基于 Object.definedProperty 实现的,这会产生一些问题,其中最主要的就是性能问题,在 data 中数据嵌套层数过多的时候尤其明显。并且这个方法没法监听数组变化,因此 Vue2 中不得不对数组的变态方法进行了重写。
而在 Vue3 中,数据的双向绑定使用了 ES6 中的 Proxy,同时利用 WeakMap 进行缓存,在性能上面有了较大的提高。
使用 Object.defineProperty 没法监听到新增属性,可是使用 Proxy 是能够监听到的。对比上面两段代码能够发现有如下几点不一样:
Object.defineProperty监听的是对象的每个属性,而 Proxy 监听的是对象自身;
使用 Object.defineProperty 须要遍历对象的每个属性,对于性能会有必定的影响;
Proxy 对新增的属性也能监听到,但 Object.defineProperty 没法监听到。

其余

另外随着 Vue3 rc 的推出,尤大在直播中提到了 vite。参考 snowpack 专门为 Vue3 开发的打包工具,其描述是:针对 Vue 单页面组件的没法打包开发服务器,能够直接在浏览器运行请求 Vue 文件。
可是和 webpack 比目前功能上还略有不足。并不能彻底替代 webpack。
点击【阅读原文】查看 Vue3 API 文档



猜你喜欢
本文分享自微信公众号 - 金科优源汇(jkyyh2020)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。