Vue 3指令與事件處理

Amd794發表於2024-05-25

title: Vue 3指令與事件處理
date: 2024/5/25 18:53:37
updated: 2024/5/25 18:53:37
categories:

  • 前端開發

tags:

  • Vue3基礎
  • 指令詳解
  • 事件處理
  • 高階事件
  • 實戰案例
  • 最佳實踐
  • 效能最佳化

image

第1章 Vue 3基礎

1.1 Vue 3簡介

Vue 3 是一個由尤雨溪(尤大)領導的開源JavaScript框架,它專注於構建使用者介面。相較於Vue 2,Vue 3在核心理念上保持一致,但對一些底層實現進行了重大最佳化,包括:

  • SFC(Single File Component) : Vue 3繼續支援SFC模式,將元件的模板、樣式和邏輯整合在一個檔案中。
  • Composition API: 引入新的程式設計模型,強調元件內部狀態的可組合性,而非依賴於props和data。
  • TypeScript支援: 提供了更好的型別系統,方便開發者編寫型別安全的程式碼。
  • Performance: 透過移除一些不必要的依賴,提高了效能,特別是對於大型應用。

1.2 安裝與配置

1.2.1 環境準備

  • Node.js: Vue 3需要Node.js環境,建議使用最新版本。
  • 使用npm或yarn: 作為包管理器,安裝Vue CLI(命令列工具)。

1.2.2 Vue CLI安裝

  • 開啟終端(或命令提示符):
npm install -g @vue/cli

  • 或者使用yarn:
yarn global add @vue/cli

1.2.3 建立專案

  • 建立一個新的Vue 3專案:
vue create my-project

  • 進入專案目錄:
cd my-project

1.2.4 配置基本檔案

  • 修改src/main.js,引入Vue例項並啟動應用:
import { createApp } from 'vue';
import App from './App.vue';

const app = createApp(App);
app.mount('#app');

1.3 模板語法

1.3.1 JSX-like模板 Vue 3的模板語法採用類似React的JSX語法,但更簡潔。如建立一個Hello World元件:

<template>
  <div>Hello, {{ name }}!</div>
</template>

<script>
export default {
  data() {
    return {
      name: 'World',
    };
  },
};
</script>

  • {{ }}用於插值表示式,{{{ }}}用於文字插值。
  • <div>是標籤,<template>用於包裹元件內容。

1.3.2 簡化模板 Vue 3還支援更簡潔的模板語法,如:

<template>
  <div>Hello, {{ name }}!</div>
</template>
<script>
export default {
  data() {
    return { name: 'World' };
  },
};
</script>

  • 省略了<script>標籤內的export defaultdata

第2章 Vue 3指令

2.1 內建指令

Vue 3提供了多種內建指令,用於控制DOM的行為和渲染。以下是一些常用的內建指令:
AD:漫畫首頁

2.1.1 v-bind

v-bind 指令用於動態地繫結一個或多個屬性,或者一個元件 prop 到表示式。在Vue 3中,v-bind 可以簡寫為 :

示例:

<template>
  <img :src="imageSrc" alt="Image">
</template>
<script>
export default {
  data() {
    return {
      imageSrc: 'https://example.com/image.jpg',
    };
  },
};
</script>

2.1.2 v-model

v-model 指令用於在表單控制元件或者元件上建立雙向資料繫結。

示例:

<template>
  <input v-model="message" placeholder="edit me">
  <p>Message is: {{ message }}</p>
</template>
<script>
export default {
  data() {
    return {
      message: '',
    };
  },
};
</script>

2.1.3 v-on

v-on 指令用於監聽DOM事件,並在觸發時執行一些JavaScript程式碼。v-on 可以簡寫為 @

示例:

<template>
  <button @click="incrementCounter">Click me</button>
</template>
<script>
export default {
  data() {
    return {
      counter: 0,
    };
  },
  methods: {
    incrementCounter() {
      this.counter++;
    },
  },
};
</script>

2.1.4 v-show與v-if

v-showv-if 指令用於條件性地渲染一塊內容。v-show 是透過CSS控制元素的顯示與隱藏,而 v-if 則是透過建立或銷燬DOM元素來控制。

示例:

<template>
  <p v-show="isVisible">This is shown by v-show</p>
  <p v-if="isVisible">This is shown by v-if</p>
</template>
<script>
export default {
  data() {
    return {
      isVisible: true,
    };
  },
};
</script>

2.1.5 v-for

v-for 指令用於基於源資料多次渲染元素或模板塊。

示例:

<template>
  <ul>
    <li v-for="item in items" :key="item.id">
      {{ item.text }}
    </li>
  </ul>
</template>
<script>
export default {
  data() {
    return {
      items: [
        { id: 1, text: 'Item 1' },
        { id: 2, text: 'Item 2' },
        { id: 3, text: 'Item 3' },
      ],
    };
  },
};
</script>

2.1.6 v-text與v-html

v-text 指令用於更新元素的 textContent。v-html 指令用於更新元素的 innerHTML。

示例:

<template>
  <p v-text="textContent"></p>
  <p v-html="htmlContent"></p>
</template>
<script>
export default {
  data() {
    return {
      textContent: 'This is text content',
      htmlContent: '<span>This is HTML content</span>',
    };
  },
};
</script>

透過這些內建指令,Vue 3允許開發者以宣告式的方式控制DOM,使得程式碼更加簡潔和易於維護。

2.2 自定義指令

除了內建指令,Vue 3還允許開發者建立自定義指令。自定義指令可以用於執行更多複雜的DOM操作。

2.2.1 建立自定義指令

可以使用 directives 選項在元件中註冊自定義指令。

示例:

export default {
  directives: {
    focus: {
      // 指令的定義
      mounted(el) {
        el.focus();
      },
    },
  },
};

2.2.2 鉤子函式

自定義指令可以包含以下幾個鉤子函式:

  • bind:只呼叫一次,指令第一次繫結到元素時呼叫。
  • inserted:被繫結元素插入到父節點時呼叫(僅保證父節點存在,但不一定已被插入到文件中)。
  • updated:所在元件的 VNode 更新時呼叫,但是可能發生在其子 VNode 更新之前。指令的值可能發生了改變,也可能沒有。但是你可以透過比較更新前後的值來忽略不必要的模板更新。
  • componentUpdated:所在元件的 VNode 及其子 VNode 全部更新後呼叫。
  • unbind:只呼叫一次,指令與元素解綁時呼叫。

示例:

export default {
  directives: {
    focus: {
      bind(el) {
        console.log('focus bind');
      },
      inserted(el) {
        console.log('focus inserted');
      },
      updated(el) {
        console.log('focus updated');
      },
      componentUpdated(el) {
        console.log('focus componentUpdated');
      },
      unbind(el) {
        console.log('focus unbind');
      },
    },
  },
};

2.2.3 指令引數與修飾符

自定義指令可以接受一個引數,該引數是一個字串,表示指令的修飾符。修飾符是一個 prefiex,以 . 開頭,用於指明指令應該以特殊方式繫結。

示例:

export default {
  directives: {
    focus: {
      bind(el, binding) {
        if (binding.arg === 'input') {
          el.focus();
        }
      },
    },
  },
};

可以在使用自定義指令時,使用 v-bind 傳遞引數。

示例:

<template>
  <input v-focus.input="">
</template>

透過自定義指令,開發者可以擴充套件 Vue 的功能,並在元件中實現更多複雜的DOM操作。

第3章 Vue 3事件處理

3.1 Vue 3事件處理

Vue 3的事件處理機制與Vue 2類似,但使用了更簡潔的語法。Vue 3中不再直接支援v-on,而是使用@符號來繫結事件。

3.1.1 基本事件繫結

基礎的事件繫結使用 @ 符號,後跟事件名稱,再加事件處理函式。例如:

<button @click="handleClick">點選我</button>

對應的JavaScript部分:

export default {
  methods: {
    handleClick() {
      console.log('Button clicked');
    },
  },
};

3.1.2 事件修飾符

Vue 3的事件修飾符與Vue 2相容,包括:

  • .prevent:阻止事件的預設行為(如阻止表單的預設提交)
  • .stop:阻止事件的進一步傳播(預設行為不會被阻止)
  • .capture:在捕獲階段觸發,從根元素開始向上
  • .self:僅在事件源和觸發元素相同時觸發
  • .passive:在觸控移動事件中,用於處理滾動,使事件在預設行為執行前觸發,常用於阻止滾動

例如:

<button @click.prevent="handleClick">阻止預設</button>

3.1.3 按鍵修飾符

  • .once:只觸發一次,然後移除事件監聽
  • .key:用於鍵盤事件,指定一個鍵值(如 EnterEsc)來監聽

例如:

<input @keyup.enter="handleEnter" />

在這個例子中,當使用者按下Enter鍵時,handleEnter 方法會被呼叫。

3.2 事件處理函式

在Vue 3中,事件處理函式是響應使用者互動的關鍵部分,它們可以以不同的形式存在,包括內聯事件處理器、方法事件處理器以及結合計算屬性和偵聽器。

3.2.1 內聯事件處理器

內聯事件處理器是指直接在模板中定義的JavaScript表示式,它們通常用於簡單的邏輯。例如:

<button @click="count++">增加計數</button>

在這個例子中,點選按鈕會直接增加count的值。

3.2.2 方法事件處理器

方法事件處理器是指在Vue元件的methods選項中定義的函式,這些函式可以處理更復雜的邏輯。例如:

export default {
  data() {
    return {
      count: 0,
    };
  },
  methods: {
    incrementCount() {
      this.count++;
    },
  },
};

在模板中使用:

<button @click="incrementCount">增加計數</button>

3.2.3 計算屬性與偵聽器

計算屬性和偵聽器也可以用於事件處理,尤其是在需要根據資料變化來更新檢視或執行某些操作時。

  • 計算屬性:計算屬性是基於它們的依賴進行快取的,只有當依賴變化時才會重新計算。例如:
export default {
  data() {
    return {
      firstName: 'John',
      lastName: 'Doe',
    };
  },
  computed: {
    fullName() {
      return `${this.firstName} ${this.lastName}`;
    },
  },
};

在模板中使用計算屬性:

<button @click="fullName = 'Jane Smith'">更改全名</button>

  • 偵聽器:偵聽器用於觀察和響應Vue例項上的資料變動。例如:
export default {
  data() {
    return {
      message: 'Hello',
    };
  },
  watch: {
    message(newVal, oldVal) {
      console.log(`Message changed from ${oldVal} to ${newVal}`);
    },
  },
};

在模板中觸發偵聽器:

<button @click="message = 'Hello, Vue 3'">更改訊息</button>

透過這些不同型別的事件處理函式,Vue 3提供了靈活且強大的工具來處理使用者互動和資料變化。

第4章 高階事件處理

在Vue中,高階事件處理技術包括使用事件匯流排、自定義事件和事件委託,這些技術可以幫助開發者更有效地管理元件間的通訊和事件處理。

4.1 事件匯流排

事件匯流排是一箇中央集線器,用於在非父子關係的元件之間傳遞事件。在Vue 2中,通常使用一個空的Vue例項作為事件匯流排。但在Vue 3中,推薦使用mitttiny-emitter等第三方庫,因為Vue 3移除了$on$off$once等例項方法。

使用事件匯流排的基本步驟如下:

  1. 建立事件匯流排:
import mitt from 'mitt';
export const emitter = mitt();

  1. 在傳送元件中觸發事件:
this.emitter.emit('eventName', data);

  1. 在接收元件中監聽事件:
this.emitter.on('eventName', this.handleEvent);

4.2 自定義事件

自定義事件是Vue中元件間通訊的另一種方式,特別是在父子元件之間。子元件可以使用$emit方法觸發一個自定義事件,父元件則透過在子元件標籤上使用v-on@來監聽這個事件。

示例:

子元件:

methods: {
  handleClick() {
    this.$emit('custom-event', '傳遞的資料');
  }
}

父元件:

<child-component @custom-event="handleCustomEvent"></child-component>

4.3 事件委託

事件委託是一種最佳化事件處理的技術,它利用事件冒泡機制,將事件處理器新增到父元素上,而不是每個子元素上。這樣可以減少記憶體消耗和提高效能,尤其是在有很多子元素需要監聽相同事件的情況下。
AD:專業搜尋引擎

在Vue中實現事件委託的示例:

<ul @click="handleClick">
  <li v-for="item in items" :key="item.id">{{ item.text }}</li>
</ul>

methods: {
  handleClick(event) {
    const target = event.target;
    if (target.tagName === 'LI') {
      // 處理點選事件
    }
  }
}

在這個例子中,handleClick方法會監聽<ul>元素上的點選事件,並透過檢查事件目標來確定是否是<li>元素被點選。這樣,無論有多少個<li>元素,都只需要一個事件處理器。

第5章 實戰案例

以下是一些Vue.js簡單實戰案例,涵蓋了表單處理、列表渲染與過濾、動態元件與非同步元件的應用。

5.1 表單處理

表單處理是前端應用中常見的需求,Vue提供了簡潔的方法來處理表單輸入。

<template>
  <div>
    <form @submit.prevent="submitForm">
      <input v-model="form.name" placeholder="Name">
      <input v-model="form.email" type="email" placeholder="Email">
      <button type="submit">Submit</button>
    </form>
  </div>
</template>

<script>
export default {
  data() {
    return {
      form: {
        name: '',
        email: ''
      }
    };
  },
  methods: {
    submitForm() {
      // 處理表單提交邏輯
      console.log('Name:', this.form.name);
      console.log('Email:', this.form.email);
    }
  }
};
</script>

5.2 列表渲染與過濾

列表渲染是Vue中的基礎功能,結合過濾器可以實現複雜的資料展示。

<template>
  <div>
    <input v-model="search" placeholder="Search">
    <ul>
      <li v-for="item in filteredList" :key="item.id">
        {{ item.name }}
      </li>
    </ul>
  </div>
</template>

<script>
export default {
  data() {
    return {
      search: '',
      items: [
        { id: 1, name: 'Apple' },
        { id: 2, name: 'Banana' },
        { id: 3, name: 'Cherry' },
        // 更多資料...
      ]
    };
  },
  computed: {
    filteredList() {
      return this.items.filter(item => item.name.includes(this.search));
    }
  }
};
</script>

5.3 動態元件與非同步元件

動態元件和非同步元件可以提高應用的靈活性和效能。

<template>
  <div>
    <button @click="component = 'ChildA'">切換到ChildA</button>
    <button @click="component = 'ChildB'">切換到ChildB</button>
    <component :is="component"></component>
  </div>
</template>

<script>
export default {
  data() {
    return {
      component: 'ChildA'
    };
  },
  components: {
    ChildA: { template: '<div>This is ChildA</div>' },
    ChildB: { template: '<div>This is ChildB</div>' }
  }
};
</script>

非同步元件的實現通常涉及到動態匯入:

components: {
  ChildA: () => import('./ChildA.vue'),
  ChildB: () => import('./ChildB.vue')
}

這樣,ChildA和ChildB元件會按需載入,從而提高應用的效能。

第6章 最佳實踐

在Vue.js開發中,遵循一些最佳實踐可以提高應用的效能、程式碼的可維護性和可測試性。以下是關於效能最佳化、程式碼組織與重用、測試與除錯的最佳實踐。AD:首頁 | 一個覆蓋廣泛主題工具的高效線上平臺

6.1 效能最佳化

  1. 使用v-if替代v-show:在需要頻繁切換顯示狀態時,使用v-ifv-show更高效。
  2. 合理使用計算屬性:對於複雜的資料處理,使用計算屬性可以減少重複計算,提高效能。
  3. 避免不必要的元件渲染:使用v-once指令可以渲染一次後不再更新,適用於靜態內容。
  4. 非同步元件和程式碼分割:使用非同步元件和Webpack的程式碼分割功能,可以按需載入元件,減少初始載入時間。
  5. 使用keep-alive快取元件:對於需要頻繁切換但資料不變的元件,使用<keep-alive>可以避免重複渲染。

6.2 程式碼組織與重用

  1. 元件化開發:將UI拆分為可重用的元件,每個元件負責特定的功能。
  2. 遵循單一職責原則:每個元件或模組應只負責一個功能,提高程式碼的可維護性和可測試性。
  3. 使用Mixins或Composition API:對於元件間的共享邏輯,可以使用Mixins或Vue 3的Composition API。
  4. 模組化管理狀態:使用Vuex或其他狀態管理工具來管理應用的狀態,確保狀態的可預測性和可維護性。
  5. 程式碼風格一致:遵循統一的程式碼風格和命名規範,提高程式碼的可讀性。

6.3 測試與除錯

  1. 單元測試:為元件和關鍵邏輯編寫單元測試,確保程式碼的正確性。可以使用Jest或Vue Test Utils等工具。
  2. 端到端測試:使用Cypress或Puppeteer等工具進行端到端測試,確保應用在真實環境中的表現符合預期。
  3. 使用Vue Devtools:利用Vue Devtools進行除錯,可以直觀地檢視元件樹、狀態和事件。
  4. 日誌和錯誤處理:在關鍵點新增日誌輸出,便於追蹤問題。使用try-catch處理可能的錯誤,提高應用的健壯性。
  5. 持續整合:將測試整合到持續整合流程中,確保每次程式碼提交都經過自動化測試。

相關文章