Bob's Blog

Web开发、测试框架、自动化平台、APP开发、机器学习等

返回上页首页

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>&emsp;{{ 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/

下一篇:  手机app性能测试工具之PerfDog
上一篇:  Django通过haystack搜索文章

共有0条评论

添加评论

暂无评论