自定义指令

局部指令 只能在组件内部使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<template>
<input type="text" name="" id="" v-focus />
</template>

<script>
export default {
directives: {
focus: {
mounted(el) {
// console.log(el);
el.focus();
},
},
},
};
</script>

<style scoped></style>

Vue3

1
2
3
4
5
6
7
8
<script setup>
// 必须v开头
const vFocus = {
mounted(el) {
el.focus();
},
};
</script>

全局指令

main.js

1
2
3
4
5
6
7
8
9
import { createApp } from "vue";
import App from "./01_自定义指令/App.vue";
import "./assets/main.css";
import useDirective from "./directives";

const app = createApp(App);
useDirective(app);
app.mount("#app");

src/directives

1
2
3
4
5
6
7
8
9
10
11
12
13
import focusDirective from "./focus";
export default function useDirective(app) {
focusDirective(app);
// 其他自定义指令
// focusDirective(app);
// focusDirective(app);
// focusDirective(app);
// focusDirective(app);
// focusDirective(app);
// focusDirective(app);
}


1
2
3
4
5
6
7
export default function focusDirective(app) {
app.directive("focus", {
mounted(el) {
el.focus();
},
});
}

为什么这样的结构:main.js 不要存在过多逻辑

自定义指令的生命周期

8 个生命周期除了 beforeCreate

参数修饰符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<template>
<input type="text" name="" id="" v-focus:title.abc="'修改'" />
</template>

const vFocus = {
mounted(el, bindings) {
console.log(bindings);
// title
console.log(bindings.arg);
// 修改
console.log(bindings.value);
// {abc:true}
console.log(bindings.modifiers);
el.focus();
},
};

Teleport

是一个 Vue 提供的内置组件,类似于 react 的 Portals;

teleport 翻译过来是心灵传输、远距离运输的意思;

它有两个属性:

  • to:指定将其中的内容移动到的目标元素,可以使用选择器;
  • disabled:是否禁用 teleport 的功能

作用:改变组件挂载位置

1
2
3
4
<template>
<teleport to="body"><hello-world /></teleport>
<input type="text" name="" id="" v-focus:title.abc="'修改'" />
</template>

可以看到组件被挂载到了 body 上

多个 teleport 应用到同一个目标上(to 的值相同),那么这些目标会进行合并:

Suspense

Suspense 是一个内置的全局组件,该组件有两个插槽:

  • default:如果 default 可以显示,那么显示 default 的内容
  • fallback:如果 default 无法显示,那么会显示 fallback 插槽的内容

配合异步组件使用

1
2
3
4
5
6
7
8
9
10
<suspense>
<template #default><async-home /></template>
</suspense>
<suspense>
<template #fallback><h2>Loading</h2></template>
</suspense>


const AsyncHome = defineAsyncComponent(() => import("./AsyncHome.vue"));

自定义插件

两种编写方式:

  • 对象类型:一个对象,但是必须包含一个 install 的函数,该函数会在安装插件时执行
1
2
3
4
5
6
app.use({
install: (app) => {
console.log(app);
},
});

  • 函数类型:一个 function,这个函数会在安装插件时自动执行
1
app.use((app) => console.log(app));

插件可以完成的功能没有限制,比如下面的几种都是可以的:

  • 添加全局方法或者 property,通过把它们添加到 config.globalProperties 上实现;
  • 添加全局资源:指令/过滤器/过渡等
  • 通过全局 mixin 来添加一些组件选项
  • 一个库,提供自己的 API,同时提供上面提到的一个或多个功能

比如上面的自定义指令

1
2
3
4
5
6
7
8
9
10
11
12
13
useDirective(app);

export default function useDirective(app) {
focusDirective(app);
// 其他自定义指令
// focusDirective(app);
// focusDirective(app);
// focusDirective(app);
// focusDirective(app);
// focusDirective(app);
// focusDirective(app);
}

可以修改为

1
createApp(App).use(useDirective).mount("#app");