vue3組件化開發之可複用性的應用

語言: CN / TW / HK

theme: vue-pro highlight: a11y-dark


持續創作,加速成長!這是我參與「掘金日新計劃 · 6 月更文挑戰」的第6天,點擊查看活動詳情

可複用性也是組件化開發的一個優勢,能讓代碼更加簡潔優雅、方便維護。下面主要寫了vue3中能體現出複用性的一些API的應用。

自定義指令

指令 (Directives) 是帶有 v- 前綴的特殊 attribute。

v-text v-show v-if ... 等是 vue 中內置的一些指令,當這些內置指令無法滿足我們的要求時,這時候也可以使用自定義指令

基本結構

js const app = Vue.createApp({}) // 註冊一個全局自定義指令 app.directive('loading', { mounted(el, binding) {}, updated(el, binding) {}, // ... }) 一個自定義指令對象可以提供以下的鈎子函數

  • created:在綁定元素的 attribute 或事件監聽器被應用之前調用。在指令需要附加在普通的 v-on 事件監聽器調用前的事件監聽器中時,這很有用。
  • beforeMount:當指令第一次綁定到元素並且在掛載父組件之前調用。
  • mounted:在綁定元素的父組件被掛載後調用。
  • beforeUpdate:在更新包含組件的 VNode 之前調用。
  • updated:在包含組件的 VNode 及其子組件的 VNode 更新後調用。
  • beforeUnmount:在卸載綁定元素的父組件之前調用
  • unmounted:當指令與元素解除綁定且父組件已卸載時,只調用一次。

鈎子函數的一些參數

包含兩個參數elbindingel 為指令綁定到的元素。這可用於直接操作 DOM。binding包含以下對象:

  • instance:使用指令的組件實例。
  • value:傳遞給指令的值。例如,在 v-my-directive="1 + 1" 中,該值為 2
  • oldValue:先前的值,僅在 beforeUpdate 和 updated 中可用。無論值是否有更改都可用。
  • arg:傳遞給指令的參數(如果有的話)。例如在 v-my-directive:foo 中,arg 為 "foo"
  • modifiers:包含修飾符(如果有的話) 的對象。例如在 v-my-directive.foo.bar 中,修飾符對象為 {foo: true,bar: true}
  • dir:一個對象,在註冊指令時作為參數傳遞。

動態指令傳遞參數

js v-mydir:[t]="val" //傳遞了t參數

t的值可以通過鈎子函數的參數binding.arg獲取到,val的值 通過binding.value獲取到。

自定義 v-loading 指令

先編寫一個LoadingIcon.vue組件,內容是加載中的樣式。

```js

```

創建一個js文件src/directives/loading.js,導出自定義指令的對象:

```js export default { mounted(el, binding) { // 插入元素 const app = createApp(LoadingIcon); const instance = app.mount(document.createElement("div")); el.instance = instance; el.appendChild(el.instance.$el);

    el.style.position = "relative";
},
updated(el, binding) {

},

}; ```

根據用户傳給指令的參數,動態設置提示文字:

js mounted(el, binding){ // ... // 提示文字 if (binding.arg) { el.instance.tips = binding.arg; } }

指令綁定的值變化時,設置顯示或隱藏loading:

js updated(el, binding) { if (!binding.value) { el.removeChild(el.instance.$el); } else { el.appendChild(el.instance.$el); } }, 全局註冊自定義指令:

```js const app = createApp(App);

import loading from "./directives/loading.js"; app.directive("loading",loading); ```

使用 v-loading 指令:

```js

```

插件

插件是自包含的代碼,通常向 Vue 添加全局級功能。它可以是公開 install() 方法的 object,也可以是 function

每當插件被添加到應用程序中時,如果它是一個對象,就會調用 install 方法。如果它是一個 function,則函數本身將被調用。在這兩種情況下,它都會收到兩個參數:由 Vue 的 createApp 生成的 app 對象和用户傳入的選項。

基本結構

導出一個對象,裏面包含 install 方法。 js export default { install: (app, options) => { // ... } }

使用插件

在使用 createApp() 初始化 Vue 應用程序後,通過調用 use() 方法將插件添加到應用程序中。

```js const app = createApp(App);

app.use(plugin); ```

實現一個全局狀態管理插件

在小型項目中,使用vuex 全局狀態管理工具,容易讓代碼變得宂餘複雜,那如果還需要全局的狀態管理,這時候就可以自己通過插件的方式實現一個mini版本的全局狀態管理。

新建minstore.js

```js import { reactive } from 'vue';

const state = reactive({ str: '字符串', });

const minstore = { state, };

export default { install: (app) => { app.provide('minstore', minstore); }, }; ```

main.js安裝這個插件:

```js import minstore from './minstore/minstore.js';

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

組件中使用minstore

js const minstore = inject('minstore'); console.log(minstore.state); ```html

{{ minstore.state.str }}

```

Teleport 傳送

先來看一個案例:

html <div style="position: relative;"> <div class="model" style="position:absolute">模態框</div> </div>

內層模態框的定位,是相對於父級的,如果想讓它相對於body定位在全局彈出模態框的話,實現起來可能很麻煩。

Teleport 提供了一種乾淨的方法,允許我們控制在 DOM 中哪個父節點下渲染了 HTML。

使用 <teleport>to 屬性,讓Vue “將這個 HTML 傳送body標籤下。

js <div style="position: relative;"> <teleport to='body'> <div v-show="showModel" class="model" style="position:absolute">模態框</div> </teleport> </div>

此時,HTML被插入到body標籤下,模態框的定位就相對於body標籤。

相關鏈接

vue3組件化開發常用API

代碼demo地址 http://github.com/kongcodes/vue3study

從0開始vue3項目搭建