组件、自定义指令和自定义过滤器的注册

一、组件的注册

1、全局注册

1
2
import DemoComponent from "@/components/Democomponent";
Vue.component("my-component-name", DemoComponent);

第一个参数是组件名,第二个参数是导入的组件对象实例

定义组件名有两种方式

第一种使用短横线分隔命名。字母全小写,就像上面的例子一样。但是使用这种方式命名,在引用这个自定义元素时也必须使用使用短横线分隔命名,字母全小写的方式,就像这样 <my-component-name>

第二种使用大驼峰命名 (首字母大写命名) 。这种方式,在引用这个自定义元素时两种命名法都可以使用。也就是说 <my-component-name><MyComponentName> 都是可接受的。注意,尽管如此,直接在 DOM (即非字符串的模板) 中使用时只有第一种方式是有效的。

给予组件的名字可能依赖于打算拿它来做什么。当直接在 DOM 中使用一个组件 (而不是在字符串模板或单文件组件) 的时候,vue 官方强烈推荐遵循 W3C 规范中的自定义组件名 (字母全小写且必须包含一个连字符)。这会帮助你避免和当前以及未来的 HTML 元素相冲突。

2、局部注册

局部注册只需在组件中配置一个 components 配置项即可

1
2
import DemoComponent from './Democomponent' export default { components: {
DemoComponent } }

3、批量全局注册

如果有大量的通用组件需要全局注册,那么我们的 main.js 文件很可能会变成这样

1
2
3
4
5
6
7
8
9
10
import DemoComponentA from "@/components/DemocomponentA";
import DemoComponentB from "@/components/DemocomponentB";
import DemoComponentC from "@/components/DemocomponentC";
import DemoComponentD from "@/components/DemocomponentD";
import DemoComponentE from "@/components/DemocomponentE";
Vue.component("my-component-nameA", DemoComponentA);
Vue.component("my-component-nameB", DemoComponentB);
Vue.component("my-component-nameC", DemoComponentC);
Vue.component("my-component-nameD", DemoComponentD);
Vue.component("my-component-nameE", DemoComponentE);

为了保持 main.js 文件的简洁,我们可以将需要全局注册的通用组件统统放在一个单独的文件夹中,/src/components,在其中的 index.js 文件中将这些组件统一导入注册,再暴露出去交给 main.js 给 Vue 使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import PageTools from "./PageTools";
import UploadExcel from "./UploadExcel";
import ImageUpload from "./ImageUpload";
import ScreenFull from "./ScreenFull";
import ThemePicker from "./ThemePicker";
import Lang from "./Lang";
import TagsView from "./TagsView";

export default {
install(Vue) {
Vue.component("PageTools", PageTools);
Vue.component("UploadExcel", UploadExcel);
Vue.component("ImageUpload", ImageUpload);
Vue.component("ScreenFull", ScreenFull);
Vue.component("ThemePicker", ThemePicker);
Vue.component("Lang", Lang);
Vue.component("TagsView", TagsView);
},
};
1
2
import Components from "@/components";
Vue.use(Components); // 注册自己的自定义组件

二、自定义指令

1、全局注册

1
2
3
4
5
6
7
8
// 注册一个全局自定义指令 `v-focus`
Vue.directive('focus', {
// 当被绑定的元素插入到 DOM 中时……
inserted: function (el) {
// 聚焦元素
el.focus()
}
})

第一个参数是指令名,注意这里不需要带 v-

第二个参数是一个配置项。可以提供如下几个钩子函数 (均为可选):

  • bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
  • inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
  • update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。
  • componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。
  • unbind:只调用一次,指令与元素解绑时调用。

指令钩子函数会被传入以下参数:

  • el:指令所绑定的元素,可以用来直接操作 DOM。
  • binding:一个对象,包含以下 property:
    • name:指令名,不包括 v- 前缀。
    • value:指令的绑定值,例如:v-my-directive="1 + 1" 中,绑定值为 2
    • oldValue:指令绑定的前一个值,仅在 updatecomponentUpdated 钩子中可用。无论值是否改变都可用。
    • expression:字符串形式的指令表达式。例如 v-my-directive="1 + 1" 中,表达式为 "1 + 1"
    • arg:传给指令的参数,可选。例如 v-my-directive:foo 中,参数为 "foo"
    • modifiers:一个包含修饰符的对象。例如:v-my-directive.foo.bar 中,修饰符对象为 { foo: true, bar: true }
  • vnode:Vue 编译生成的虚拟节点。
  • oldVnode:上一个虚拟节点,仅在 updatecomponentUpdated 钩子中可用。

注意,除了 el 之外,其它参数都应该是只读的,切勿进行修改。如果需要在钩子之间共享数据,建议通过元素的 dataset 来进行。

2、局部注册

同样局部注册,只需配置组件中的一个 directives 配置项即可

1
2
export default { directives: { focus: { // 指令的定义 inserted: function (el) {
el.focus() } } } }

3、批量全局注册

同样如果有很多自定义指令需要全局注册,我们可以从 main.js 中分离出来单独处理。新建 src/directives/index.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// 负责管理所有的自定义指令
// 只负责导出指令对象
// 变量名称就是指令名称
export const imageerror = {
// 指令内容
// 指令作用在 图片上的 dom是图片对象
// inserted 在Vue3中也改名 => mounted
inserted(dom, options) {
// inserted执行的之后 此时 并没有对 src赋值
// 图片有地址 但是地址加载图片失败的时候 会执行一个函数 onerror
dom.src = dom.src || options.value;
dom.onerror = function () {
// 监听onerror事件
// options.value就是指令传过来的值
dom.src = options.value; // 当图片异常的时候 接收指令传过来的值 让这个值作为头像的备选
};
// 只有src有值 并且加载失败才会触发onerror
},
// 此钩子会在给image赋值之后执行
// 这个钩子函数在Vue3中改名了 => updated
componentUpdated(dom, options) {
dom.src = dom.src || options.value;
},
};

再在 main.js 中批量注册即可

1
2
3
4
5
6
import * as directives from "@/directives";
// directives是所有指令的一个集合
Object.keys(directives).forEach((key) => {
// key就是指令名称
Vue.directive(key, directives[key]);
});

三、过滤器

1、全局注册

1
2
3
4
5
Vue.filter("capitalize", function (value) {
if (!value) return "";
value = value.toString();
return value.charAt(0).toUpperCase() + value.slice(1);
});

第一个参数是过滤器的名称,第二个参数是一个函数,通常是一些处理文本格式化的操作。

2、局部注册

同样局部注册,只需配置组件中的一个 filters 配置项即可

1
2
3
export default { filters: { capitalize: function (value) { if (!value) return ''
value = value.toString() return value.charAt(0).toUpperCase() + value.slice(1) }
} }

使用时放在 JavaScript 表达式的尾部,由“管道”符号指示即可

3、全局批量注册

同样如果有很多过滤器需要全局注册,我们可以从 main.js 中分离出来单独处理。新建 src/filters/index.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
function pluralize(time, label) {
if (time === 1) {
return time + label;
}
return time + label + "s";
}

export function timeAgo(time) {
const between = Date.now() / 1000 - Number(time);
if (between < 3600) {
return pluralize(~~(between / 60), " minute");
} else if (between < 86400) {
return pluralize(~~(between / 3600), " hour");
} else {
return pluralize(~~(between / 86400), " day");
}
}
export function numberFormatter(num, digits) {
const si = [
{ value: 1e18, symbol: "E" },
{ value: 1e15, symbol: "P" },
{ value: 1e12, symbol: "T" },
{ value: 1e9, symbol: "G" },
{ value: 1e6, symbol: "M" },
{ value: 1e3, symbol: "k" },
];
for (let i = 0; i < si.length; i++) {
if (num >= si[i].value) {
return (
(num / si[i].value)
.toFixed(digits)
.replace(/\.0+$|(\.[0-9]*[1-9])0+$/, "$1") + si[i].symbol
);
}
}
return num.toString();
}

在 main.js 中批量注册

1
2
3
4
import * as filters from "@/filters";
Object.keys(filters).forEach((key) => {
Vue.filter(key, filters[key]);
});
  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!
  • Copyrights © 2023-2025 congtianfeng
  • 访问人数: | 浏览次数: