1. 程式人生 > 程式設計 >15分鐘上手vue3.0(小結)

15分鐘上手vue3.0(小結)

Vue 3 還沒有正式釋出,但是 Alpha 版本已經發布了。

雖然官方還不推薦在生產環境中直接使用 Vue 3 ,但是提前學習總歸是有好處的。

嘴上喊著老子學不動了,雙手還是很誠實的打開了 Vue 3 文件

建立專案

Vue 官方很貼心的提供了一個 github 倉庫,讓我們能快速體驗Vue 3的新特性:

git clone https://github.com/vuejs/vue-next-webpack-preview.git vue3-start
cd vue3-start
npm install or yarn intall

開發環境準備就緒後,啟動命令:

npm run dev

在瀏覽器中開啟 http://127.0.0.1:8080 ,您可以看到一個簡單的計數器頁面:

15分鐘上手vue3.0(小結)

開啟 package.json,當前使用的 vue 版本是:3.0.0-beta.2

Vue 3 新特性

Vue 3 的設計目標是更快,更小,並更好的支援 TypeScript 。

一些新特性包括:

1、Composition API
2、Multiple root elements
3、Suspense
4、Multiple V-models
5、Reactivity
6、Teleport
7、Transition
8、Remove Filter
9、App configuration

1、Composition API


Vue 官方釋出了 Composition API 的官方外掛,使廣大使用者可以在 Vue2.x 中享受 Function Base 帶來的新體驗。
而在 vue 3 中無需單獨安裝外掛,開箱即用。

開啟 App.vue,你會看到 setup()方法:

<template>
 <img src="./logo.png">
 <h1>Hello Vue 3!</h1>
 <button @click="inc">Clicked {{ count }} times.</button>
</template>

<script>
import { ref } from 'vue'

export default {
 setup() {
 const count = ref(0)
 const inc = () => {
  count.value++
 }

 return {
  count,inc
 }
 }
}
</script>

<style scoped>
img {
 width: 200px;
}
h1 {
 font-family: Arial,Helvetica,sans-serif;
}
</style>

Composition API 主要提供兩大好處:

1、清晰的程式碼結構
2、消除重複邏輯

<template>
 <div class="counter">
 <p>count: {{ count }}</p>
 <p>NewVal (count + 2): {{ countDouble }}</p>
 <button @click="inc">Increment</button>
 <button @click="dec">Decrement</button>
 <p> Message: {{ msg }} </p>
 <button @click="changeMessage()">Change Message</button>
 </div>
</template>
<script>
import { ref,computed,watch } from 'vue'
export default {
 setup() {
 /* ---------------------------------------------------- */
 let count = ref(0)
 const countDouble = computed(() => count.value * 2)
 watch(count,newVal => {
  console.log('count changed',newVal)
 })
 const inc = () => {
  count.value += 1
 }
 const dec = () => {
  if (count.value !== 0) {
  count.value -= 1
  }
 }
 /* ---------------------------------------------------- */
 let msg= ref('some text')
 watch(msg,newVal => {
  console.log('msg changed',newVal)
 })
 const changeMessage = () => {
  msg.value = "new Message"
 }
 /* ---------------------------------------------------- */
 return {
  count,inc,dec,countDouble,msg,changeMessage
 }
 }
}
</script>

如果你不喜歡使用 Composition API,也可以繼續使用 2.x 的傳統方法:

<template>
 <div class="counter">
 <p>count: {{ count }}</p>
 <p>NewVal (count + 2): {{ countDouble }}</p>
 <button @click="inc">Increment</button>
 <button @click="dec">Decrement</button>
 <p> Message: {{ msg }} </p>
 <button @click="changeMessage()">Change Message</button>
 </div>
</template>
<script>
export default {
 data() {
 return {
  count: 0,msg: 'some message'
 }
 },computed: {
 countDouble() {
  return this.count*2
 }
 },watch: {
 count(newVal) {
  console.log('count changed',newVal)
 },msg(newVal) {
  console.log('msg changed',newVal)
 }
 },methods: {
  inc() {
  this.count += 1
 },dec() {
  if (this.count !== 0) {
  this.count -= 1
  }
 },changeMessage() {
  msg = "new Message"
 }
 }

}
</script>

上面兩段程式碼在效果上市完全等價的

使用 Composition API 的好處:可以讓我們更好地組織程式碼(state,methods,computed properties,watcher 等)。
隨著元件規模的增長,如何組織我們的業務程式碼逐漸變成一個重要的問題,確保新進的開發人員都可以輕鬆地理解程式碼,而不需要花太多時間。

以前我們會使用 mixin 來複用程式碼。然而,mixin 最大的痛點是,需要我們跟蹤不同元件中的狀態和方法,這往往會給開發帶來一定的心智負擔,一不小心,mixin 可能會覆蓋元件中的現有狀態或方法。

使用 Composition API 讓程式碼複用更加容易。

我們同樣可以抽取出重複功能的程式碼:

// message.js
import { ref,watch } from "vue";
export function message() {
 let msg = ref(123);
 watch(msg,(newVal) => {
 console.log("msg changed",newVal);
 });
 const changeMessage = () => {
 msg.value = "new Message";
 };
 return { msg,changeMessage };
}

在其他元件中使用上面元件:

<template>
 <div class="counter">
 <p>count: {{ count }}</p>
 <p>NewVal (count + 2): {{ countDouble }}</p>
 <button @click="inc">Increment</button>
 <button @click="dec">Decrement</button>
 <p>Message: {{ msg }}</p>
 <button @click="changeMessage()">change message</button>
 </div>
</template>
<script>
import { ref,watch } from 'vue'
import { message } from './common/message'
export default {
 setup() {
 let count = ref(0)
 const countDouble = computed(() => count.value * 2)
 watch(count,newVal)
 })
 const inc = () => {
  count.value += 1
 }
 const dec = () => {
  if (count.value !== 0) {
  count.value -= 1
  }
 }
 let { msg,changeMessage } = message()
 return {
  count,changeMessage,countDouble
 }
 }
}
</script>

2、Multiple root elements

在 Vue 2 中,tempalte 只能取一個根元素。即使我們只有兩個 <p> 標記,我們也必須將它們包含在一個 <div> 標記中:

<template>
 <div class="counter">
 <p> Count: {{ count }} </p>
 <button @click="increment"> Increment </button>
 <button @click="decrement"> Decrement</button>
 </div>
</template>

為了能編譯通過,我們通常會增加一個根節點。

這個設計確實很糟糕,我曾經無數次吐槽過這個設計。因為會帶來不必要的程式碼巢狀和縮排。

幸好在 Vue 3 中取消了這一限制:
可以直接在<template></template>中使用任意數量的標籤:

<template>
 <p> Count: {{ count }} </p>
 <button @click="increment"> Increment </button>
 <button @click="decrement"> Decrement </button>
</template>

用 VScode 開啟模板時,看到一些 lint 錯誤,這是因為官方外掛 eslint-plugin-vue 還沒有支援新的模板語法。

3、Suspense

Suspense 是一個 Vue 3 新特性。

通常前後端互動是一個非同步的過程: 預設我們提供一個載入中的動畫,當資料返回時配合使用 v-if 來控制資料顯示。
Suspense 的出現大大簡化了這個過程:它提供了 default 和 fallback 兩種狀態:

<template>
 <Suspense>
 <template #default>
  <div v-for="item in articleList" :key="item.id">
  <article>
   <h2>{{ item.title }}</h2>
   <p>{{ item.body }}</p>
  </article>
  </div>
 </template>
 <template #fallback>
  Articles loading...
 </template>
 </Suspense>
</template>
<script>
import axios from 'axios'
export default {
 async setup() {
 let articleList = await axios
  .get('https://jsonplaceholder.typicode.com/posts')
  .then(response => {
  console.log(response)
  return response.data
  })
 return {
  articleList
 }
 }
}
</script>

4、Multiple v-models

我們都知道 v-models 用於雙向資料繫結。一般用於與表單元素一起使用。有時我們會在自定義元件中使用它。
Vue 2 只允許在一個元件上使用一個 v-models。在 Vue 3 中,我們可以將任意數量的 v-model 繫結到我們的定製元件上:

<template>
 <survey-form v-model:name="name" v-model:age="age">
 {" "}
 </survey-form>
</template>
SurveyForm.vue:
<template>
 <div>
  <label>Name: </label>
  <input :value="name" @input="updateName($event.target.value)" />
  <label>Age: </label>
  <input :value="age" @input="updateAge($event.target.value)" />
 </div>
</template>
<script>
 export default {
  props: {
  name: String,age: Number
  },setup(props,{ emit }) {
  const updateName = value => {
   emit('update:name',value)
  }
  const updateAge = value => {
   emit('update:age',+value)
  }
  return { updateName,updateAge }
  }
 }
</script>

5、Reactivity

Vue 2 的響應式已經非常棒了,但在少數情況下會存在一些問題:

<template>
 <div class="hello" @click="test">test {{list }} {{ myObj }}</div>
</template>
<script>
export default {
 name: "HelloWorld",data() {
 return {
  list: [1,2],myObj: { name: "Preetish" }
 };
 },watch: {
 list: {
  handler: () => {
  console.log("watcher triggered");
  },deep: true
 }
 },methods: {
 test() {
  this.list[2] = 4;
  this.myObj.last = "HS";
  delete this.myObj.name;
 }
 }
};
</script>

我們發現通過this.list下標來修改元素,並不會觸發 wacher 監聽函式,為了達到目的,我們不得不使用 vue.set() 或 vue.delete() 這些方法。

而在 vue 3 中,我們不需要藉助其他 API:

export default {
 setup() {
 let list = ref([1,2]);
 let myObj = ref({ name: "Preetish" });
 function myFun() {
  list.value[3] = 3;
  myObj.value.last = "HS";
  delete myObj.value.name;
 }
 return { myFun,list,myObj };
 },};

6、Portals

Portals 提供了一種將元件中渲染到頁面任意一個 DOM 節點中的能力。在 Vue 2 中,利用一個 portal-vue 的第三方外掛來做到這一點。

在 vue 3 中直接使用:

<Teleport to="#modal-layer">
 <div class="modal">hello</div>
</Teleport>
<Teleport> 是 vue3 中提供特定的標籤用於建立一個 Portals。
<Teleport> </Teleport>中間出現的內容會出現在 to 指定的節點中:
<div id="modal-target"></div>

目前為止,<Teleport>在 Alpha 版本中並不能使用

7、Transition

之前我在使用 v-enter-active,v-enter,v-enter-to 這些個狀態時搞的暈頭轉向。
現在 Vue 3 從命名上更直觀了: v-enter 變成了 v-enter-from,v-leave 變成 v-leave-from。

8、Remove Filter

Vue 3 拋棄了 Filter 的用法,更推薦使用計算屬性或方法來實現:

<!-- vue 2.x -->
{{ date | format }}

<!-- vue 3.0 -->
{{ format(date) }}

9、App configration

在 Vue 2 中,如果想使用 use(),mixin(),directive() 等方法需要配合全域性 Vue 物件:

import Vue from "vue";
import App from "./App";

Vue.use(/* ... */);
Vue.mixin(/* ... */);
Vue.component(/* ... */);
Vue.directive(/* ... */);

new Vue({
 el: "#app",template: "<App/>",components: {
  App,},});

在 Vue 3 中, 改成了 createApp 返回的 Vue 例項:

import { createApp } from "vue";
import App from "./App.vue";

const app = createApp(App);

app.use(/* ... */);
app.mixin(/* ... */);
app.component(/* ... */);
app.directive(/* ... */);

app.mount("#app");

結束語

總之Vue 3 通過提供一種簡單的方式來組織和共享程式碼,並提供強大的 TypeScript 支援,新的程式碼組織方式會對未來的應用開發產生重大影響。

同時一些其它的特性,如 Suspense,多個 v-models 等也會給開發帶來巨大的便利。

同時效能更快,體積更小。它是如何做到的請參考我寫的另一篇文章:Vue.js 作者:關於 Vue3.0 背後的故事

到此這篇關於15分鐘上手vue3.0(小結)的文章就介紹到這了,更多相關vue3.0入門內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!