Vue3 组合式 API:更灵活的组合组件逻辑


点击上方“蓝字”关注咱们react



做者 | 王冠淇
webpack

编辑 | 张婵web


概念数组


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



Vue2 中存在的问题缓存



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



Vue2 中的代码微信


首先先看一下:app


  1. constApp={函数

  2. template:`

  3. <button @click='click'>{{message}}</button>

  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,可是业务逻辑一旦复杂的话,就会出现必定的问题,一旦逻辑复杂你就不能给他写成一大坨,就须要考虑哪些部分须要抽离出来,须要考虑共有逻辑,否则程序维护难度太大。



Vue3 中的代码


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

  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:`<div>x:{{ x }} y:{{ y }} z:{{ time }} </div>`,


  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')



API 介绍


咱们先看看 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

 


setup 使用 composition API 的入口 


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. <div>

  12. <div>count is {{ state.count }} </div>

  13. <div>plusOne is {{ state.plusOne }}</div>

  14. </div>

  15. `


  16. // 咱们再看看用了toRefs

  17. const state = reactive({

  18. count:0,

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

  20. })

  21. return{

  22. ...toRefs(state)

  23. }

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

  25. template:`

  26. <div>

  27. <div>count is {{ count }} </div>

  28. <div>plusOne is {{ plusOne }}</div>

  29. </div>

  30. `



watch 定义监听器


同 Vue2 只是写法略有不一样:

  
  
   
   
   
   
watch(()=> state.count *2, val =>{ console.log(`count * 2 is ${val}`)})



effect 反作用函数


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

  1. effect(()=>{

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

  3. })


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

 


computed 计算属性


同 Vue2:


  1. const state = reactive({

  2. count:0,

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

  4. })




生命周期钩子 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 文档


  


猜你喜欢  

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



以为不错,点个在看

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

相关文章
相关标签/搜索