vue3在今年內應該就會推出,尤大以前也針對vue3的設計和api給出了RFC和最新徵求意見稿。本人閱讀後總結了一些我的心得,但願對你們有用。javascript
vue2在近幾年不太長的生命週期內,經歷了大小各類項目的歷練,能夠說很是易於上手,方便開發。同時也暴露了很多問題亟待解決:css
vue3基於上述弊端從新設計了內部的實現方式,而且同時從新設計了組件選項和api。主要有:html
從新設計了響應式數據對象,內部實現從defineProperty改成由瀏覽器原生支持的proxy實現。包括手動定義響應式數據(reactive)和包裝對象(ref)兩種api方式建立響應式數據。前端
示例代碼:vue
// reactive響應式數據
import { reactive } from 'vue'
const state = reactive({
count: 0
})
function increment() {
state.count ++
}
複製代碼
// ref包裝對象
import { ref } from 'vue'
const count = ref(0);
// 以變量的形式引用包裝對象
function increment() {
count.value ++
}
複製代碼
新增了watchEffect api,和vue2中的watch效果相似,監測響應式數據變化並執行反作用函數。java
import { reactive, ref, watchEffect } from 'vue'
const state = reactive({
count: 0,
})
const titleCount = ref(0);
// 當state.count、titleCount變化時,watchEffect將會自動執行反作用回調函數
watchEffect(() => {
document.body.innerHTML = `count is ${state.count}`
document.title = `title count is ${titleCount}`
});
複製代碼
從新設計了computed api,將會建立一個依賴其它狀態的響應式狀態。被依賴的狀態能夠是由reactive或ref建立響應式數據,生成的狀態則是一個只讀的包裝對象,以變量的形式使用時須要以
.value
這種方式。react
import { reactive, ref, computed } from 'vue'
const state = reactive({
count: 0,
})
const num = ref(0);
const double = computed(() => state.count * 2)
// 使用ref建立響應式對象時須要用.value取值計算
const triple = computed(() => num.value * 3)
watchEffect(() => {
console.log(double.value) // -> 0
console.log(triple.value) // -> 0
})
state.count++ // -> 2
num.value++ // -> 3
複製代碼
新設計了setup()組件選項,代替以前的data組件選項。這個函數是組件開始邏輯的地方,它接收組件的props屬性做爲參數,而後開始調用,整個組件生命週期內只會執行一次。webpack
import { ref } from 'vue'
const MyComponent = {
setup(props) {
const msg = ref('hello')
const appendName = () => {
msg.value = `hello ${props.name}`
}
return {
msg,
appendName
}
},
template: `<div @click="appendName">{{ msg }}</div>`
}
複製代碼
類型推導,須要使用defineComponent函數定義組件才能支持typescript類型推導web
import { defineComponent, ref } from 'vue'
const MyComponent = defineComponent({
// props選項聲明用來定義prop屬性類型
props: {
msg: String
},
setup(props) {
console.log(props.msg) // string 或 undefined
// setup中返回的數據對象能夠在模板中用於類型推斷推斷類型
const count = ref(0)
return {
count
}
}
})
複製代碼
在瞭解了上面的一些基本api後,咱們能夠看一下尤大給出的一個基本組件寫法:typescript
import { ref, computed, watchEffect, onMounted } from 'vue'
const App = {
template: ` <div> <span>count is {{ count }}</span> <span>plusOne is {{ plusOne }}</span> <button @click="increment">count++</button> </div> `,
setup() {
// reactive state
const count = ref(0)
// computed state
const plusOne = computed(() => count.value + 1)
// method
const increment = () => { count.value++ }
// watch
watchEffect(() => count.value * 2, val => {
console.log(`count * 2 is ${val}`)
})
// lifecycle
onMounted(() => {
console.log(`mounted`)
})
// expose bindings on render context
return {
count,
plusOne,
increment
}
}
}
複製代碼
這裏只介紹了少數比較重要的vue3 api,並且不肯定最終api還會不會再改動,若是想要詳細查詢學習的同窗能夠去查看官方api文檔。
尤大親自說過vue3的最新設計很大程度上是借鑑了react hooks的思路。具體類似的地方至少有:
官方文檔也給出了一個將獲取鼠標位置的功能抽取成獨立函數的實例:
// 抽取獲取鼠標x, y位置的成函數 mouse.js
import { ref, onMounted, onUnmounted } from 'vue'
export function useMousePosition() {
const x = ref(0)
const y = ref(0)
function update(e) {
x.value = e.pageX
y.value = e.pageY
}
onMounted(() => {
window.addEventListener('mousemove', update)
})
onUnmounted(() => {
window.removeEventListener('mousemove', update)
})
return { x, y }
}
複製代碼
import { useMousePosition } from './mouse'
export default {
setup() {
const { x, y } = useMousePosition()
// 其餘邏輯...
return { x, y }
},
}
複製代碼
若是是寫過react hooks的同窗會發現,這與react hooks抽取公用函數的寫法一模一樣。換句話說,寫過二者其一的話,都有助於咱們理解另外一個框架。
雖然vue3的寫法相似於react hooks,可是其內部實現思路是不一樣的:
vue3的設計在尤大看來至少有一下優點:
在閱讀api設計文檔時確實發現一些容易讓開發者搞暈的東西,尤大對此也進行了總結。對於我我的來講有如下比較麻煩的地方:
我我的但願vue3正式推出的時候,文檔可能提供api使用推薦寫法,同時能提供相應的lint校驗插件輔助,這樣纔好讓不一樣開發者寫出通用可讀的代碼。
隨着vue3而來的構建工具不是webpack,而是vite一種新型的項目構建工具。vite做用相似webpack,可是原理與webpack不一樣。對比webpack有如下優點:
我也研究了一下vite的技術原理:
做者簡介: 宮晨光,人和將來大數據前端工程師。