因爲vue更新後與文中demo不兼容 ,再此說明一下, 本文的全部內容是基於3.0.0-alpha.1
版本編寫,各位小夥伴在學習的時候注意下版本哦 javascript
首先,在GitHub上拉取最新代碼html
$ git pull https://github.com/vuejs/vue-next.git $ cd vue-next && yarn 複製代碼
下載完成以後打開代碼, 開啓sourceMap 一、tsconfig.json 把sourceMap字段修改成true
前端
rollup.config.js
中,手動鍵入
output.sourcemap = true
三、
yarn dev
四、在根目錄建立一個demo目錄用於存放示例代碼 並在demo目錄下建立html、js文件,引入構建後的vue文件
/demo/index.html
vue
<!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
java
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文件, react
這裏的服務器環境使用serve
庫來建立的,有興趣的話能夠看下
serve
anyway,我們接着看我們的/demo/index.js
文件,能夠看到,我們用了setup, reactive
等函數,這就是Vue3的Composition API
,相對於Vue2的組件來講 3 可讓咱們很簡單的經過組合API的方式建立一個 基於Vue3 響應式 Web 應用。 下邊我會經過一個個的demo爲你們詳細解釋這些API。git
接下來我們實現一個雙向綁定的demo!!!github
const { reactive } = Vue let App = { template: ` <div class="container"> <input v-model="state.value"/>{{state.value}} </div>`, setup() { const state = reactive({ value: '' }) return { state } } } Vue.createApp().mount(App, '#app') 複製代碼setup是幹啥的?? setup其實是一個組件的入口,它運行在組件被實例化時候,props 屬性被定義以後,實際上等價於 2 版本的
beforeCreate
和
Created
這兩個生命週期。
setup接受兩個參數,第一個參數是props, 另外一個參數是context,因此你們在使用2.0時習慣的在this下獲取屬性的方式 ,在 vue3.0 中,變成了:shell
setup(props, ctx) { console.log(props, ctx) } 複製代碼
不過在模板中仍然能夠直接使用props的屬性值,例如:npm
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
,能夠掃描下方二維碼加我微信,備註交流。
感謝H5獸超進化前端菜雞獸指正文章中的問題