api hook监听文件变化_Vue3 组合式 API:更灵活的组合组件逻辑

428b22d0289b99ced6683f464db7de2d.png

点击上方“蓝字”关注我们

作者 | 王冠淇

编辑 | 张婵

4b2f5e02a6aa079d57f3881272b10468.png

概念

f9d833f7240611f61b1bad5287e6f118.png

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

4b2f5e02a6aa079d57f3881272b10468.png

Vue2 中存在的问题

f9d833f7240611f61b1bad5287e6f118.png

Vue2 中如果想给所有组件都添加公共逻辑,比如果添加防抖,主要的实现方式是利用 Mixins来注入,但是这种实现有一个弊端,光看模板很难分清一个属性是从哪来的,而且一旦这种注入的逻辑增多,无论是对代码阅读,还是维护来说,都有较大的困难。

4b2f5e02a6aa079d57f3881272b10468.png

Vue2 中的代码

f9d833f7240611f61b1bad5287e6f118.png

首先先看一下:

  1. constApp={

  2. template:`

  3. {{message}}

  4. `,

  5. data(){

  6. return{

  7. message:'Hello Vue 3!!'

  8. }

  9. },

  10. methods:{

  11. click(){

  12. console.log('click ....',this.message)

  13. this.message =this.message.split('').reverse().join('')

  14. }

  15. }

  16. }

  17. let vm =newVue({

  18. render: h => h(App)

  19. }).$mount('#app')

经典的 Vue API 可以归纳成 options API,是基于配置的方式声明逻辑的 API,但是业务逻辑一旦复杂的话,就会出现一定的问题,一旦逻辑复杂你就不能给他写成一大坨,就需要考虑哪些部分需要抽离出来,需要考虑共有逻辑,不然程序维护难度太大。

4b2f5e02a6aa079d57f3881272b10468.png

Vue3 中的代码

f9d833f7240611f61b1bad5287e6f118.png

第一段逻辑是尤大的逻辑鼠标位置监听逻辑:

  1. function useMouse(){

  2. const state = reactive({

  3. x:0,

  4. y:0

  5. })

  6. const update = e =>{

  7. state.x = e.pageX

  8. state.y = e.pageY

  9. }

  10. onMounted(()=>{

  11. window.addEventListener('mousemove', update)

  12. })

  13. onUnmounted(()=>{

  14. window.removeEventListener('mousemove', update)

  15. })

  16. return toRefs(state)

  17. }

我们还想组合另外一段逻辑,比如随时刷新的时间逻辑:

  1. function useOtherLogic(){

  2. const state = reactive({

  3. time:''

  4. })

  5. onMounted(()=>{

  6. setInterval(()=>{

  7. state.time =newDate()

  8. },1000)

  9. })

  10. return toRefs(state)

  11. }

在实际的工作中我们可以认为这两个逻辑可能被很多组件复用,如果你使用 Mixin 将会十分麻烦,但是如果利用组合式 API,只需引入这两段逻辑即可。

  1. constMyComponent={

  2. template:`

    x:{{ x }} y:{{ y }} z:{{ time }}
    `,
  3. setup(){

  4. const{

  5. x,

  6. y

  7. }= useMouse()

  8. // 与其它函数配合使用

  9. const{

  10. time

  11. }= useOtherLogic()

  12. return{

  13. x,

  14. y,

  15. time

  16. }

  17. }

  18. }

  19. createApp().mount(MyComponent,'#app')

4b2f5e02a6aa079d57f3881272b10468.png

API 介绍

f9d833f7240611f61b1bad5287e6f118.png

我们先看看 Vue3 的基础 API 都有哪些?

  1. const{

  2. createApp,

  3. reactive,// 创建响应式数据对象

  4. ref,// 创建一个响应式的数据对象

  5. toRefs,// 将响应式数据对象转换为单一响应式对象

  6. isRef,// 判断某值是否是引用类型

  7. computed,// 创建计算属性

  8. watch,// 创建watch监听

  9. // 生命周期钩子

  10. onMounted,

  11. onUpdated,

  12. onUnmounted,

  13. }=Vue

4b2f5e02a6aa079d57f3881272b10468.png

setup 使用 composition API 的入口 

f9d833f7240611f61b1bad5287e6f118.png

setup 函数会在 beforeCreate 之后 created 之前执行

  1. setup(props,context){

  2. console.log('setup....',)

  3. console.log('props',props)// 组件参数

  4. console.log('context',context)// 上下文对象

  5. }

reactive

reactive() 函数接受一个普通对象 返回一个响应式数据对象

  1. const state = reactive({

  2. count:0,

  3. plusOne: computed(()=> state.count +1)

  4. })

ref 与 isRef

  • ref 将给定的值(确切的说是基本数据类型 ini 或 string)创建一个响应式的数据对象

  • isRef 其实就是判断一下是不是ref生成的响应式数据对象

toRefs

 toRefs 可以将 reactive 创建出的对象展开为基础类型

  1. // 如果不用toRefs

  2. const state = reactive({

  3. count:0,

  4. plusOne: computed(()=> state.count +1)

  5. })

  6. return{

  7. state

  8. }

  9. // 模板渲染要这样写

  10. template:`

  11. count is {{ state.count }}

plusOne is {{ state.plusOne }}

`

// 我们再看看用了toRefs

const state = reactive({

count:0,

plusOne: computed(()=> state.count +1)

})

return{

...toRefs(state)

}

// 模板渲染要这样写

template:`

count is {{ count }}

plusOne is {{ plusOne }}

`

4b2f5e02a6aa079d57f3881272b10468.png

watch 定义监听器

f9d833f7240611f61b1bad5287e6f118.png

同 Vue2 只是写法略有不同:

watch(()=> state.count *2, val =>{

console.log(`count * 2 is ${val}`)

})

4b2f5e02a6aa079d57f3881272b10468.png

effect 副作用函数

f9d833f7240611f61b1bad5287e6f118.png

响应式对象修改会触发这个函数:

  1. effect(()=>{

  2. console.log('数值变化了..',state.count)

  3. })

effect 是响应式的副产物,在 get 的时候收集 effect,并在 set 时候触发,和 Vue2 中 dep.notify() 类似。

4b2f5e02a6aa079d57f3881272b10468.png

computed 计算属性

f9d833f7240611f61b1bad5287e6f118.png

同 Vue2:

  1. const state = reactive({

  2. count:0,

  3. plusOne: computed(()=> state.count +1)

  4. })

4b2f5e02a6aa079d57f3881272b10468.png

生命周期钩子 Hooks

f9d833f7240611f61b1bad5287e6f118.png

Vue2

Vue3

beforeCreate

setup(替代)

created

setup(替代)

beforeMount

onBeforeMount

mounted

onMounted

beforeUpdate

onBeforeUpdate

updated

onUpdated

beforeDestroy

onBeforeUnmount

destroyed

onUnmounted

errorCaptured

onErrorCaptured

4b2f5e02a6aa079d57f3881272b10468.png

Vue3 中的数据绑定

f9d833f7240611f61b1bad5287e6f118.png

最后,再来分别看一下 Vue2 和 Vue3 中针对数据双向绑定绑定分别做的处理。

Vue2 中数据绑定是基于 Object.definedProperty 实现的,这会产生一些问题,其中最主要的就是性能问题,在 data 中数据嵌套层数过多的时候尤为明显。而且这个方法无法监听数组变化,所以 Vue2 中不得不对数组的变态方法进行了重写。

而在 Vue3 中,数据的双向绑定使用了 ES6 中的 Proxy,同时利用 WeakMap 进行缓存,在性能上面有了较大的提升。

使用 Object.defineProperty 无法监听到新增属性,但是使用 Proxy 是可以监听到的。对比上面两段代码可以发现有以下几点不同:

  • Object.defineProperty监听的是对象的每一个属性,而 Proxy 监听的是对象自身;

  • 使用 Object.defineProperty 需要遍历对象的每一个属性,对于性能会有一定的影响;

  • Proxy 对新增的属性也能监听到,但 Object.defineProperty 无法监听到。

4b2f5e02a6aa079d57f3881272b10468.png

其他

f9d833f7240611f61b1bad5287e6f118.png

另外随着 Vue3 rc 的推出,尤大在直播中提到了 vite。参考 snowpack 专门为 Vue3 开发的打包工具,其描述是:针对 Vue 单页面组件的无法打包开发服务器,可以直接在浏览器运行请求 Vue 文件。

但是和 webpack 比目前功能上还略有不足。并不能完全替代 webpack。

点击【】查看 Vue3 API 文档

 73151b52c543a65767f0bcb976366ace.gif 6e22de0f8d9439adb5391de8ea519618.gif 2d3492a5e47503017fa2923613eb73fa.gif

猜你喜欢  

通过双叉十字模型判断股票买入点位 | 金融科技之量化策略研究课题报告(上)基于时间序列 ARIMA 模型预测股票收盘价 | 金融科技之量化策略研究课题报告(下)建信金科大咖访谈:数字时代,如何稳步迈上智慧经营之路?一个输入框你要做一周?

8f7fd94d0be5780ed5100b64957fc0ad.png

觉得不错,点个在看
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值