vue3-ts项目练习
项目是对一些vue3新语法的使用,以及对ts的使用,基本都是一些常用逻辑,主要学习了一些组件的封装, 以及将一些逻辑封装成hooks。自己来实现一些常见ui库的一些组件。
1.axios封装
axios.defaults.baseURL = "/api/api/"; //配置默认url
// 对请求做封装,请求的时候加载loading组件,响应的时候关闭,收集错误的响应信息。 axios.interceptors.request.use((config) => { store.commit("setLoading", true); store.commit("setError", { status: false, message: "" }); return config; }); axios.interceptors.response.use( (config) => { store.commit("setLoading", false); return config; }, (e) => { console.log(e.response); const { error } = e.response.data; store.commit("setError", { status: true, message: error }); store.commit("setLoading", false); return Promise.reject(error); } );
2.router,store的使用
import { useRouter } from "vue-router";
import { useStore } from "vuex";
const router = useRouter();
const store = useStore();
3.权限认证,可以在路由的meta里面添加对应信息,在route.beforeEach中添加相应的权限认证。
const route = createRouter({
history: routerHistory,
routes: [
{
path: "/",
name: "home",
component: Home,
},
{
path: "/login",
name: "login",
component: Login,
meta: { redirectAlreadyLogin: true },
}
]
})
4.setup中有两个参数,props,context
props为父组件传的参数,context中包含attrs 、 emit 、slots
5.封装一些组件,封装前想好可能的参数,自定义部分用slot来实现,将需要自定义的部分尽量细分。
6.drowdown组件的封装。
<dropdown :title="`你好 ${user.nickName}`">
<dropdown-item
><a class="dropdown-item" href="#" @click.prevent="toCreate"
>新建文章</a
></dropdown-item
>
<dropdown-item :disabled="true"
><a class="dropdown-item" href="#">编辑资料</a></dropdown-item
>
<dropdown-item
><a class="dropdown-item" href="#" @click="logout"
>退出登陆</a
></dropdown-item
>
</dropdown>
内部实现:dropdown中展示一个title,以及一个ul,ul中用slot来留给dropdown-item。
<div class="dropdown" ref="drowDownRef">
<a
href="#"
class="btn btn-outline-light my-2 dropdown-toggle"
@click.prevent="toggleOpen"
>
{{ title }}
</a>
<ul class="dropdown-menu" :style="{ display: 'block' }" v-if="isOpen">
<slot></slot>
</ul>
</div>
dropdown-item,外层用li,里面用slot自由发挥
<li class="dropdown-option" :class="{ 'is-disabled': disabled }">
<slot></slot>
</li>
判断当鼠标点击下拉框外部的时候下拉框关闭:点击处于非下拉框&&下拉框打开。
import { ref, onMounted, onUnmounted, Ref } from "vue";
const useClickOutSide = (elementRef: Ref<null | HTMLElement>) => {
const isClickOutSide = ref(false);
const handler = (e: MouseEvent) => {
if (elementRef.value) {
if (!elementRef.value.contains(e.target as HTMLElement)) {
isClickOutSide.value = false;
} else {
isClickOutSide.value = true;
}
}
};
onMounted(() => {
document.addEventListener("click", handler);
});
onUnmounted(() => {
document.removeEventListener("click", handler);
});
return isClickOutSide;
};
export default useClickOutSide;
7.用teleport,封装一个最外层的loading组件
8.validateForm的封装,表单验证组件,分成表单及详细的input框,textarea框
validateForm
<form class="validate-form-container">
<slot name="default"></slot>
<div class="submit-area" @click.prevent="submitForm">
<slot name="submit">
<button type="submit" class="btn btn-primary">提交</button>
</slot>
</div>
</form>
validateInput
<input
v-if="tag !== 'textarea'"
class="form-control"
:class="{ 'is-invalid': inputRef.error }"
@blur="validateInput"
:value="inputRef.val"
@input="updateValue"
v-bind="$attrs"
/>
<textarea
v-else
class="form-control"
:class="{ 'is-invalid': inputRef.error }"
@blur="validateInput"
:value="inputRef.val"
@input="updateValue"
v-bind="$attrs"
></textarea>
<span v-if="inputRef.error" class="invalid-feedback">{{
inputRef.message
}}</span>
9.以及上传组件,消息框组件
10.封装路由导航hooks
// import { useRouter, RouteParamsRaw } from "vue-router";
import Vrouter, { RouteParamsRaw } from "vue-router";
const router = Vrouter;
export default function useNavigate(
route: string,
params?: RouteParamsRaw
): void {
router.push({
name: route,
params,
});
}

浙公网安备 33010602011771号