也沒啥好說的,直奔主題 javascript
首先,在GitHub上拉取最新代碼css
$ git pull https://github.com/vuejs/vue-next.git
$ cd vue-next && yarn
複製代碼
下載完成以後打開代碼, 開啓sourceMap 一、tsconfig.json 把sourceMap字段修改成true
html
rollup.config.js
中,手動鍵入
output.sourcemap = true
三、
yarn dev
四、在根目錄建立一個demo目錄用於存放示例代碼 並在demo目錄下建立html、js文件,引入構建後的vue文件
/demo/index.html
前端
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style> .container { text-align: center; font-size: 24px; padding: 32px; } </style>
<script src="../packages/vue/dist/vue.global.js"></script>
</head>
<body>
<div id="app"></div>
</body>
<script src="./index.js"></script>
</html>
複製代碼
/demo/index.js
vue
const { reactive } = Vue
var App = {
template: ` <div class="container"> {{message}} </div>`,
setup() {
const state = reactive({message: "Hello World!!!"})
return {
...state
}
}
}
Vue.createApp().mount(App, '#app')
複製代碼
在瀏覽器打開我們編寫的html文件, java
這裏的服務器環境使用serve
庫來建立的,有興趣的話能夠看下
serve
anyway,我們接着看我們的/demo/index.js
文件,能夠看到,我們用了setup, reactive
等函數,這就是Vue3的Composition API
,相對於Vue2的組件來講 3 可讓咱們很簡單的經過組合API的方式建立一個 基於Vue3 響應式 Web 應用。 下邊我會經過一個個的demo爲你們詳細解釋這些API。react
接下來我們實現一個雙向綁定的demo!!!git
const { reactive } = Vue
let App = {
template: ` <div class="container"> <input v-model="value"/>{{value}} </div>`,
setup() {
return reactive({ value: '' })
}
}
Vue.createApp().mount(App, '#app')
複製代碼
setup是幹啥的?? setup其實是一個組件的入口,它運行在組件被實例化時候,props 屬性被定義以後,實際上等價於 2 版本的
beforeCreate
和
Created
這兩個生命週期。
setup接受兩個參數,第一個參數是props, 另外一個參數是context,因此你們在使用2.0時習慣的在this下獲取屬性的方式 ,在 vue3.0 中,變成了:github
setup(props, ctx) {
console.log(props, ctx)
}
複製代碼
不過在模板中仍然能夠直接使用props的屬性值,例如:shell
let Child = {
template: `<div>{{title}}</div>`,
setup(props, context) {
console.log(props)
}
}
let App = {
template: ` <div class="container"> <Child title="test props"/> </div>`,
components: { Child }
}
Vue.createApp().mount(App, '#app')
複製代碼
那reactive???以前用的 data呢??? 在Vue3中,咱們能夠把數據通過 reactive 加工變成響應式的對象,用於模版的渲染數據, 固然Vue的向下兼容 仍是容許咱們使用data的方式實現,但既然Vue3出新的寫法了,何不嘗試一波呢
const { reactive, toRefs } = Vue
let App = {
template: ` <div class="container"> count: {{count}} <button @click="handlerCountAdd"> Click ++ </button> </div>`,
setup() {
const state = reactive({ count: 0 })
const handlerCountAdd = () => {
state.count++
}
return { ...toRefs(state), handlerCountAdd }
}
}
Vue.createApp().mount(App, '#app')
複製代碼
這個toRefs是??????????? 在說這個以前 我想先說下 ref ,vue3提供的ref讓咱們有機會建立單個的響應式的對象,在setup函數中return出去以後,在模板中可直接訪問,例:
const App = {
template: ` <div class="container"> {{value}} </div>`,
setup() {
const value = ref(1)
return value
}
}
Vue.createApp().mount(App, '#app')
複製代碼
能夠看到 vulue已經被渲染到頁面上。 那上文提到的
reactive
建立的響應式對象 在模板中訪問的話,則須要
state.xxx
, 例:
const App = {
template: ` <div class="container"> {{state.value}} </div>`,
setup() {
const state = reactive({ value: 'reactive' })
return { state }
}
}
Vue.createApp().mount(App, '#app')
複製代碼
這樣訪問屬性確實有點麻煩,vue3提供的toRefs
正是爲咱們解決這個問題的,toRefs把一組的響應式對象拆成單個的響應式對象,就可以在模板中直接訪問了,及:
const App = {
template: ` <div class="container"> {{value}} </div>`,
setup() {
const state = reactive({ value: 'reactive' })
return toRefs(state)
}
}
Vue.createApp().mount(App, '#app')
複製代碼
let App = {
template: ` <div class="container"> value: <input v-model="value"/> <br/> rvalue: {{rvalue}} </div>`,
setup() {
const state = reactive({
value: '',
rvalue: computed(() =>
state.value
.split('')
.reverse()
.join('')
)
})
return toRefs(state)
}
}
Vue.createApp().mount(App, '#app')
複製代碼
這個demo中 咱們用到了
computed
計算屬性實現了反轉字符串的功能,這個函數雖然簡單,可是功能很強大,正如vue官網所說:對於任何複雜邏輯,你都應當使用計算屬性。
你們都知道, 在Vue3中實現數據響應式的方案由Vue2中的Object.defineProperty 換成了 Proxy,關於數據響應式的Api上邊說到了一些,還剩下effect和watch沒有說起到,effect是數據響應式中重要的一部分,watch和computed都是基於 effect 的,下邊來看下代碼
let App = {
template: ` <div class="container"> count: {{count}} <button @click="handlerCountAdd"> Click ++ </button> </div>`,
setup() {
const state = reactive({ count: 0, value: 1 })
const handlerCountAdd = () => {
state.count++
}
watch(
() => state.count,
val => {
console.log('watch', state.count)
console.log('watch', state.value)
}
)
effect(() => {
console.log('effect', state.count)
console.log('effect', state.value)
})
return { ...toRefs(state), handlerCountAdd }
}
}
Vue.createApp().mount(App, '#app')
複製代碼
代碼是基於上邊計數器的demo來實現的,能夠看到我們點擊click++的時候,effect和watch均可以監聽到我們數據的變化,從而根據業務做出相應的操做, 看到這裏,你們可能會有一個疑問,那就是,既然effect和watch都能監聽到數據的變化,那二者有什麼區別呢?
首先,effect 在響應式數據變化的時候就會執行,執行次數根據響應式數據的個數來決定,例如
let App = {
template: ` <div class="container"> <button @click="handlerCountAdd"> Click ++ </button> </div>`,
setup() {
const r = ref(1)
const s = ref(1)
const t = ref(1)
const handlerCountAdd = () => {
r.value *= 1
s.value *= 2
t.value *= 3
}
effect(() => {
console.log('effect', [r.value, s.value, t.value])
})
return { handlerCountAdd }
}
}
Vue.createApp().mount(App, '#app')
複製代碼
如上圖所示: 咱們點擊一次同時更新三個ref,effect就會被執行三次。
而watch則點擊一次 ,只會觸發執行一次
let App = {
template: ` <div class="container"> <button @click="handlerCountAdd"> Click ++ </button> </div>`,
setup() {
const state = reactive({ count: 0, value: 1 })
const r = ref(1)
const s = ref(1)
const t = ref(1)
const handlerCountAdd = () => {
r.value *= 1
s.value *= 2
t.value *= 3
}
watch([r, s, t], val => {
console.log('watch', val)
})
return { handlerCountAdd }
}
}
Vue.createApp().mount(App, '#app')
複製代碼
vue3 Watch的源碼在
這裏有興趣的小夥伴能夠研究研究
好了,vue3Composition Api
中經常使用的一些函數在咱上邊的demo中使用了,接下來我們對比一下2和3的生命週期函數有什麼改變
Vue2 | Vue3 |
---|---|
beforeCreate | setup(替代) |
created | setup(替代) |
beforeMount | onBeforeMount |
mounted | onMounted |
beforeUpdate | onBeforeUpdate |
updated | onUpdated |
beforeDestroy | onBeforeUnmount |
destroyed | onUnmounted |
errorCaptured | onErrorCaptured |
雖然Vue官方說能夠直接運行run dev 就能夠對其進行調試,但是運行該命令後,是生成事後的代碼,不能對其編寫的ts源碼進行調試。
開啓了sourcemap以後,在編譯時會生成對應的sourcemap文件,而後贊麼就能夠在瀏覽器愉快的使用斷點調試Vue的源代碼了篇幅很大,感謝你們耐心觀看,文中若有錯誤歡迎指正。
我是
Colin
,能夠加我微信zw_898396209
與我交流,備註交流。
感謝H5獸超進化前端菜雞獸指正文章中的問題