Django restframework加Vue打造前后端分离的网站(十)美化界面
在前面的样例中,已经有一个界面可以查看项目和登陆,不过这个界面实在是太简陋了,于是在这篇文章里会记录如何通过UI组件来美化界面。
类似该博客网站,除了自定义的html和css,我用了bootstrap4来完成外观,因为bootstrap已经定义了很多风格和界面样式,而且能帮助我建立响应式布局和移动设备的适配。使用vue时也可以用bootstrap:https://bootstrap-vue.js.org/
不过我打算用ant-design-vue: https://www.antdv.com/docs/vue/introduce/
因为按照antd的说明,它提炼自企业级中后台产品的交互语言和视觉风格,而我目前想做的类似一个管理系统,两者比较相符,也当作尝试新的工具。
安装使用
先安装ant-design-vue
npm install ant-design-vue --save
修改src/main.js,添加如下以引入ant-design-vue
import Antd from 'ant-design-vue'
import 'ant-design-vue/dist/antd.css'
Vue.use(Antd)
然后在原先的home.vue中新增一句,加一个antd的button
<button type="button" @click='getProjects' :style="{ margin: '10px', padding: '5px' }">get projects</button>
<a-button type="primary">Button</a-button> // add here
此时运行npm run dev便可看到两种button的对比
图标使用
另外我们仍然可以使用font-awesome的图标https://github.com/FortAwesome/vue-fontawesome,先安装
npm i --save @fortawesome/fontawesome-svg-core
npm i --save @fortawesome/free-solid-svg-icons
npm i --save @fortawesome/vue-fontawesome
# 为了使用更多免费图标,还可以安装
npm i --save @fortawesome/free-brands-svg-icons
npm i --save @fortawesome/free-regular-svg-icons
在src/main.js中添加引用
import { library } from '@fortawesome/fontawesome-svg-core'
import { faChartArea } from '@fortawesome/free-solid-svg-icons'
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
library.add(faChartArea)
Vue.component('font-awesome-icon', FontAwesomeIcon)
然后在app.vue中添加一个图标,便能看到如下图的效果,之后便可使用font-awesome里的免费图标
<font-awesome-icon icon="chart-area" size="3x" inverse />
当然也可以使用ant-design-vue自带的图标,比如
<span slot="title"><a-icon type="setting" /><span>Settings</span></span>
主题定制
ant-design-vue中有dark和light两种主题,分别对应着不同的背景色和高亮色等;我们也可以根据自己的需要定制主题。
官方有文档:https://www.antdv.com/docs/vue/customize-theme-cn/
不过我自己试过后发现会有一点不一样。
我是用vue-cli 2创建的项目,于是修改build/utils.js,替换如下内容,改成自己的主色编号。(其他的定制则一样的修改其他的参数)
return {
....
// less: generateLoaders('less'), //注释这里
less: generateLoaders('less', {
modifyVars: {
// 类似于修改如下参数
'primary-color': '#2F4F4F',
'link-color': '#fff',
'border-radius-base': '2px',
},
javascriptEnabled: true,
}),
....
}
但是修改后发现并没有生效。查阅资料后发现在main.js里引用的antd.css要改成antd.less。
// import 'ant-design-vue/dist/antd.css'
import 'ant-design-vue/dist/antd.less'
并安装less,less-loader
npm i --save less less-loader
重新运行npm run dev后便能看到新效果了。
样例
我加上了预设的sider,header,footer,之后再加上对应的功能,添加页面内容即可。如下图和代码。
<template>
<div id="app">
<a-layout>
<a-layout-sider breakpoint="lg" collapsedWidth="0" @collapse="onCollapse" @breakpoint="onBreakpoint" style="background: #2F4F4F;">
<div class="logo">
<router-link to="/">
<font-awesome-icon icon="chart-area" size="3x" inverse />
<!--<font-awesome-icon :icon="['fab', 'autoprefixer']" size="3x" inverse />-->
<h3 style="color: #fff; margin: 10px;">Automation Center</h3>
</router-link>
</div>
<hr style="width: 90%;">
<a-menu mode="inline" :openKeys="openKeys" @openChange="onOpenChange" style="background: #2F4F4F; color: #fff;">
<a-sub-menu key="sub1">
<span slot="title"><a-icon type="project" /><span>Projects</span></span>
<a-menu-item key="1">ByBlog</a-menu-item>
<a-menu-item key="2">MobileSTF</a-menu-item>
<a-menu-item key="3">RestAPI</a-menu-item>
</a-sub-menu>
<a-sub-menu key="sub2">
<span slot="title"><a-icon type="setting" /><span>Settings</span></span>
<a-menu-item key="1">Projects</a-menu-item>
<a-menu-item key="2">Users</a-menu-item>
</a-sub-menu>
</a-menu>
</a-layout-sider>
<a-layout>
<a-affix style="height: 64px">
<a-layout-header style="background: #fff; border-bottom: 1px solid #e8e8e8;">
<a-input-search placeholder="input keyword..." @search="onSearch" enterButton style="width: 40%; margin: 15px 0px; float: left;" />
<div id="header-right" style="float: right;">
<font-awesome-layers class="fa-fw fa-1x">
<font-awesome-icon :icon="[ 'fas', 'bell' ]" />
<font-awesome-layers class="fa-layers-counter fa-layers-top-right">{{ notifications }}</font-awesome-layers>
</font-awesome-layers> {{ notifications }}
<a-divider type="vertical" />
Bob Jiang
<img src="./assets/niming-no-gender.png" style="margin: 5px; width: 30px; height: 30px; border-radius: 50%;">
</div>
</a-layout-header>
</a-affix>
<a-layout-footer style="text-align: center">
{{ fullCopyRight }}
</a-layout-footer>
</a-layout>
</a-layout>
<router-view/>
</div>
</template>
<script>
export default {
name: 'App',
data() {
return {
rootSubmenuKeys: ['sub1', 'sub2'],
openKeys: ['sub1'],
notifications: 3,
copyRightPrefix: "Copyright © ",
copyRightSuffix: " BobJiang | byincd.com"
};
},
created: function() {
this.$http.interceptors.response.use(
response => {
return response;
},
error => {
if (error.response) {
switch (error.response.status) {
case 401:
// 返回 401 清除token信息并跳转到登录页面
console.log('unauthorized or expired, Please login first')
this.$store.dispatch('logout');
this.$router.replace({
path: 'login',
query: {redirect: this.$router.currentRoute.fullPath}
})
}
}
return Promise.reject(error.response.data) // 返回接口返回的错误信息
});
},
methods: {
onCollapse(collapsed, type) {
console.log(collapsed, type);
},
onBreakpoint(broken) {
console.log(broken);
},
onOpenChange(openKeys) {
const latestOpenKey = openKeys.find(key => this.openKeys.indexOf(key) === -1);
if (this.rootSubmenuKeys.indexOf(latestOpenKey) === -1) {
this.openKeys = openKeys;
} else {
this.openKeys = latestOpenKey ? [latestOpenKey] : [];
}
},
onSearch(value) {
console.log(value);
},
},
computed: {
fullCopyRight: function(){
return this.copyRightPrefix + new Date().getFullYear() + this.copyRightSuffix;
}
}
}
</script>
<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
}
.logo {
margin: 10px 5px;
}
.ant-menu {
text-align: left;
}
</style>
参考:
https://blog.logrocket.com/full-guide-to-using-font-awesome-icons-in-vue-js-apps-5574c74d9b2d/