此项目一套开箱即用的中后台前端框架,这个项目就从 0 到 1 实现
vue create vue-public-ui
ui 组件库
日期处理库
配置 ant-design-vue
引入组件,全局注册
main.js
引入 antd 的样式
main.js
此时延申的一个问题,我们自定义项目配置时,需要遵循 vue-cli 标准,所以我们去看一下 vue-cli 中怎么配置 less 的 loader
vue.config.js
module.exports = {
css: {
loaderOptions: {
less: {
javascriptEnabled: true // 重点是这句
}
}
}
}
// 配置完需要重启,因为我们修改的是配置
// 至此,我们可以全局使用antd组件了
比如我们使用了 ant-design-vue 这个 ui 库,这个库本身体积很大,但我们项目中或许只用了 button,那么将所有的资源加载下来是很笨重的,但是每个地方用到了再去引入也很繁琐,所以我们采用按需加载策略
注意看官网:https://www.antdv.com/docs/vue/use-with-vue-cli-cn/
安装按需加载 babel
根据官网提示
babel.config.js
plugins: [
[
'import',
{ libraryName: 'ant-design-vue', libraryDirectory: 'es', style: true }
]
]
main.js
// 此时通过以上配置我们直接可以引入我们需要的组件类型
import { Button } from 'ant-design-vue'
// 修改了配置项,记得重启
router>index.js
// 采用复合组合路由形式
path: "/user",
component: { render: h => h("router-view") }, // 重点解释这一句,这里通过render函数将路由页面渲染。
// 但是思考问题,很多情况下登录页和注册页长得很像,那这公共的部分不想重复写的话怎么处理好?
children: [
{
path: "/user/login",
name: "login",
component: () => {
return import(
/* webpackChunkName: "user" */ "../views/User/Login.vue" // 解释一下注释部分:说白了就是告诉webpack将这个代码打包到user代码块中,业务聚合
);
}
},
{
path: "/user/register",
name: "register",
component: () => {
return import(
/* webpackChunkName: "user" */ "../views/User/Register.vue"
);
}
}
]
},
-解决问题:解决背景公共布局的问题
UserLayout.vue
<template>
<div class="user-layout">
<div class="desc">vue-public-ui</div>
<router-view></router-view>
</div>
</template>
<script>
export default {
data() {
return {};
}
};
</script>
<style lang="less" scoped></style>
router>index.js
// 采用复合组合路由形式
path: "/user",
component: () => {
return import(
/* webpackChunkName: "user" */ "../Layout/UserLayout.vue" //使用布局也
);
},
children: [
{
path: "/user/login",
name: "login",
component: () => {
return import(
/* webpackChunkName: "user" */ "../views/User/Login.vue" // 解释一下注释部分:说白了就是告诉webpack将这个代码打包到user代码块中,业务聚合
);
}
},
{
path: "/user/register",
name: "register",
component: () => {
return import(
/* webpackChunkName: "user" */ "../views/User/Register.vue"
);
}
}
]
},
// 采用复合组合路由形式
path: "/user",
component: () => {
return import(
/* webpackChunkName: "user" */ "../Layout/UserLayout.vue" //使用布局也
);
},
children: [
{
path:"/user",
retdirect:'/user/login' // 页面重定向
},
{
path: "/user/login",
name: "login",
component: () => {
return import(
/* webpackChunkName: "user" */ "../views/User/Login.vue" // 解释一下注释部分:说白了就是告诉webpack将这个代码打包到user代码块中,业务聚合
);
}
},
{
path: "/user/register",
name: "register",
component: () => {
return import(
/* webpackChunkName: "user" */ "../views/User/Register.vue"
);
}
}
]
},
router>index.js
import NotFond from "@/views/404";
// 404页面
{
path: "*",
name: "404",
component: NotFond
}
router>index.js
router.beforeEach((to, from, next) => {
// 路由切换时,出现进度条,提高交互体验
NProgress.start()
next()
})
router.afterEach((to, from, next) => {
NProgress.done()
next()
})
vsCode-> 应用商店-> Ant Deisign Vue helper
解决的问题
使用步骤
// 根据文档插槽指向handle
<template v-slot:handle>
<div class="handle" @click="visible = !visible">
// 使用一个icon作为标志
<a-icon :type="visible ? 'close' : 'setting'"></a-icon>
</div>
</template>
.handle {
position: absolute;
top: 300px;
right: 268px;
background-color: saddlebrown;
height: 40px;
width: 40px;
line-height: 40px;
text-align: center;
background-color: #1890ff;
border-radius: 5px;
color: white;
}
<a-drawer
:placement="placement"
:closable="false"
@close="onClose"
:visible="visible"
>
<template v-slot:handle>
<div class="handle" @click="visible = !visible">
<a-icon :type="visible ? 'close' : 'setting'">a-icon>
div>
template>
<div>
<h2>整体风格设置h2>
<a-radio-group
@change="e => handleSettingChange('navTheme', e.target.value)"
:value="this.$route.query.navTheme || 'dark'"
>
<a-radio value="dark">黑色a-radio>
<a-radio value="white">白色a-radio>
a-radio-group>
<h2>导航模式h2>
<a-radio-group
@change="e => handleSettingChange('navLayout', e.target.value)"
:value="this.$route.query.navLayout || 'left'"
>
<a-radio value="left">左侧a-radio>
<a-radio value="top">顶部a-radio>
a-radio-group>
div>
a-drawer>
handleSettingChange(type, value) {
console.log('类型', type)
console.log('类型', value)
this.$router.push({ query: { ...this.$route.query, [type]: value } }) // 通知路由风格设计
}
Layouts->BasicLayout.vue
// 通过路由来判断用户设置的全局皮肤数据
computed: {
navTheme() {
return this.$route.query.navTheme || 'dark'
},
navLayout() {
return this.$route.query.navLayout || 'left'
}
}
<template>
<div :class="[`nav-theme-${navTheme}`, `nav-layout-${navLayout}`]">div>
template>
<a-layout-sider
:theme="navTheme"
v-if="navLayout === 'left'"
:trigger="null"
collapsible
v-model="collapsed"
>
a-layout-sider>
// 确保在切换主题的时候,文字相关的可以不受影响
.nav-theme-dark .logo {
color: #ffffff;
}
// 路由守卫
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})
router.beforeEach((to, from, next) => {
// 只有在路由地址发生变化时触发进度条
if (to.path != from.path) {
NProgress.start()
}
next()
})
router.afterEach(() => {
NProgress.done()
})