1. Vue scaffolding

NPM install -g vue-cli vue init Webpack VueDemo CD VueDemo NPM install NPM run dev Production environment Package release (Webpack package) NPM run build Use static server tool package: NPM install -g serve Serve Disthttp://localhost:5000
Copy the code

New vue. Config. Js

module.exports = {
  pages: {index: {entry:'src/main.js'}},lintOnSave:false// Turn off syntax checking
}
Copy the code

2 routing vueRouter

  1. Write routing information to SRC /router/index.js,
  2. Using routing components in SRC/app.vue, <router-view />To view the routing view

SRC/router/index. Js

import Vue from 'vue'
import VueRouter from 'vue-router'
import Main from '.. /views/Main.vue'

Vue.use(VueRouter)

const routes = [
  {
    path: '/'.name: 'Main'.component: Main
  },
  {
    path: '/about'.name: 'About'.// route level code-splitting
    // this generates a separate chunk (about.[hash].js) for this route
    // which is lazy-loaded when the route is visited.
    component: () = > import(/* webpackChunkName: "about" */ '.. /views/About.vue')}]const router = new VueRouter({
  mode: 'history'.base: process.env.BASE_URL,
  routes
})

export default router
Copy the code

SRC/App. Vue

<template>
  <div id="app">

     <router-link to="/">Main</router-link> |
     <router-link to="/about">about</router-link>

      <router-view />
  </div>
</template>
Copy the code

3 element-ui

Introducing the element – the UI

  • Introduced the global
  • Introduction on demand (General project Introduction on demand)
  1. Change the configuration of babel.config.js@Babel/preset-env

, Babel. Config. Js

module.exports = {
  presets: [
    '@vue/cli-plugin-babel/preset',]."plugins": [["component",
      {
        "libraryName": "element-ui"."styleLibraryName": "theme-chalk"}}]]Copy the code
  1. Some components that introduce element-UI in main. vue need to be registered in main.js

, the main js

import Vue from 'vue'
import App from './App.vue'
import './registerServiceWorker'
import router from './router'
import store from './store'
// import ElementUI from 'element-ui';
// import 'element-ui/lib/theme-chalk/index.css';

// Vue.use(ElementUI);
import { Menu, MenuItem, MenuItemGroup,Submenu,Button, Select,Radio,Container,Aside,Header,Main } from 'element-ui';

Vue.use(Button);
Vue.use(Select);
Vue.use(Radio);
Vue.use(Container);
Vue.use(Aside);
Vue.use(Header);
Vue.use(Menu);
Vue.use(Main);
Vue.use(MenuItem);
Vue.use(MenuItemGroup);
Vue.use(Submenu);
// Vue.component(Button.name, Button);
// Vue.component(Select.name, Select);
// Vue.component(Radio.name, Radio);


Vue.config.productionTip = false

new Vue({
  router,
  store,
  render: h= > h(App)
}).$mount('#app')

Copy the code

4 the Container layout

src/views/Main.vue

<template>
  <el-container style="height:100%">
  <el-aside width="auto">aside</el-aside>
  <el-container>
    <el-header>Header</el-header>
    <el-main>Main</el-main>
  </el-container>
</el-container>
</template>
Copy the code

Five components

Sidebar component UI-commonAside. Vue

  1. Create the sidebar components SRC/components/CommonAside vue, copy and paste the sidebar UI components.
  2. Import components in SRC /views/ main.vueimport CommonAside from ".. /components/CommonAside.vue", register componentscomponents: {CommonAside}

And use the component tag

SRC/components/CommonAside. Vue

<template> 
    <el-menu  class="el-menu-vertical-demo" @open="handleOpen" @close="handleClose" :collapse="isCollapse">
        <el-submenu index="1">
            <template slot="title">
            <i class="el-icon-location"></i>
            <span slot="title">A navigation</span>
            </template>
            <el-menu-item-group>
            <span slot="title">Group a</span>
            <el-menu-item index="1-1">Option 1</el-menu-item>
            <el-menu-item index="1-2">Option 2</el-menu-item>
            </el-menu-item-group>
            <el-menu-item-group title="Group 2">
            <el-menu-item index="1-3">Option 3</el-menu-item>
            </el-menu-item-group>
            <el-submenu index="1-4">
            <span slot="title">Option 4</span>
            <el-menu-item index="1-4-1">Option 1</el-menu-item>
            </el-submenu>
        </el-submenu>
        <el-menu-item index="2">
            <i class="el-icon-menu"></i>
            <span slot="title">Navigation 2</span>
        </el-menu-item>
        <el-menu-item index="3" disabled>
            <i class="el-icon-document"></i>
            <span slot="title">Navigation three</span>
        </el-menu-item>
        <el-menu-item index="4">
            <i class="el-icon-setting"></i>
            <span slot="title">Navigation four</span>
        </el-menu-item>
    </el-menu>
</template> 


<style>
  .el-menu-vertical-demo:not(.el-menu--collapse) {
    width: 200px;
    min-height: 400px;
  }
</style>

<script>
  export default {
    data() {
      return {
        isCollapse: true
      };
    },
    methods: {
      handleOpen(key, keyPath) {
        console.log(key, keyPath);
      },
      handleClose(key, keyPath) {
        console.log(key, keyPath); }}}</script>
Copy the code

Primary menu and secondary menu

src/components/CommonAside.vue

  1. Write menu data
  2. Calculate properties to determine whether there are submenus
  3. The menu list is implemented by: band and V-for for unbinding and looping
<template> 
    <el-menu class="el-menu-vertical-demo" @open="handleOpen" @close="handleClose" :collapse="isCollapse">
        <h3>General background management system</h3>
        <el-menu-item :index="item.path" v-for="item in noChildren" :key="item.path">
            <i :class="'el-icon-'+ item.icon"></i>
            <span slot="title">{{item.label}}</span>
        </el-menu-item>
        
        <el-submenu :index="item.label" v-for="item in hasChildren" :key="item.path">
            <template slot="title">
            <i :class="'el-icon-'+ item.icon"></i>
            <span slot="title">{{item.label}}</span>
            </template>
            <el-menu-item-group>
            <el-menu-item :index="subItem.path" v-for="(subItem, subIndex) in item.children" :key="subIndex">
            <i :class="'el-icon-'+ subItem.icon"></i>
            <span slot="title">{{subItem.label}}</span> 
            </el-menu-item>
            </el-menu-item-group>
        </el-submenu>
    </el-menu>
</template> 

<style scoped>
  .el-menu-vertical-demo:not(.el-menu--collapse) {
    width: 200px;
    min-height: 400px;
    height: 100vh;
    border-right: 0;
  }
  .el-menu-item..el-submenu{
    text-align: left;
  }
</style>

<script>
  export default {
    data() {
      return {
        isCollapse: true.// Menu 1 writes menu data
        menu:[
            {
                path: '/'.name: 'home'.label:'home'.icon:'s-home'.url:'Home/Home'}, {path: '/mall'.name: 'mall'.label:'Merchandise Management'.icon:'video-play'.url:'MallManage/MallManage'}, {path: '/user'.name: 'user'.label:'User Management'.icon:'user'.url:'UserManage/UserManage'}, {label:'other'.icon:'location'.children:[
                    {
                    path: '/page1'.name: 'page1'.label:'page 1'.icon:'setting'.url:'Other/PageOne'}, {path: '/page2'.name: 'page2'.label:'page 2'.icon:'setting'.url:'Other/PageTwo'},]}]}; },methods: {
      handleOpen(key, keyPath) {
        console.log(key, keyPath);
      },
      handleClose(key, keyPath) {
        console.log(key, keyPath); }},// 2 Calculate properties to check whether there are submenus
    computed: {
        noChildren() {
            return this.menu.filter((item) = >! item.children) },hasChildren(){
            return this.menu.filter((item) = > item.children)
        }
    }
  }
</script>
Copy the code

The Menu style

src/components/CommonAside.vue

    <el-menu 
    class="el-menu-vertical-demo"  
    :collapse="isCollapse" 
    background-color="#545c64" 
    text-color="fff" 
    active-text-color="#ffd04b">
Copy the code

CommonHeader Components (drop-down list)

  1. Create a Header component SRC/components/CommonHeader vue

, copy and paste the EL-Header component UI.

  1. Import components in SRC /views/ main.vueimport CommonHeader from ".. /components/CommonHeader.vue", register componentscomponents: {CommonHeader}

And use the component tag

home

SRC/components/CommonHeader. Vue

<template>
    <header>
    <div class="l-content">
        <el-button plain icon="el-icon-menu" size="mini"></el-button>   
        <h3 style="color:#fff"></h3>
    </div>
    <div class="r-content">
        <el-dropdown trigger="click" size="mini">
            <span class="el-dropdown-link">
                <img src="userImg" class="user" />
            </span>
             <el-dropdown-menu slot="dropdown">
            <el-dropdown-item>Personal center</el-dropdown-item>
            <el-dropdown-item>exit</el-dropdown-item>
        </el-dropdown-menu>
        </el-dropdown>
    </div>
    </header>
</template>

<script>

export default {
  components: {},// Define attributes
  data() {
    return {
      userImg: require('.. /assets/user.png'),}},// Evaluate attributes, and listen for dependent attributes to change accordingly
  computed: {},// Monitor changes in data
  watch: {},
  // Set of methods
  methods: {},}</script>

<style lang='scss' scoped>
  header {
      display: flex;
      height:100%;
      align-items: center;
      justify-content:space-between;

  }
  .l-content{
      display:flex;
      align-item:center;
      .el-button{
          margin-right:20px}}.r-content{
      .user{
          width:40px;
          height:40px;
          border-radio: 50%; }}</style>
Copy the code

Collapse shrinkage of the sidebar (Vuex)

Click header to collapse and shrink the sidebar

Note: Vuex state management is used to transfer values across components,

1 store/TAB. Js

export default{
    state: {isCollapse: false,},mutations: {collapseMenu(state){ state.isCollapse = ! state.isCollapse; }}}Copy the code

2 store/index. Js

import Vue from 'vue'
import Vuex from 'vuex'
import tab from './tab'// TAB in the current directory

Vue.use(Vuex)

export default new Vuex.Store({
 
  modules: {
    tab
  }
})

Copy the code

3. Change isCollapse to a method to determine whether // isCollapse: false,// this is written in computed

SRC/components/CommonAside. Vue

 <el-menu class="el-menu-vertical-demo"  :collapse="isCollapse" background-color="#545c64" text-color="fff" active-text-color="#ffd04b">
        <h3 v-show=! "" isCollapse">General background management system</h3>
        <h3 v-show="isCollapse">The background</h3>
Copy the code
computed: {
        noChildren() {
            return this.menu.filter((item) = >! item.children) },hasChildren(){
            return this.menu.filter((item) = > item.children)
        },
        isCollapse(){
          return this.$store.state.tab.isCollapse
        }
    }
Copy the code

SRC/components/CommonHeader. Vue

        <el-button plain icon="el-icon-menu" size="mini" @click="clickHandler(item)"></el-button>   

Copy the code

 methods: {
    clickHandler(){
        this.$store.commit('collapseMenu'); }},Copy the code

Home Component Layout (Router)

  1. Add router/index.js to the child route
const routes = [
  {
    path: '/'.name: 'Main'.component: Main,
    children: [{path: '/'.name:'home'.component: () = >import('@/views/Home/Home')// Route lazy loading}},Copy the code
  1. Creating a Home component

views/Home/Home.vue

<template>
  <div>This is the component of Home</div>
</template>

Copy the code

Home component User card section

<template>
  <el-row class="home" :gutter="20">
    <el-col :span="8" style="margin-top:20px">
        <el-card shadow="hover">
            <div class="user">
                <img :src="userImg"/>
                <div class="userinfo">
                    <p class="name">Admin</p>
                    <p class="access">Super administrator</p>
                </div>
            </div>
            <div class="login-info">
            <p>Last login time:<span>2021-12-20</span></p>
            <p>Last login Location:<span>suzhou</span></p>

            </div>
        </el-card>
    </el-col>
    <el-col :span="16"></el-col>
  </el-row>
</template>

<script>

export default {
  components: {},// Define attributes
  data() {
    return {
          userImg:require('.. /.. /assets/user.png')}},// Evaluate attributes, and listen for dependent attributes to change accordingly
  computed: {},// Monitor changes in data
  watch: {},
  // Set of methods
  methods: {},}</script>

<style lang='sass' scoped>
  @import "~@/assets/scss/home"
</style>
Copy the code

Home component purchase statistics

 <el-card style="margin-top:20px">
            <el-table :data="tableData">
            <el-table-column 
            show-overflow-tooltip 
            v-for="(val,key) in tableLabel"
            :key="key"
            :prop="key"
            :label="val"
            >
             </el-table-column>
            </el-table>
        </el-card>
Copy the code
data() {
    return {
          userImg:require('.. /.. /assets/user.png'),
          tableData: [].// Data needs to be put in here, or mock dummy data
          tableLabel: {name: 'course'.todayBuy:'Buy today'.mouthBuy:'Buy this month'.totalBuy:'Total purchase',}}},Copy the code

Home component order display

 <el-col :span="16" style="margin-top:20px">
    <div class="num">
        <el-card 
            shadow="hover" 
            v-for="item in countData" 
            :key="item.name" 
            :body-style="{display:'flex',padding:0}"
            >
        <i 
            class="icon" 
            :class="`el-icon-${item.icon}` " 
            :style="{background: item.color}"
            ></i>
        <div class="detail">
            <p class="num">${{item. Value}}</p>
            <p class="txt">{{item.name}}</p>
        </div>
        </el-card>
        </div>
        <el-card shadow="hover" style="height:280px"></el-card>
        <div class="graph" >
            <el-card shadow="hover" style="height:260px"></el-card>
            <el-card shadow="hover" style="height:260px"></el-card>
        </div>
    </el-col>
Copy the code

Axios is basically used

  1. Download and install AxiOS

cnpm install axios

main.js

import https from 'axios'

Vue.prototype.$http = http

Copy the code

2 Home.vue

mounted() {
        this.$http.get('/user? ID=12345')
            .then(function (response) {
                console.log(response);
            })
            .catch(function (error) {
                console.log(error);
            });
    }
Copy the code

Implementation of axiOS with secondary wrapping (interceptor)

Interceptors are added before (adding some parameters) and after the request, allowing for centralized processing of common errors.

  1. New SRC/API/axios. Js
/ / the interceptor
import axios from 'axios';
/ / into the config/index. Js
import config from '.. /config/index'
The development environment is different from the production environment
const baseUrl  = process.env.NODE_ENV ===  'development' ? config.baseUrl.dev :config.baseUrl.pro

class HttpRequest {
    constructor(baseUrl){
        this.baseUrl = baseUrl
    }
    getInsideConfig() { 
        const config = {
            baseUrl:this.baseUrl,
            header: {}}return config
    }
    interceptors(instance) {
        // Add request interceptor
        instance.interceptors.request.use(function (config) {
            // What to do before sending the request
            console.log('Intercept processing request')
            return config;
        }, function (error) {
            // What to do about the request error
            return Promise.reject(error);
        });

        // Add a response interceptor
        instance.interceptors.response.use(function (response) {
            // What to do with the response data
            console.log('Process response')
            return response.data;
        }, function (error) {
            // Do something about the response error
            console.log(error)
            return Promise.reject(error);
        });
    }
    / / {
    // baseUrl:'./api-'
    // }
    request(options){// Request (option) is a call to the above HttpRequest method, options is passed some parameter objects
        / / request
        // /api/getList /api/getHome
        constinstance = axios.create() options = {... (this.getInsideConfig()),... options}/ / skills
        this.interceptors(instance)
        return instance(options)
    }
}

export default new HttpRequest(baseUrl)

Copy the code

options = {... (this.getInsideConfig()),... options}

  1. New SRC/config/index. Js

Config here is some configuration in API/AXIos


export default{
    title:'admin'.baseUrl: {// Development environment
        dev:'./api/'.// Production environment
        pro:' '}}Copy the code

The use of axios for secondary encapsulation

  1. new

scr/api/data.js

import axios from './axios'

export const getMenu = () = > {
    return axios.request({
        url:'menu'.method:'GET'})},Copy the code

2 Home.vue is introduced and used

<script>
import {} from ".. /.. /api/data.js"


    mounted() {
        getMenu().then((res) = >{
            console.log(res)
        })
    }
}
</script>
Copy the code

Mock Implementation of mock data

Mock. js generates random data that intercepts Ajax requests

1. Install CNPM I mockjs-s

  1. The new API/mock. Js
import Mock from "mockjs"
import homeApi from "./mockServerData/home"
Mock.mock('api/home/getData',homeApi.getStatisticalData)
Copy the code
  1. The new API/mockServerData/home. Js

Import data

  1. api/data.js

Add the getHome method

import axios from './axios'

export const getMenu = () = > {
    return axios.request({
        url:'menu'.method:'GET'})},export const getHome = () = > {
    return axios.request({
        url:'/home/getData'.method:'GET'})},Copy the code
  1. Mock. js is introduced in main.js
if(process.env.NODE_EN === 'development') require('@/api/mock')

Copy the code
  1. Use the mock

Echarts application

  1. Install echarts
  2. joinref="userEchart"

Home.vue

<el-card shadow="hover" style="height:280px" ></el-card>
        <div style="height:280px" ref="echart"></div>
        <div class="graph" >
            <el-card shadow="hover" style="height:260px"></el-card>
                <div style="height:280px" ref="userEchart"> </div>

            <el-card shadow="hover" style="height:260px"></el-card>
              <div style="height:280px" ref="videoEchart"> </div>
Copy the code
  1. show

    methods: {getTableData(){
            getHome().then((res) = >{
                this.tableData = res.data.tableData

                // Display the line graph
                const order = res.data.orderData
                // console.log(order)
                this.echartsData.order.xAxis.data = order.data

                let keyArray = Object.keys(order.data[0])
                keyArray.forEach((key) = >{
                    this.echartsData.order.series.push({
                        name: key,
                        data: order.data.map((item) = > item[key]),
                        type: "line",})})const myEchartsOrder = echarts.init(this.$refs.echart)//refs do not write directly on the el- component, use div
                myEchartsOrder.setOptions(this.echartsOrder.order)

                / / user
                this.echartsData.user.xAxis.data = red.data.userData.map((item) = > item.data)
                this.echartsData.user.series.push({
                    name:'New User'.data: res.data.userData.map((item) = > item.new),
                    type:'bar'
                });
                this.echartsData.user.series.push({
                    name:'Active User'.data: res.data.userData.map((item) = > item.active),
                    type:'bar'
                });

                const myEchartsUser = echarts.init(this.$refs.userEchart)//refs do not write directly on the el- component, use div
                myEchartsUser.setOptions(this.myEchartsUser.user)

                / / the pie chart
                this.echartsData.video.series.push({
                    data: res.data.videoData,
                    type:'pie'
                });
                const myEchartsVideo = echarts.init(this.$refs.videoEchart)//refs do not write directly on the el- component, use div
                myEchartsVideo.setOptions(this.myEchartsVideo.user)

            })
        }
    },
Copy the code

Echarts encapsulation

1. Create components/ echarts.vue based on whether there is an X-axis

<template>
  <div ref="echart">
      
  </div>
</template>

<script>

export default {
  components: {},props: {charData: {
          type: Object.default(){
              return{
                  xData:[],
                  series,
              }
          }
      },
      isAxisChart: {
          type: Boolean.default: true,}}// Define attributes
  data() {
    return {
      axisOption: {legend: {
          // Legend text color
          textStyle: {
            color: "# 333",}},grid: {
          left: "20%",},/ / prompt dialog box
        tooltip: {
          trigger: "axis",},xAxis: {
          type: "category"./ / category axis
          data: [].axisLine: {
            lineStyle: {
              color: "#17b3a3",}},axisLabel: {
            interval: 0.color: "# 333",}},yAxis: [{type: "value".axisLine: {
              lineStyle: {
                color: "#17b3a3",},},},],color: ["#2ec7c9"."#b6a2de"."#5ab1ef"."#ffb980"."#d87a80"."#8d98b3"].series: []},normalOption: {
        tooltip: {
          trigger: "item",},color: [
          "#0f78f4"."#dd536b"."#9462e5"."#a6a6a6"."#e1bb22"."#39c362"."#3ed1cf",].series: []},echart: null}; },// Evaluate attributes, and listen for dependent attributes to change accordingly
  computed: {},// Monitor changes in data
  watch: {},
  // Set of methods
  methods: {},}</script>

<style lang='sass' scoped>
  
</style>
Copy the code
  1. Judge different data and monitor through watch
  // 2 Monitors data changes in data
  watch: {
      charData{
          handler:function(){
              this.initChart();
          },
          deep:true,}},Copy the code

4. Init initializes chart

// Set of methods
  methods: {
    initChart() {
      this.initChartData();
      // Set the echarts table
      //
      if (this.echart) {
        this.echart.setOption(this.options);
      } else {
        this.echart = echarts.init(this.$refs.echart);
        this.echart.setOption(this.options); }},initChartData() {
      if (this.isAxisChart) {
        this.axisOption.xAxis.data = this.chartData.xData;
        this.axisOption.series = this.chartData.series;
      } else {
        this.normalOption.series = this.chartData.series; }}},Copy the code

5 Evaluate properties, listen for dependent properties to change as a result

   // 5 Evaluate attributes and listen for dependent attributes to change accordingly
  computed: {
      options(){
          return this.isAxisChart ? this.axisOption :this.normalOption
      }
  },
Copy the code

Encapsulate line, pie, and bar charts

home.vue

 <el-card shadow="hover" style="height: 280px">
        <echart :chartData="echartData.order" style="height: 280px"></echart>
      </el-card>
      <div class="graph">
        <el-card shadow="hover" style="height: 260px">
          <echart :chartData="echartData.user" style="height: 240px"></echart>
        </el-card>
        <el-card shadow="hover" style="height: 260px">
          <echart
            :chartData="echartData.video"
            style="height: 240px"
            :isAxisChart="false"
          ></echart>
        </el-card>
Copy the code
 methods: {
    getTableData() {
      getHome().then((res) = > {
        // console.log(res);
        this.tableData = res.data.tableData;

        // Display the line graph
        const order = res.data.orderData;
        let keyArray = Object.keys(order.data[0]);

        // const myEchartsOrder = echarts.init(this.$refs.echart);
        // myEchartsOrder.setOption(this.echartsData.order);

        // The value passed to the component
        this.echartData.order.xData = order.date;
        keyArray.forEach((key) = > {
          this.echartData.order.series.push({
            name: key,
            data: order.data.map((item) = > item[key]),
            type: "line"}); });/ / user

        this.echartData.user.xData = res.data.userData.map((item) = > item.date);
        this.echartData.user.series.push({
          name: "New User".data: res.data.userData.map((item) = > item.new),
          type: "bar"});this.echartData.user.series.push({
          name: "Active Users".data: res.data.userData.map((item) = > item.active),
          type: "bar"});this.echartData.video.series.push({
          data: res.data.videoData,
          type: "pie"}); }); }},mounted() {
    this.getTableData(); }};Copy the code