Vue3教程-使用Vue3新特性創建一個簡單App

Vue3目前還沒有文檔,但git上面卻有些樣本,本來打算但拿它的樣本去寫一個tutorial,但發現已經有人寫了,而且寫得很好。此文是我按著他的文章內容用自己的系統環境走了一遍編寫,大多數只是翻譯過來。
相關參考:
https://vuejsdevelopers.com/2020/03/16/vue-js-tutorial/
https://github.com/vuejs/vue-next-webpack-preview
開發環境:
window10 x64
node v10.16.3
npm v6.13.4

1.Vue3安裝和設置

首先,我們需要把項目vue-next-webpack-preview復制過來,此項目包含Vue的設置

 git clone https://github.com/vuejs/vue-next-webpack-preview.git vue3-experiment
 cd vue3-experiment
 npm i

當我們復制完項目和安裝完node_modules之后,我們需要把樣板的文件刪除,和重新創建一個新的main.js(window系統我找不到好命令,只好全部刪了再重新創建)

rd -r "src" 
mkdir src
cd src
type > main.js

現在我們來運行一下(記得把路徑切換回跟目錄,假如路徑還是‘src’的話,執行下‘cd ../’)

npm run dev

2.創建一個新的Vue app

以前我們會用new Vue()去創建應用,現在我們引入createApp方法去創建。
我們會調用createApp方法,然后把我們定義的Vue實例對象作為參數傳入,之后createApp方法會返回一個app對象。
下一步,我們會調用app對象的mount方法,把我們css選擇器的元素傳進去,這個就像我們之前的vue2的$mount方法一樣

//main.js

import { createApp } from "vue";

const app = createApp({
  // root instance definition
});

app.mount("#app");

為何要這么做
以前的話,我們會把一些全局寫在這里(如plugins, mixins, prototype properties等等),假如有多個app的話,會造成實例污染。

//main.js

// Affects both instances
Vue.mixin({ ... })

const app1 = new Vue({ el: '#app-1' })
const app2 = new Vue({ el: '#app-2' })

vue3的createApp會返回一個全新的app,可以很好地避免這個問題

3.添加state屬性

這里,我們會創建一個'計數'的app,每次我們點擊按鈕,計數都+1。
在Vue2,我們可以在我們的app創建一個data對象,data對象里有創建一個count屬性作為記錄計數。

//main.js

const app = createApp({
  data: {
    count: 0
  }
});

但現在不允許這樣干了,data對象必須通過工廠方法創建并返回,你必須要在Vue components中這么做。

//main.js

const app = createApp({
  data: () => ({
    count: 0
  })
});

為何要這么做
假如有些情況,我們需要共享state呢?兩個app之間的state會互相影響。

//main.js

const state = {
  sharedVal: 0
};

const app1 = new Vue({ state });
const app2 = new Vue({ state });

// Affects both instances
app1._data.sharedVal = 1;

但這方面的用例很少而且可以繞過,而且這樣聲明很不友善,所以這種特征(feature,或者說這種寫法吧)已經決定移除。
我們來繼續剛才計數app,我們需要加一個方法去增加記錄計數(count),這一點和Vue 2沒什么不同

//main.js

const app = createApp({
  data: () => ({
    count: 0  
  }),
  methods: {
    inc() {
      this.count++;
    }
  }
});

4.使用root component

我們目前為止還有沒有component來瀏覽效果(文章說在控制臺會出現‘Component is missing render function’的警告,但反正我看不到這個警告)。
現在我們來創建一個component來作為一個root實例。

cd src
type > App.vue

App.vue的內容我們先不管,現在我們可以獲取root實例用來渲染component了,在Vue2中,我們通常會用render方法去做:

//main.js

import App from "./App.vue";

const app = createApp({
  ...
  render: h => h(App)
});

app.mount("#app");

我們依然可以這么做,但在Vue 3有一種更簡單的方法,我們可以直接把root實例作為參數帶過去:

//main.js

import App from "./App.vue";

const app = createApp(App);

app.mount("#app");

這意味著App component不止用來渲染root實例,而且本身就是一個root實例。
至此,我們讓代碼再變簡單點吧:

//main.js

createApp(App).mount("#app");

我們把之前計數的state和方法移動到App.vue(root component)吧。

//App.vue

<script>
export default {
  data: () => ({
    count: 0  
  }),
  methods: {
    inc() {
      this.count++;
    }
  }
};
</script>

5.創建template

這個沒啥好說,就是在root component添加template代碼,放一個按鈕,然后每點擊一次按鈕就+1,我們瀏覽器看到的就這個部分的內容:

//App.vue

<template>
  <span>Button clicked {{ count }} times.</span>
  <button @click="inc">Inc</button>
</template>
<script>
...
</script>

以前的話,這樣寫一定會報錯,因為有兩個root元素,template下面只能允許一個大的html元素,包含所有,但在Vue3,我們沒有這樣的強制(終于把單元素這種寫法改掉了,以前一直就覺得有點受迫)。

6.Composition API

Composition API是Vue3的一個王牌。Composition API可以讓你使用setup方法去定義(define,定義或者設計的意思)控件。
直接看代碼吧,我們可以把App.vue寫成:

//App.vue

<template>
  <span>Button clicked {{ count }}</span>
  <button @click="inc">Inc</button>
</template>
<script>
import { ref } from "vue";
export default {
  setup () {
    const count = ref(0);
    const inc = () => {
      count.value++;
    };
    return {
      count,
      inc
    }
  }
};
</script>

我們導入ref方法,這個方法可以讓我們去定義count這個變成,這個變量相當于this.count。假如我們不加ref方法,直接寫成‘const count = 0;’,count會變成一個常量,不會再改變,這個跟react是不是有點像?
更多可以參考這個文檔 Vue Composition API docs

附最終效果圖:


App.vue
main.js
瀏覽器效果
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。