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
- Write routing information to SRC /router/index.js,
- 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)
- 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
- 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
- Create the sidebar components SRC/components/CommonAside vue, copy and paste the sidebar UI components.
- Import components in SRC /views/ main.vue
import 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
- Write menu data
- Calculate properties to determine whether there are submenus
- 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)
- Create a Header component SRC/components/CommonHeader vue
, copy and paste the EL-Header component UI.
- Import components in SRC /views/ main.vue
import 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)
- 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
- 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
- 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.
- 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}
- 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
- 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
- The new API/mock. Js
import Mock from "mockjs"
import homeApi from "./mockServerData/home"
Mock.mock('api/home/getData',homeApi.getStatisticalData)
Copy the code
- The new API/mockServerData/home. Js
Import data
- 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
- Mock. js is introduced in main.js
if(process.env.NODE_EN === 'development') require('@/api/mock')
Copy the code
- Use the mock
Echarts application
- Install echarts
- join
ref="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
- 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
- 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