一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第3天,点击查看活动详情。
序
基于工作上Vue项目的一些技巧总结,主观性会比较强,或许对你有帮助。
持续更新中
Composition API
的实用技巧
reactive
和toRefs
配合使用
Vue2
中使用data属性声明的变量可以直接使用,在Vue3
中如果使用reactive
声明响应式对象states
,在template
模板中需要打点调用属性,如{{ states.name }}
当然你也可以使用展开运算符,返回{ ...states }
,但这会让属性失去响应性
因此需要toRefs
配合使用
<script lang="ts">
import { defineComponent, reactive, toRefs } from "vue";
export default defineComponent({
setup() {
const state = reactive({
label: "hello"
});
setTimeout(() => {
state.label = "111";
}, 1000);
return {
...toRefs(state)
};
}
});
</script>
<template>{{ label }}</template>
此实践技巧仅适合在setup函数中使用
props
和toRefs
配合使用
和上面的例子差别不大,这里需要注意props
中的属性值不要和reacitve
中的属性值重名
props
需要先声明类型,才可以使用
<script lang="ts">
import { defineComponent, toRefs } from "vue";
export default defineComponent({
name: "TextComponents",
props: {
msg: {
type: String,
default: "hello"
}
},
setup(props) {
return {
...toRefs(props)
};
}
});
</script>
<template>
<div>{{ msg }}</div>
</template>
此实践技巧仅适合在setup函数中使用
自动注册Vue
全局组件
由于webpack
和vite
注册Vue
全局组件的方式不尽相同,因此分开两个版本说明
webpack
版本
webpack
的环境下,可以使用require.context
方法获取所需全局注册的vue
组件
require.context在webpack
官网的详细说明
首先在component
文件夹新建index.js
文件,使用require.context
获取vue
文件
const componentList = require.context(
// 其组件目录的相对路径
'../components',
// 是否查询其子目录
true,
// 匹配vue后缀文件名的文件
/.vue$/
)
然后使用install
方法,vue
注册全局组件
需要注意的是组件名称,可以是文件名,也可以是vue
文件的name
属性
这里以name
属性为例,如name:"inputComponent"
,可以在template
这样使用<input-component />
const autoRegist = {
install(app) {
componentList.keys().forEach((path) => {
const file = components(path).default
const fileName = file.name
app.component(fileName, file || components(path))
})
}
}
export default autoRegist
最后需要在main.js
使用
import autoRegist from './components'
app.use(autoRegist)
vite
版本
vite
中的操作和webpack
差不多,也是获取vue
文件,然后注册组件
主要用到的方法是import.meta.glob
和globEager
,区别是同步还是异步
详细内容可以到vite官网查看相关信息
异步注册全局组件,需要调用vue
中的defineAsyncComponent
import { defineAsyncComponent } from "vue";
const componentList = import.meta.glob("@/components/*.vue");
const autoRegist = {
install(app) {
for (const [key, value] of Object.entries(componentList)) {
const name = key.slice(key.lastIndexOf("/") + 1, key.lastIndexOf("."));
app.component(name, defineAsyncComponent(value));
}
}
};
export default autoRegist;
本次组件名称选择截取文件名称的方法
如文件名是selectComponent,则可以可以在template
这样使用<select-component />
同步注册全局组件则需要修改部分内容,如下
const componentList = import.meta.glob("@/components/*.vue");
app.component(name, value);
最后在main.js
使用即可
import autoRegist from "./components";
app.use(autoRegist);
自定义指令
判断权限的自定义指令v-permission
已Vue3
的自定义指令为例
依旧是获取权限数组,根据传入的权限字符串,判断是否移除节点,具体代码如下
import { DirectiveBinding, VNode } from "vue";
const permissionList = ["add", "update"];
export default {
mounted(el: HTMLElement, binding: DirectiveBinding, vnode: VNode, prevVnode: VNode | null) {
const isHas = permissionList.includes(binding.value);
if (!isHas) {
el.parentNode && el.parentNode.removeChild(el);
}
}
};
具体使用如下
<template>
<div>
premission
<div v-permission="'add'">有权限</div>
<div v-permission="false">无权限</div>
</div>
</template>
可根据需求优化代码,比如传值必须是字符串,否则有报错提示,可传数组,判断多个权限亦可
自动注册全局自定义指令
基本与自动注册Vue
全局组件一样,套路还是获取自定义指令js
文件,然后遍历文件,
调用vue
注册全局自定义指令即可
以vite
环境为例
需要注意的是,可能会把index.js
文件都获取到,需要把它去除
import { App } from "vue";
const directivesList = import.meta.globEager("@/directives/*.ts");
const autoRegist = {
install(app: App) {
for (const [key, value] of Object.entries(directivesList)) {
const name = key.slice(key.lastIndexOf("/") + 1, key.lastIndexOf("."));
app.directive(name, value.default);
console.log(directivesList);
}
}
};
export default autoRegist;
在main.js
文件中使用
import autoRegistDirectives from "./directives";
app.use(autoRegistDirectives);
mixin
的使用
如果项目使用Vue2,有大量重复代码,可以考虑使用mixin
建议每个页面只用一个mixin
,项目中mixin
最好不要超过3个
当项目中有大量的curd页面,可以把重复代码抽离到mixin
当中,比如表格数据,翻页相关的数据等
export default {
data() {
return {
tableData: [], // 数据列表
page: 1, // 当前页码
limit: 15, // 每页数
total: 0, // 总条数
loading: false, // loading状态
addOrUpdateVisible: false, // 新增/更新弹窗visible状态
};
},
methods: {
// 分页
handleChangePage(val) {
this.page = val;
this.findPage();
},
},
};
<template>
<div class="home" @click="handleChangePage(1)">
{{ tableData }}
</div>
</template>
<script>
import useMixin from "../mixin/useMixin";
export default {
name: "demo",
mixins: [useMixin],
methods: {
findPage() {
console.log("findPage");
},
},
};
</script>
以上就是mixin
的例子,可以在调用的页面,直接调用里面的变量和事件
需要注意的是调用页面与mixin
中同名的,会覆盖mixin
变量或事件
待更新