![](http://static.javashuo.com/static/loading.gif)
點擊上方「藍字」關注咱們react
做者 | 王冠淇
webpack
編輯 | 張嬋web
![](http://static.javashuo.com/static/loading.gif)
概念數組
![](http://static.javashuo.com/static/loading.gif)
組合式 API(Composition API),其本質是爲了更方便實現邏輯的組合而產生的。瀏覽器
![](http://static.javashuo.com/static/loading.gif)
Vue2 中存在的問題緩存
![](http://static.javashuo.com/static/loading.gif)
Vue2 中若是想給全部組件都添加公共邏輯,好比果添加防抖,主要的實現方式是利用 Mixins來注入,可是這種實現有一個弊端,光看模板很難分清一個屬性是從哪來的,並且一旦這種注入的邏輯增多,不管是對代碼閱讀,仍是維護來講,都有較大的困難。服務器
![](http://static.javashuo.com/static/loading.gif)
Vue2 中的代碼微信
![](http://static.javashuo.com/static/loading.gif)
首先先看一下: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,可是業務邏輯一旦複雜的話,就會出現必定的問題,一旦邏輯複雜你就不能給他寫成一大坨,就須要考慮哪些部分須要抽離出來,須要考慮共有邏輯,否則程序維護難度太大。
![](http://static.javashuo.com/static/loading.gif)
Vue3 中的代碼
![](http://static.javashuo.com/static/loading.gif)
第一段邏輯是尤大的邏輯鼠標位置監聽邏輯:
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')
![](http://static.javashuo.com/static/loading.gif)
API 介紹
![](http://static.javashuo.com/static/loading.gif)
咱們先看看 Vue3 的基礎 API 都有哪些?
const{
createApp,
reactive,// 建立響應式數據對象
ref,// 建立一個響應式的數據對象
toRefs,// 將響應式數據對象轉換爲單一響應式對象
isRef,// 判斷某值是不是引用類型
computed,// 建立計算屬性
watch,// 建立watch監聽
// 生命週期鉤子
onMounted,
onUpdated,
onUnmounted,
}=Vue
![](http://static.javashuo.com/static/loading.gif)
setup 使用 composition API 的入口
![](http://static.javashuo.com/static/loading.gif)
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>
`
![](http://static.javashuo.com/static/loading.gif)
watch 定義監聽器
![](http://static.javashuo.com/static/loading.gif)
同 Vue2 只是寫法略有不一樣:
watch(()=> state.count *2, val =>{ console.log(`count * 2 is ${val}`)})
![](http://static.javashuo.com/static/loading.gif)
effect 反作用函數
![](http://static.javashuo.com/static/loading.gif)
響應式對象修改會觸發這個函數:
effect(()=>{
console.log('數值變化了..',state.count)
})
effect 是響應式的副產物,在 get 的時候收集 effect,並在 set 時候觸發,和 Vue2 中 dep.notify() 相似。
![](http://static.javashuo.com/static/loading.gif)
computed 計算屬性
![](http://static.javashuo.com/static/loading.gif)
同 Vue2:
const state = reactive({
count:0,
plusOne: computed(()=> state.count +1)
})
![](http://static.javashuo.com/static/loading.gif)
生命週期鉤子 Hooks
![](http://static.javashuo.com/static/loading.gif)
Vue2 |
Vue3 |
beforeCreate |
setup(替代) |
created |
setup(替代) |
beforeMount |
onBeforeMount |
mounted |
onMounted |
beforeUpdate |
onBeforeUpdate |
updated |
onUpdated |
beforeDestroy |
onBeforeUnmount |
destroyed |
onUnmounted |
errorCaptured |
onErrorCaptured |
![](http://static.javashuo.com/static/loading.gif)
Vue3 中的數據綁定
![](http://static.javashuo.com/static/loading.gif)
最後,再來分別看一下 Vue2 和 Vue3 中針對數據雙向綁定綁定分別作的處理。
Vue2 中數據綁定是基於 Object.definedProperty 實現的,這會產生一些問題,其中最主要的就是性能問題,在 data 中數據嵌套層數過多的時候尤其明顯。並且這個方法沒法監聽數組變化,因此 Vue2 中不得不對數組的變態方法進行了重寫。
而在 Vue3 中,數據的雙向綁定使用了 ES6 中的 Proxy,同時利用 WeakMap 進行緩存,在性能上面有了較大的提高。
使用 Object.defineProperty 沒法監聽到新增屬性,可是使用 Proxy 是能夠監聽到的。對比上面兩段代碼能夠發現有如下幾點不一樣:
Object.defineProperty監聽的是對象的每個屬性,而 Proxy 監聽的是對象自身;
使用 Object.defineProperty 須要遍歷對象的每個屬性,對於性能會有必定的影響;
Proxy 對新增的屬性也能監聽到,但 Object.defineProperty 沒法監聽到。
![](http://static.javashuo.com/static/loading.gif)
其餘
![](http://static.javashuo.com/static/loading.gif)
另外隨着 Vue3 rc 的推出,尤大在直播中提到了 vite。參考 snowpack 專門爲 Vue3 開發的打包工具,其描述是:針對 Vue 單頁面組件的沒法打包開發服務器,能夠直接在瀏覽器運行請求 Vue 文件。
可是和 webpack 比目前功能上還略有不足。並不能徹底替代 webpack。
點擊【閱讀原文】查看 Vue3 API 文檔
![](http://static.javashuo.com/static/loading.gif)
![](http://static.javashuo.com/static/loading.gif)
![](http://static.javashuo.com/static/loading.gif)
猜你喜歡
本文分享自微信公衆號 - 金科優源匯(jkyyh2020)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。