后端人员开发前端vue。

git地址:https://github.com/1065744299/vue-elment-ui
演示地址:https://1065744299.github.io/
csdn下载源码地址:https://download.csdn.net/download/qq_25451199/11256228
这个demo主要用到vue、vueRouter、vueX、element UI、echarts等技术。主要以展示怎么使用为主。主要的功能有登录、路由、store、报表、导出等。
这里用vue的多页面功能,为了组件的重复使用。
开始介绍代码:
为了打包的时候直打包一个页面,这里对vue.config.js做了修改;代码如下:

var projectname = process.argv[5]
var glob = require('glob')function getEntry () {var entries = {}if (process.env.NODE_ENV === 'production') {entries = {index: {// page的入口entry: 'src/modules/' + projectname + '/main.js',// 模板来源template: 'public/index.html',// 在 dist/index.html 的输出filename: 'index.html',title: projectname,chunks: ['chunk-vendors', 'chunk-common', 'index']}}} else {var items = glob.sync('./src/modules/*/*.js')for (var i in items) {var filepath = items[i]var fileList = filepath.split('/')var fileName = fileList[fileList.length - 2]entries[fileName] = {entry: `src/modules/${fileName}/main.js`,// 模板来源template: `public/index.html`,// 在 dist/index.html 的输出filename: `${fileName}.html`,// 提取出来的通用 chunk 和 vendor chunk。chunks: ['chunk-vendors', 'chunk-common', fileName]}}}return entries
}var pages = getEntry()
// vue.config.js
module.exports = {// 基本路径publicPath: '/',// 输出文件目录// outputDir: 'dist',// webpack-dev-server 相关配置devServer: {port: 8888},// 生产禁止显示源代码productionSourceMap: false,// 输出文件目录outputDir: 'dist/' + projectname,pages: pages
}

下面开始搭建一个简单的demo。

主要有几个基础的组件。
先了解下项目结构:


这里主要说组件的内容。

  • Home.vue
    主页组件
<template><el-container><el-header><Head :isCollapse='isCollapse' @changeCollapse="changeCollapsed" :sysName='sysName' :userInfo='homeUserInfo' @logoutHandle='logoutHandle'></Head></el-header><el-container><el-aside :class="isCollapse?'menu-collapsed':'menu-expanded'"><Menu :isCollapse='isCollapse' :defaultActive="defaultActive" :menuJson='menuJson' @selectedTab="selectedTab(arguments)"/></el-aside><el-main><div class="my-main"><Main :editableTabsValue="editableTabsValue" ref="myMain" @selectedTab="mainSelectedTab(arguments)"/></div></el-main></el-container></el-container>
</template>
<script>
import Menu from '@/components/Menu.vue'
import Head from '@/components/Head.vue'
import Main from '@/components/Main.vue'
export default {name: 'app',props: ['sysName', 'userInfo', 'menuJson'],components: {Menu,Head,Main},data () {return {// 菜单是否折叠'isCollapse': false,// 主展示区默认选项卡'editableTabsValue': '首页',// 菜单默认选中'defaultActive': '/main/home'}},computed: {'homeUserInfo': function () {return this.userInfo}},methods: {changeCollapsed: function () {this.isCollapse = !this.isCollapse},selectedTab: function (args) {this.editableTabsValue = args[0]this.defaultActive = args[1]this.$refs.myMain.addTab(this.editableTabsValue, this.defaultActive)},mainSelectedTab: function (args) {this.editableTabsValue = args[0]this.defaultActive = args[1]},myRoute: function (index) {this.$router.push({ 'path': index })},logoutHandle: function () {this.$emit('logoutHandle')}},created: function () {this.myRoute(this.defaultActive)}
}
</script>
<style>html,body,#app,.el-container {height: 100%;}.el-header {color: #333;line-height: 60px;padding: 0 0px;}.el-aside {background-color: #eef1f6;color: #333;line-height: 200px;}.el-main {color: #333;padding: 0 0 0 0px;width: 100%;}.menu-collapsed{flex:0 0 65px;width: 65px;}.menu-expanded{flex:0 0 201px;width: 201px;}body{margin: 0px;}main {height:  100%;overflow-y: auto;}
</style>
  • Head.vue
    头部组件
<template><el-col :span="24" class="header"><el-col :span="10" class="logo " :class="isCollapse?'logo-collapse-width':'logo-width'">{{isCollapse?'':sysName}}<img src="../assets/w.jpg" width="66px" height="100%" v-show="isCollapse"/></el-col><el-col :span="10"><div class="tools"><i :class="isCollapse?'el-icon-s-unfold':'el-icon-s-fold'" @click="pchangeCollapse"></i></div></el-col><el-col :span="4" class="userinfo"><el-dropdown trigger="hover"><span class="el-dropdown-link userinfo-inner"><img :src="img"/>{{name}}</span><el-dropdown-menu slot="dropdown"><el-dropdown-item>我的消息</el-dropdown-item><el-dropdown-item>设置</el-dropdown-item><el-dropdown-item @click.native="logoutHandle">退出登录</el-dropdown-item></el-dropdown-menu></el-dropdown></el-col></el-col>
</template>
<script>
let userInfo = {name: '苏三杰',img: 'https://raw.githubusercontent.com/taylorchen709/markdown-images/master/vueadmin/user.png'
}
export default {props: {'isCollapse': {type: Boolean,default: true},'userInfo': {type: Object,default: () => userInfo},'sysName': {type: String,default: 'WEBDEMO'}},data () {return {}},computed: {'name': function () {return this.userInfo.name},'img': function () {return this.userInfo.img}},methods: {pchangeCollapse: function () {this.$emit('changeCollapse')},logoutHandle: function () {this.$confirm('确定要退出吗?', '提示', {confirmButtonText: '确定',cancelButtonText: '取消',type: 'warning'}).then(() => {// this.$message({//   type: 'success',//   message: '删除成功!'// })this.$emit('logoutHandle')}).catch(() => {this.$message({type: 'info',message: '已取消退出'})})}}
}
</script>
<style scoped>
.header {height: 60px;line-height: 60px;background: #67C23A;color:#fff
}.userinfo {height: 60px;line-height: 60px;text-align: right;padding-right: 35px;float: right;
}.userinfo-inner {height: 60px;line-height: 60px;cursor: pointer;color:#fff;}.userinfo-inner>img {cursor: pointer;color:#fff;width: 40px;height: 40px;border-radius: 20px;margin: 10px 0px 10px 10px;float: right;}.logo {height:60px;font-size: 22px;border-color: rgba(238,241,146,0.3);border-right-width: 1px;border-right-style: solid;}.txt {color:#fff;}.logo-width{width:202px;padding-left:20px;padding-right:20px;}.logo-collapse-width{width:65px;padding-left:0px;padding-right:0px;}.tools{padding: 0px 23px;width:14px;height: 60px;line-height: 60px;cursor: pointer;}
</style>
  • Main.vue
    主展示区组件
<template><el-tabs v-model="myEditableTabsValue" type="card" closable @tab-remove="removeTab" @tab-click="goRoute"><el-tab-panev-for="(item) in editableTabs":key="item.name":label="item.title":name="item.name":myindex="item.index"><div class="mymain"><router-view/></div></el-tab-pane></el-tabs>
</template>
<script>
export default {props: ['editableTabsValue'],data () {return {editableTabs: [{title: '首页',name: '首页',index: '/main/home'}],myEditableTabsValue: this.editableTabsValue}},methods: {addTab (name, index) {for (var t in this.editableTabs) {if (this.editableTabs[t].name === name) {this.myEditableTabsValue = namereturn}}this.editableTabs.push({title: name,name: name,index: index})this.myEditableTabsValue = name},removeTab (targetName) {let tabs = this.editableTabslet activeName = this.myEditableTabsValue// let activeName = ''let _index = ''if (activeName === targetName) {tabs.forEach((tab, index) => {if (tab.name === targetName) {let nextTab = tabs[index + 1] || tabs[index - 1]if (nextTab) {activeName = nextTab.name_index = nextTab.index}}})}this.$router.push({ 'path': _index })this.$emit('selectedTab', activeName, _index)this.myEditableTabsValue = activeNamethis.editableTabs = tabs.filter(tab => tab.name !== targetName)},goRoute (args) {let tabs = this.editableTabslet _thisTab = tabs.filter(tab => tab.name === args.name)[0]this.$router.push({ 'path': _thisTab.index })this.$emit('selectedTab', _thisTab.name, _thisTab.index)// this.$emit('myRoute', _thisTab.index)}}
}
</script>
<style scoped>
.mymain {padding: 0 5px
}
</style>
  • Menu.vue
    菜单组件
<template><div><el-menu:default-active="defaultActive"class="el-menu-vertical-demo"@open="handleOpen"@close="handleClose":collapse="isCollapse"background-color="#eef1f6"active-text-color="#20a0ff":collapse-transition="false"text-color="#48576a":router="true"><template v-for="m in menus"><el-submenu v-if="m.type=='subMenu'" :index="m.id" :key="m.id"><template slot="title"><i :class="m.icon"></i><span slot="title">{{m.name}}</span></template><el-menu-item v-for="mi in m.submenus" :key="mi.id" :index="mi.url" :route="{path: mi.url}" @click.native="selected(mi.name, mi.url)">{{mi.name}}</el-menu-item></el-submenu><el-menu-item v-if="m.type=='menu-item'" :index="m.url" :key="m.id" :route="{path: m.url}" @click.native="selected(m.name, m.url)"><i :class="m.icon"></i><span slot="title">{{m.name}}</span></el-menu-item></template></el-menu>
</div>
</template>
<script>
let menuJson = [{id: '1',name: '首页',type: 'menu-item',url: '/',icon: 'el-icon-star-off',submenus: []},{id: '2',name: 'TableS',type: 'subMenu',url: '',icon: 'el-icon-s-grid',submenus: [{id: '3',name: '动态table',type: 'subMenu',url: '/about',icon: ''},{id: '4',name: '拖拽table',type: 'subMenu',url: '/about1',icon: ''},{id: '5',name: '综合table',type: 'subMenu',url: '/about2',icon: ''}]},{id: '6',name: '列表demo',type: 'subMenu',url: '',icon: 'el-icon-user',submenus: [{id: '7',name: '用户列表',type: 'subMenu',url: '/user',icon: ''}]}
]
export default {// props: ['isCollapse', 'defaultActive', 'menuJson'],props: {'isCollapse': {type: Boolean,default: true},'defaultActive': {type: String,default: '首页'},'menuJson': {type: Array,default: () => menuJson}},data () {return {menus: this.menuJson}},methods: {handleOpen (key, keyPath) {console.log(key, keyPath)},handleClose (key, keyPath) {console.log(key, keyPath)},selected (name, index) {this.$emit('selectedTab', name, index)}}
}
</script>
<style>.el-menu-vertical-demo:not(.el-menu--collapse) {width: 200px;}.el-menu {border-right: solid 0px #e6e6e6;}
</style>
  • Table.vue
    列表组件
<template>
<div><el-table :data="datas" v-bind="tableAttrs" v-on="tableEvents" :cell-style="{padding:0}" style="width: 100%;" :header-cell-style="{background:'#eef1f6',color:'#606266'}"><el-table-column v-for="(item, index) in columns" :key="index" v-bind="item"></el-table-column><slot></slot></el-table>
</div>
</template>
<script>
export default {props: ['datas', 'tableAttrs', 'tableEvents', 'columns'],methods: {}
}
</script>
<style>
.el-table__row>td {height: 30px
}
</style>
  • Page.vue
    页码组件
<template><el-pagination@size-change="handleSizeChange"@current-change="handleCurrentChange":current-page="currentPage":page-sizes="[20, 40, 80, 100]":page-size="20"layout="total, sizes, prev, pager, next, jumper":total="total"></el-pagination>
</template>
<script>
export default {props: ['currentPage', 'total'],data () {return {}},methods: {handleSizeChange (val) {this.$emit('handleSizeChange', val)},handleCurrentChange (val) {this.$emit('handleCurrentChange', val)}}
}
</script>
<style></style>
  • CommonPage.vue
    常用主页面组件(这个很重要,为以后直接生成页面做准备)
<template><div><el-row :gutter="10"><el-col :span="24" v-if="formEntity"><div  class="bg-purple-dark"><el-form :inline="true" :model="formInline"><template v-for="(item, index) in formEntity"><template v-if="item.template === 'input'"><el-form-item :label="item.label" :key="index"><el-input v-model="formInline[item.name]" size="small" v-bind="item"></el-input></el-form-item></template><template v-if="item.template === 'date'"><el-form-item :label="item.label" :key="index"><el-date-picker v-model="formInline[item.name]" size="small" v-bind="item"></el-date-picker></el-form-item></template><template v-if="item.template === 'select'"><el-form-item :label="item.label" :key="index"><el-select v-model="formInline[item.name]" size="small" v-bind="item"><el-option v-for="(option, index) in item.options" :key="index" :label="option.label" :value="option.value"></el-option></el-select></el-form-item></template></template><el-form-item><el-button type="primary" size="small" @click="queryF">查询</el-button></el-form-item></el-form></div></el-col></el-row><el-row v-if="buttons && buttons.length > 0"><el-button plain size="small" v-for="(item , index) in buttons" :key="index" v-bind="item" @click="buttonClick(item.callback)">{{item.label}}</el-button></el-row><el-row v-if="tableEntity"><Table v-bind="tableEntity.options"><el-table-column v-if="tableEntity.options.operationColumn && tableEntity.options.operationColumn.length > 0" label="操作"><template scope="scope"><el-button plain v-for="(item, index) in tableEntity.options.operationColumn" :key="index" size="mini" v-bind="item" @click="tableoperationcallback(scope.$index, scope.row,item.callback)">{{item.label}}</el-button></template></el-table-column></Table></el-row><el-row v-if="tableEntity.page" style="background: #EEF1F6;"><div  class="bg-purple-dark"><Page:currentPage="tableEntity.page.currentPage":total="tableEntity.page.total"@handleSizeChange="handleSizeChange"@handleCurrentChange="handleCurrentChange"/></div></el-row></div>
</template>
<script>
import Table from '@/components/Table.vue'
import Page from '@/components/Page.vue'export default {props: {// 查询实体formEntity: {type: Array},queryFunction: {type: Function},tableEntity: {type: Object},buttons: {type: Array}},components: {Table,Page},data () {return {formInline: {}}},methods: {// 查询方法queryF () {if (this.queryFunction) {this.queryFunction(this.formInline)}},// 列表操作事件tableoperationcallback: function (index, row, callback) {if (callback) {callback(index, row)}},// 页面列表记录数改表handleSizeChange (val) {if (this.tableEntity.page && this.tableEntity.page.handleSizeChange) {this.tableEntity.page.handleSizeChange(val)}},// 点击其他页面handleCurrentChange (val) {if (this.tableEntity.page && this.tableEntity.page.handleCurrentChange) {this.tableEntity.page.handleCurrentChange(val)}},// 按钮点击事件buttonClick (fun) {if (fun) {fun()}}}
}
</script>
<style scoped>.bg-purple-dark {border-radius: 4px;background: #EEF1F6;padding: 5px;}.el-form-item {margin: 5px;}.el-row {margin-bottom: 5px;}.el-form-item__label {min-width: 70px;}
</style>

上面就把主要的组件写完了,下面就是一个应用。
这个应用使用多级路由和vuex。

  • App.vue
<template><div id="app"><router-view/></div>
</template>
<script>
import axios from './utils/http'export default {components: {// Home},data () {return {// userInfo: userInfo,// sysName: sysName,// menuJson: menuJson}},methods: {logoutHandle: function () {// TODOconsole.log('退出')},testApi: function () {// http://10.98.3.27:8080/app/mock/data/139axios.get('http://10.98.3.27:8080/app/mock/data/139').then(response => {console.info(response)console.info(response.data)}).catch(error => {console.log(error)}).finally(() => console.log('finally'))}},created: function () {// this.testApi()this.$router.push({ 'path': '/main/home' })}
}
</script>
<style>
html, body, #app{width: 100%;
}
</style>
  • main.js
import Vue from 'vue'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
import App from './App.vue'
import router from './router'
import store from './store'
// import axios from 'axios'
// import VueAxios from 'vue-axios'
// import http from './utils/http'
// import VueAxios from 'vue-axios'// Vue.use(VueAxios, http)Vue.use(ElementUI)
// Vue.use(http)
Vue.config.productionTip = false
// 做拦截
router.beforeEach((to, from, next) => {// 判断该路由是否需要登录权限if (to.path !== '/login') {// 判断当前的user_id是否存在 ; 登录存入的user_idif (store.state.userInfo.name) {next()} else {next({path: '/login',// 将要跳转路由的path作为参数,传递到登录页面query: { redirect: to.fullPath }})}} else {next()}
})new Vue({router,store,// http,render: h => h(App)
}).$mount('#app')
  • router.js
import Vue from 'vue'
import Router from 'vue-router'
import Home from './views/Home.vue'Vue.use(Router)export default new Router({mode: 'history',base: process.env.BASE_URL,routes: [// {//   path: '/home',//   name: 'home',//   component: Home// },// {//   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')// },// {//   path: '/user',//   name: 'user',//   component: () => import('./views/User.vue')// },{path: '/login',name: 'login',component: () => import('./views/Login.vue')},{path: '/main',name: 'main',component: () => import('./views/MyMain.vue'),children: [{path: 'home',name: 'home',component: Home},{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')},{path: 'user',name: 'user',component: () => import('./views/User.vue')},{path: 'order',name: 'order',component: () => import('./views/Order.vue')},{path: 'echarts',name: 'echarts',component: () => import('./views/Echarts.vue')},{path: 'export',name: 'export',component: () => import('./views/Export.vue')},{path: 'about1',name: 'about1'},{path: 'about2',name: 'about2'},{path: 'ioc',name: 'ioc'}]}]
})
  • store.js
import Vue from 'vue'
import Vuex from 'vuex'Vue.use(Vuex)export default new Vuex.Store({state: {userInfo: {// name: 'Vuex',// img: 'https://raw.githubusercontent.com/taylorchen709/markdown-images/master/vueadmin/user.png'}},mutations: {login (state, user) {state.userInfo = user}},actions: {}
})
  • http.js
    这里使用axios和后台交互,具体业务请自己完善。这里没有具体的使用
import axios from 'axios'
// import {Loading, Message} from 'element-ui'
// import store from '../store'
// import VueAxios from 'vue-axios'
// import Vue from 'vue'// Vue.use(VueAxios, axios)/*** 提示函数* 禁止点击蒙层、显示一秒后关闭*/
const tip = msg => {
//   Message({
//     message: msg,
//     duration: 1000,
//     forbidClick: true
//   })
}/**
* 跳转登录页
* 携带当前页面路由,以期在登录页面完成登录后返回当前页面
*/
const toLogin = () => {// router.replace({//   path: '/login',//   query: {//     redirect: router.currentRoute.fullPath//   }// })
}/**
* 请求失败后的错误统一处理
* @param {Number} status 请求失败的状态码
*/
const errorHandle = (status, other) => {// 状态码判断switch (status) {// 401: 未登录状态,跳转登录页case 401:toLogin()break// 403 token过期// 清除token并跳转登录页case 403:tip('登录过期,请重新登录')localStorage.removeItem('token')// store.commit('loginSuccess', null)setTimeout(() => {toLogin()}, 1000)break// 404请求不存在case 404:tip('请求的资源不存在')breakdefault:console.log(other)}
}// 创建axios实例
var instance = axios.create({ timeout: 1000 * 12 })
// 设置post请求头
instance.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'
/**
* 请求拦截器
* 每次请求前,如果存在token则在请求头中携带token
*/
instance.interceptors.request.use(config => {// 登录流程控制中,根据本地是否存在token判断用户的登录情况// 但是即使token存在,也有可能token是过期的,所以在每次的请求头中携带token// 后台根据携带的token判断用户的登录情况,并返回给我们对应的状态码// 而后我们可以在响应拦截器中,根据状态码进行一些统一的操作。// const token = store.state.token// token && (config.headers.Authorization = token)console.log('interceptors')return config},error => Promise.error(error))// 响应拦截器
instance.interceptors.response.use(// 请求成功res => res.status === 200 ? Promise.resolve(res) : Promise.reject(res),// 请求失败error => {const { response } = errorif (response) {// 请求已发出,但是不在2xx的范围errorHandle(response.status, response.data.message)return Promise.reject(response)} else {// 处理断网的情况// eg:请求超时或断网时,更新state的network状态// network状态在app.vue中控制着一个全局的断网提示组件的显示隐藏// 关于断网组件中的刷新重新获取数据,会在断网组件中说明// store.commit('changeNetwork', false)}})export default instance
  • About.vue
<template><div class="about"><h1>This is an about page</h1></div>
</template>
  • Echarts.vue
<template><div><el-row :gutter="20" class="echarts-row"><el-col :span="6"><div id = "echartss" class="echarts-div" ref="myEchart"></div></el-col><el-col :span="6"><div id = "echartss1" class="echarts-div" ref="myEchart1"></div></el-col><el-col :span="6"><div id = "echartss2" class="echarts-div" ref="myEchart2"></div></el-col><el-col :span="6"><div id = "echartss3" class="echarts-div" ref="myEchart3"></div></el-col></el-row><el-row :gutter="20" class="echarts-row"><el-col :span="6"><div id = "echartss4" class="echarts-div" ref="myEchart4"></div></el-col><el-col :span="6"><div id = "echartss5" class="echarts-div" ref="myEchart5"></div></el-col><el-col :span="6"><div id = "echartss6" class="echarts-div" ref="myEchart6"></div></el-col><el-col :span="6"><div id = "echartss7" class="echarts-div" ref="myEchart7"></div></el-col></el-row><!-- <el-row :gutter="20" class="echarts-row"><el-col :span="6"><div id = "echartss8" class="echarts-div" ref="myEchart8"></div></el-col><el-col :span="6"><div id = "echartss9" class="echarts-div" ref="myEchart9"></div></el-col><el-col :span="6"><div id = "echartss10" class="echarts-div" ref="myEchart10"></div></el-col><el-col :span="6"><div id = "echartss11" class="echarts-div" ref="myEchart11"></div></el-col></el-row><el-row :gutter="20" class="echarts-row"><el-col :span="6"><div id = "echartss12" class="echarts-div" ref="myEchart12"></div></el-col><el-col :span="6"><div id = "echartss13" class="echarts-div" ref="myEchart13"></div></el-col><el-col :span="6"><div id = "echartss14" class="echarts-div" ref="myEchart14"></div></el-col><el-col :span="6"><div id = "echartss15" class="echarts-div" ref="myEchart15"></div></el-col></el-row> --></div>
</template>
<script>
import echarts from 'echarts'
let data = []
for (var i = 0; i <= 360; i++) {var t = i / 180 * Math.PIvar r = Math.sin(2 * t) * Math.cos(2 * t)data.push([r, i])
}
export default {// 挂载前初始化echarts实例mounted: function () {// 基于准备好的dom,初始化echarts实例this.myChart = echarts.init(this.$refs.myEchart)// 绘制图表,this.echarts1_option是数据this.myChart.setOption(this.echarts_option)this.myChart1 = echarts.init(this.$refs.myEchart1)this.myChart1.setOption(this.echarts1_option)this.myChart2 = echarts.init(this.$refs.myEchart2)this.myChart2.setOption(this.echarts2_option)this.myChart3 = echarts.init(this.$refs.myEchart3)this.myChart3.setOption(this.echarts3_option)this.myChart4 = echarts.init(this.$refs.myEchart4)this.myChart4.setOption(this.echarts4_option)},data () {return {echarts4_option: {tooltip: {trigger: 'item',formatter: '{a} <br/>{b}: {c} ({d}%)'},legend: {orient: 'vertical',x: 'left',data: ['直接访问', '邮件营销', '联盟广告', '视频广告', '搜索引擎']},series: [{name: '访问来源',type: 'pie',radius: ['50%', '70%'],avoidLabelOverlap: false,label: {normal: {show: false,position: 'center'},emphasis: {show: true,textStyle: {fontSize: '30',fontWeight: 'bold'}}},labelLine: {normal: {show: false}},data: [{ value: 335, name: '直接访问' },{ value: 310, name: '邮件营销' },{ value: 234, name: '联盟广告' },{ value: 135, name: '视频广告' },{ value: 1548, name: '搜索引擎' }]}]},echarts3_option: {title: {text: '简单柱状图'},xAxis: {type: 'category',data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']},yAxis: {type: 'value'},series: [{data: [120, 200, 150, 80, 70, 110, 130],type: 'bar'}]},echarts2_option: {title: {text: '极坐标双数值轴'},legend: {data: ['line']},polar: {center: ['50%', '54%']},tooltip: {trigger: 'axis',axisPointer: {type: 'cross'}},angleAxis: {type: 'value',startAngle: 0},radiusAxis: {min: 0},series: [{coordinateSystem: 'polar',name: 'line',type: 'line',showSymbol: false,data: data}],animationDuration: 2000},echarts_option: {title: {text: '折线图'},xAxis: {type: 'category',data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']},yAxis: {type: 'value'},series: [{data: [820, 932, 901, 934, 1290, 1330, 1320],type: 'line'}]},echarts1_option: {title: {text: '折线图堆叠'},tooltip: {trigger: 'axis'},// legend: {//   data: ['邮件营销', '联盟广告', '视频广告', '直接访问', '搜索引擎']// },grid: {left: '3%',right: '4%',bottom: '3%',containLabel: true},toolbox: {feature: {saveAsImage: {}}},xAxis: {type: 'category',boundaryGap: false,data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日']},yAxis: {type: 'value'},series: [{name: '邮件营销',type: 'line',stack: '总量',data: [120, 132, 101, 134, 90, 230, 210]},{name: '联盟广告',type: 'line',stack: '总量',data: [220, 182, 191, 234, 290, 330, 310]},{name: '视频广告',type: 'line',stack: '总量',data: [150, 232, 201, 154, 190, 330, 410]},{name: '直接访问',type: 'line',stack: '总量',data: [320, 332, 301, 334, 390, 330, 320]},{name: '搜索引擎',type: 'line',stack: '总量',data: [820, 932, 901, 934, 1290, 1330, 1320]}]}}}
}
</script>
<style scoped>
.echarts-row {height: 300px;
}
.echarts-div {width: 100%;height: 300px;
}
</style>
  • Export.vue
    这里有一个导出,和模拟修改用户信息的按钮
<template><div><el-button type='success' plain size='small' @click='export2Excel'>导出excel</el-button><el-button type='success' plain size='small' @click='updateUser'>修改登录用户</el-button></div>
</template>
<script>
// import Blob from '@/assets/excel/Blob'
// import Export2Excel from '@/assets/excel/Export2Excel.js'
export default {data () {return {tableData: [{ 'index': '0', 'nickName': '沙滩搁浅我们的旧时光', 'name': '小明' },{ 'index': '1', 'nickName': '女人天生高贵', 'name': '小红' },{ 'index': '2', 'nickName': '海是彩色的灰尘', 'name': '小兰' }]}},methods: {export2Excel: function () {require.ensure([], () => {const { exportJsonToExcel } = require('@/assets/excel/Export2Excel')const tHeader = ['序号', '昵称', '姓名']// 上面设置Excel的表格第一行的标题const filterVal = ['index', 'nickName', 'name']// 上面的index、nickName、name是tableData里对象的属性let list = []// const list = this.tableDatalet d = { 'index': '0', 'nickName': '沙滩搁浅我们的旧时光', 'name': '小明' }for (let a = 0; a < 100000; a++) {list.push(d)}// 把data里的tableData存到listconst data = this.formatJson(filterVal, list)// console.log(data)exportJsonToExcel(tHeader, data, '列表excel')})},formatJson (filterVal, jsonData) {return jsonData.map(v => filterVal.map(j => v[j]))},updateUser () {let userInfo = {name: 'UpdateUser',img: 'https://raw.githubusercontent.com/taylorchen709/markdown-images/master/vueadmin/user.png'}this.$store.commit('login', userInfo)}}
}
</script>
  • Home.vue(demo中的首页)
<template><el-row ><el-col :span="24" class="disc"><h3>关于本DEMO</h3><div>后端工程师写vue之路。</div><div>使用vue、element ui作为基础的脚手架。在这个基础上进一步的做了优化,使得在以后得开发过程中只关注业务,不需要考虑整体的结构。</div></el-col><el-col :span="24" class="disc"><h3>启动</h3><div>npm run serve 默认启动<br>npm run serve-dev  启动dev环境<br>npm run serve-local  启动local环境</div></el-col><el-col :span="24" class="disc"><h3>打包</h3><div>npm run build 全部工程打包<br>npm run build-test demo 指定环境和项目打包<br>npm run build-prod demo 指定环境和项目打包</div></el-col></el-row>
</template><script>
export default {
}
</script>
<style>
.disc {padding-left: 10px
}
</style>
  • Login.vue
<template><div class="login-main"><el-row class="login"><el-col :span="4" :offset="6"><div class="login-info"><div>VUE</div><div>VUEX</div><div>router</div><div>element UI</div><div>echarts</div><div>......</div></div></el-col><el-col :span="6" :offset="3"><div class="login-div"><h3>登录</h3><el-form :model="login" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm"><el-form-item label="用户名称" prop="name"><el-input v-model="login.name" ></el-input></el-form-item><el-form-item label="登录密码" prop="pwd"><el-input v-model="login.pwd"></el-input></el-form-item><el-form-item><el-button type="success" @click="updateUser('ruleForm')">模拟登录</el-button><el-button @click="resetForm('ruleForm')">重置</el-button></el-form-item></el-form></div></el-col></el-row></div>
</template>
<script>
export default {data () {return {'login': {'name': '','pwd': ''},rules: {name: [{ required: true, message: '请输入用户名称', trigger: 'blur' },{ min: 5, max: 20, message: '长度在 5 到 20 个字符', trigger: 'blur' }],pwd: [{ required: true, message: '请输入密码', trigger: 'blur' },{ min: 6, max: 20, message: '长度在 6 到 20 个字符', trigger: 'blur' }]}}},methods: {updateUser (formName) {this.$refs[formName].validate((valid) => {if (valid) {let userInfo = {name: this.login.name,img: 'https://raw.githubusercontent.com/taylorchen709/markdown-images/master/vueadmin/user.png'}this.$store.commit('login', userInfo)// 如果存在参数if (this.$route.query.redirect) {let redirect = this.$route.query.redirect// 则跳转至进入登录页前的路由this.$router.push(redirect)} else {// 否则跳转至首页this.$router.push('/main/home')}} else {console.log('error submit!!')return false}})},resetForm (formName) {this.$refs[formName].resetFields()}}
}
</script>
<style>
.login-main{width: 100%;height: 100%;
}
.login{margin-top: 15%;background-color: #67C23A
}
.login-info{height: 100%;padding: 20px 0 0 0;
}
.login-info>div{margin-bottom: 20px;font-size: 20px;
}
.login-div{padding: 20px 60px 40px 40px;background-color: #eef1f6
}body{margin: 0px;}
</style>
  • MyMain.vue
<template><div id="app"><Home :sysName='sysName' :userInfo='userInfo' :menuJson='menuJson' @logoutHandle='logoutHandle'/><!-- <router-view/> --></div>
</template>
<script>
import Home from '@/components/Home.vue'
import axios from '../utils/http'
// 用户
// let userInfo = {
//   name: '苏三杰',
//   img: 'https://raw.githubusercontent.com/taylorchen709/markdown-images/master/vueadmin/user.png'
// }
// 系统名称
let sysName = 'WXD-DEMO'
// 菜单
let menuJson = [{id: '1',name: '首页',type: 'menu-item',url: '/main/home',icon: 'el-icon-star-off',submenus: []},{id: '2',name: 'TableS',type: 'subMenu',url: '',icon: 'el-icon-s-grid',submenus: [{id: '3',name: '动态table',type: 'subMenu',url: '/main/about',icon: ''},{id: '4',name: '拖拽table',type: 'subMenu',url: '/main/about1',icon: ''},{id: '5',name: '综合table',type: 'subMenu',url: '/main/about2',icon: ''}]},{id: '6',name: '列表demo',type: 'subMenu',url: '',icon: 'el-icon-user',submenus: [{id: '7',name: '用户列表',type: 'subMenu',url: '/main/user',icon: ''},{id: '8',name: '订单列表',type: 'subMenu',url: '/main/order',icon: ''}]},{id: '9',name: '工具demo',type: 'subMenu',url: '',icon: 'el-icon-setting',submenus: [{id: '10',name: '常用报表',type: 'subMenu',url: '/main/echarts',icon: ''},{id: '11',name: '常用图标',type: 'subMenu',url: '/main/ioc',icon: ''},{id: '12',name: '导出demo',type: 'subMenu',url: '/main/export',icon: ''}]}
]export default {components: {Home},data () {return {// 'userInfo': this.$store.state.userInfo,'sysName': sysName,'menuJson': menuJson}},computed: {'userInfo': function () {return this.$store.state.userInfo}},methods: {logoutHandle: function () {// TODOconsole.log('退出')this.$store.commit('login', {})this.$router.push({ 'path': '/login' })},testApi: function () {// http://10.98.3.27:8080/app/mock/data/139axios.get('http://10.98.3.27:8080/app/mock/data/139').then(response => {console.info(response)console.info(response.data)}).catch(error => {console.log(error)}).finally(() => console.log('finally'))}},created: function () {// this.testApi()// this.$router.push({ 'path': '/login' })console.log(this.$store.state)}
}
</script>
<style>
</style>
  • Order.vue
<template><CommonPage :formEntity="formEntity" :queryFunction="queryF" :tableEntity="tableEntity" :buttons="buttons"></CommonPage>
</template>
<script>
import CommonPage from '@/components/CommonPage.vue'
// 查询表单数组
let formEntityDemo = [{template: 'input',type: 'string',name: 'name',label: '用户名',placeholder: '用户名'},{template: 'input',type: 'number',name: 'age',label: '年龄',placeholder: '年龄'},{template: 'date',type: 'date',name: 'birthday',label: '生日',placeholder: '生日'},{template: 'date',type: 'month',name: 'month',label: '月份',placeholder: '月份'},{template: 'date',type: 'monthrange',name: 'monthrange',label: '月份区间','range-separator': '至','start-placeholder': '开始月份','end-placeholder': '结束月份',placeholder: '月份区间'},{template: 'date',type: 'daterange',name: 'qutime',label: '日期区间','start-placeholder': '开始日期','end-placeholder': '结束日期','default-time': ['00:00:00', '23:59:59'],placeholder: '日期区间'},{template: 'select',type: 'select',name: 'region',label: '活动区域',placeholder: '活动区域',options: [{label: '区域一',value: 'shanghai'},{label: '区域二',value: 'beijing'},{label: '区域三',value: 'shanxi'}]}
]
// 数据列表
let users = [{'id': 1,'name': '刘娟','sex': 1,'age': 23,'addr': '香港特别行政区 新界 西贡区','orderNo': '001','amount': 200},{'id': 1,'name': '刘娟','sex': 0,'age': 23,'addr': '香港特别行政区 新界 西贡区','orderNo': '002','amount': 200},{'id': 1,'name': '刘娟','sex': 1,'age': 23,'addr': '香港特别行政区 新界 西贡区','orderNo': '003','amount': 200},{'id': 1,'name': '刘娟','sex': 0,'age': 23,'addr': '香港特别行政区 新界 西贡区','orderNo': '004','amount': 200},{'id': 1,'name': '刘娟','sex': 1,'age': 23,'addr': '香港特别行政区 新界 西贡区','orderNo': '005','amount': 200},{'id': 1,'name': '刘娟','sex': 1,'age': 23,'addr': '香港特别行政区 新界 西贡区','orderNo': '006','amount': 200},{'id': 1,'name': '刘娟','sex': 0,'age': 23,'addr': '香港特别行政区 新界 西贡区','orderNo': '007','amount': 200},{'id': 1,'name': '刘娟','sex': 1,'age': 23,'addr': '香港特别行政区 新界 西贡区','orderNo': '008','amount': 200},{'id': 1,'name': '刘娟','sex': 0,'age': 23,'addr': '香港特别行政区 新界 西贡区','orderNo': '009','amount': 200},{'id': 1,'name': '刘娟','sex': 1,'age': 23,'addr': '香港特别行政区 新界 西贡区','orderNo': '010','amount': 200},{'id': 1,'name': '刘娟','sex': 1,'age': 23,'addr': '香港特别行政区 新界 西贡区','orderNo': '011','amount': 200},{'id': 1,'name': '刘娟','sex': 0,'age': 23,'addr': '香港特别行政区 新界 西贡区','orderNo': '012','amount': 200},{'id': 1,'name': '刘娟','sex': 1,'age': 23,'addr': '香港特别行政区 新界 西贡区','orderNo': '012','amount': 200},{'id': 1,'name': '刘娟','sex': 0,'age': 23,'addr': '香港特别行政区 新界 西贡区','orderNo': '012','amount': 200},{'id': 1,'name': '刘娟','sex': 1,'age': 23,'addr': '香港特别行政区 新界 西贡区','orderNo': '012','amount': 200},{'id': 1,'name': '刘娟','sex': 1,'age': 23,'addr': '香港特别行政区 新界 西贡区','orderNo': '012','amount': 200},{'id': 1,'name': '刘娟','sex': 1,'age': 23,'addr': '香港特别行政区 新界 西贡区','orderNo': '012','amount': 200},{'id': 1,'name': '刘娟','sex': 1,'age': 23,'addr': '香港特别行政区 新界 西贡区','orderNo': '012','amount': 200},{'id': 1,'name': '刘娟','sex': 1,'age': 23,'addr': '香港特别行政区 新界 西贡区','orderNo': '012','amount': 200},{'id': 1,'name': '刘娟','sex': 1,'age': 23,'addr': '香港特别行政区 新界 西贡区','orderNo': '012','amount': 200}
]
// 列表属性
let tableDemo = {page: {currentPage: 1,total: 1400,// 改变每页记录数handleSizeChange: (size) => {console.log('order页面' + size)},// 点击其他页面handleCurrentChange: (currentPage) => {console.log('order页面' + currentPage)}},options: {// 数据'datas': users,// 表格属性tableAttrs: {'size': 'small','border': true},// 表格事件tableEvents: {'select': function (selection, row) {console.log(selection)console.log('order页面' + selection)}},// 列 不包括操作列columns: [{'type': 'selection','width': '55'},{'type': 'index','label': '序号','width': '60'},{'prop': 'orderNo','label': '订单号','width': '120'},{'prop': 'amount','label': '金额','width': '120'},{'prop': 'name','label': '姓名','width': '120'},{'prop': 'sex','label': '性别','width': '120','formatter': function (row, column) {return row.sex === 1 ? '男' : row.sex === 0 ? '女' : '未知'}},{'prop': 'age','label': '年龄','width': '120'},{'prop': 'addr','label': '收货地址','width': '250'}],// 操作列operationColumn: [{'label': '编辑','type': 'primary','callback': (index, row) => {console.log(row)}},{'label': '查看','type': 'danger','callback': (index, row) => {console.log(row)}}]}
}
// 按钮
let buttons = [{'label': '添加订单','type': 'primary','callback': () => {console.log('添加订单')}},{'label': '修改订单','type': 'warning','callback': () => {console.log('修改订单')}},{'label': '删除订单','type': 'danger','callback': () => {console.log('删除订单')}},{'label': '订单详情','type': 'info','callback': () => {console.log('订单详情')}}
]
export default {components: {CommonPage},data () {return {formEntity: formEntityDemo,tableEntity: tableDemo,buttons: buttons}},methods: {// 查询方法queryF: function (a) {// 查询的实体console.log(a)}}
}
</script>
  • User.vue
<template><div><el-row :gutter="10"><el-col :span="24"><div  class="bg-purple-dark"><el-form :inline="true" :model="formInline"><el-form-item label="用户名"><el-input v-model="formInline.user" size="small" placeholder="用户名"></el-input></el-form-item><el-form-item label="用户名"><el-input v-model="formInline.user" size="small" placeholder="用户名"></el-input></el-form-item><el-form-item label="用户名"><el-input v-model="formInline.user" size="small" placeholder="用户名"></el-input></el-form-item><el-form-item label="用户名"><el-input v-model="formInline.user" size="small" placeholder="用户名"></el-input></el-form-item><el-form-item label="用户名"><el-input v-model="formInline.user" size="small" placeholder="用户名"></el-input></el-form-item><el-form-item label="活动区域"><el-select v-model="formInline.region" size="small" placeholder="活动区域"><el-option label="区域一" value="shanghai"></el-option><el-option label="区域二" value="beijing"></el-option></el-select></el-form-item><el-form-item><el-button type="primary" size="small">查询</el-button></el-form-item></el-form></div></el-col></el-row><el-row><el-button plain size="small">朴素按钮</el-button><el-button type="primary" plain size="small" @click="userAdd">添加用户</el-button><el-button type="success" plain size="small">成功按钮</el-button><el-button type="info" plain size="small">信息按钮</el-button><el-button type="warning" plain size="small">警告按钮</el-button><el-button type="danger" plain size="small" @click="userDel">删除用户</el-button></el-row><el-row><Table v-bind="options"><el-table-column label="操作" width="150"><template scope="scope"><el-button size="mini" @click="handleEdit(scope.$index, scope.row)">编辑</el-button><el-button plain type="danger" size="mini" @click="handleDel(scope.$index, scope.row)">删除</el-button></template></el-table-column></Table></el-row><el-row style="background: #f2f2f2;"><div  class="bg-purple-dark"><Page:currentPage="currentPage":total="total"@handleSizeChange="handleSizeChange"@handleCurrentChange="handleCurrentChange"/></div></el-row><UserAdd  ref="userAddView" :pdialogFormVisible="pdialogFormVisible"/></div>
</template>
<script>
import Table from '@/components/Table.vue'
import Page from '@/components/Page.vue'
import UserAdd from './UserAdd.vue'
let users = [{'id': 1,'name': '刘娟','sex': 1,'age': 23,'addr': '香港特别行政区 新界 西贡区'},{'id': 1,'name': '刘娟','sex': 0,'age': 23,'addr': '香港特别行政区 新界 西贡区'},{'id': 1,'name': '刘娟','sex': 1,'age': 23,'addr': '香港特别行政区 新界 西贡区'},{'id': 1,'name': '刘娟','sex': 0,'age': 23,'addr': '香港特别行政区 新界 西贡区'},{'id': 1,'name': '刘娟','sex': 1,'age': 23,'addr': '香港特别行政区 新界 西贡区'},{'id': 1,'name': '刘娟','sex': 1,'age': 23,'addr': '香港特别行政区 新界 西贡区'},{'id': 1,'name': '刘娟','sex': 0,'age': 23,'addr': '香港特别行政区 新界 西贡区'},{'id': 1,'name': '刘娟','sex': 1,'age': 23,'addr': '香港特别行政区 新界 西贡区'},{'id': 1,'name': '刘娟','sex': 0,'age': 23,'addr': '香港特别行政区 新界 西贡区'},{'id': 1,'name': '刘娟','sex': 1,'age': 23,'addr': '香港特别行政区 新界 西贡区'},{'id': 1,'name': '刘娟','sex': 1,'age': 23,'addr': '香港特别行政区 新界 西贡区'},{'id': 1,'name': '刘娟','sex': 0,'age': 23,'addr': '香港特别行政区 新界 西贡区'},{'id': 1,'name': '刘娟','sex': 1,'age': 23,'addr': '香港特别行政区 新界 西贡区'},{'id': 1,'name': '刘娟','sex': 0,'age': 23,'addr': '香港特别行政区 新界 西贡区'},{'id': 1,'name': '刘娟','sex': 1,'age': 23,'addr': '香港特别行政区 新界 西贡区'}
]
// let selectedIds = []
export default {components: {Table,Page,UserAdd},data () {var _this = thisreturn {pdialogFormVisible: false,currentPage: 4,total: 1400,selectedIds: [],formInline: {user: '',region: ''},options: {'datas': users,tableAttrs: {'size': 'small','border': true},tableEvents: {'select': function (selection, row) {_this.selectedIds = selection.map(u => {return u.id})}},columns: [{'type': 'selection','width': '55'},{'type': 'index','label': '序号','width': '60'},{'prop': 'name','label': '姓名','width': '120'},{'prop': 'sex','label': '性别','width': '120','formatter': function (row, column) {return row.sex === 1 ? '男' : row.sex === 0 ? '女' : '未知'}},{'prop': 'age','label': '年龄','width': '120'},{'prop': 'addr','label': '地址','width': '250'}]}}},methods: {userDel () {// 获取选中的用户idif (this.selectedIds.length === 0) {this.$alert('请选择要删除的用户', '提示', {confirmButtonText: '确定',callback: function () {// do something}})return}this.$confirm('此操作将永久删除该用户, 是否继续?', '提示', {confirmButtonText: '确定',cancelButtonText: '取消',type: 'warning'}).then(() => {// 正真的删除this.$message({type: 'success',message: '删除成功!'})}).catch(() => {this.$message({type: 'info',message: '已取消删除'})})},userAdd () {this.$refs.userAddView.opendialog()// this.pdialogFormVisible = true// console.log(this.pdialogFormVisible)},handleEdit: function (index, row) {console.log(index)console.log(row)},handleSizeChange (val) {console.log('每页 条' + val)},handleCurrentChange (val) {console.log('当前页: ' + val)},setSelectedIds (ids) {this.selectedIds = ids}}
}
</script>
<style scoped>.bg-purple-dark {border-radius: 4px;background: #EEF1F6;padding: 10px;}.el-form-item {margin: 5px;}.el-row {margin-bottom: 5px;}
</style>
  • UserAdd.vue
<template><el-dialog title="收货地址" :visible.sync="dialogFormVisible"><el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm"><el-form-item label="活动名称" prop="name"><el-input v-model="ruleForm.name"></el-input></el-form-item><el-form-item label="活动区域" prop="region"><el-select v-model="ruleForm.region" placeholder="请选择活动区域"><el-option label="区域一" value="shanghai"></el-option><el-option label="区域二" value="beijing"></el-option></el-select></el-form-item><el-form-item label="活动时间" required><el-col :span="11"><el-form-item prop="date1"><el-date-picker type="date" placeholder="选择日期" v-model="ruleForm.date1" style="width: 100%;"></el-date-picker></el-form-item></el-col><el-col class="line" :span="2">-</el-col><el-col :span="11"><el-form-item prop="date2"><el-time-picker placeholder="选择时间" v-model="ruleForm.date2" style="width: 100%;"></el-time-picker></el-form-item></el-col></el-form-item><el-form-item label="即时配送" prop="delivery"><el-switch v-model="ruleForm.delivery"></el-switch></el-form-item><el-form-item label="活动性质" prop="type"><el-checkbox-group v-model="ruleForm.type"><el-checkbox label="美食/餐厅线上活动" name="type"></el-checkbox><el-checkbox label="地推活动" name="type"></el-checkbox><el-checkbox label="线下主题活动" name="type"></el-checkbox><el-checkbox label="单纯品牌曝光" name="type"></el-checkbox></el-checkbox-group></el-form-item><el-form-item label="特殊资源" prop="resource"><el-radio-group v-model="ruleForm.resource"><el-radio label="线上品牌商赞助"></el-radio><el-radio label="线下场地免费"></el-radio></el-radio-group></el-form-item><el-form-item label="活动形式" prop="desc"><el-input type="textarea" v-model="ruleForm.desc"></el-input></el-form-item></el-form><div slot="footer" class="dialog-footer"><el-button @click="dialogFormVisible = false">取 消</el-button><el-button @click="resetForm('ruleForm')">重置</el-button><el-button type="primary" @click="submitForm('ruleForm')">确 定</el-button></div></el-dialog>
</template>
<script>
export default {props: ['pdialogFormVisible'],data () {return {'dialogFormVisible': this.pdialogFormVisible,ruleForm: {name: '',region: '',date1: '',date2: '',delivery: false,type: [],resource: '',desc: ''},rules: {name: [{ required: true, message: '请输入活动名称', trigger: 'blur' },{ min: 3, max: 5, message: '长度在 3 到 5 个字符', trigger: 'blur' }],region: [{ required: true, message: '请选择活动区域', trigger: 'change' }],date1: [{ type: 'date', required: true, message: '请选择日期', trigger: 'change' }],date2: [{ type: 'date', required: true, message: '请选择时间', trigger: 'change' }],type: [{ type: 'array', required: true, message: '请至少选择一个活动性质', trigger: 'change' }],resource: [{ required: true, message: '请选择活动资源', trigger: 'change' }],desc: [{ required: true, message: '请填写活动形式', trigger: 'blur' }]}}},methods: {submitForm (formName) {this.$refs[formName].validate((valid) => {if (valid) {alert('submit!')this.dialogFormVisible = false} else {console.log('error submit!!')return false}})},resetForm (formName) {this.$refs[formName].resetFields()},opendialog () {if (this.dialogFormVisible) {return}this.dialogFormVisible = true}},created () {}
}
</script>

OK、主要的代码就完成了。
启动后的效果图:


以上就完成了一个简单的demo。

源码地址:https://github.com/1065744299/vue-elment-ui

如果对你有帮助,可以请作者喝杯咖啡:

vue2+element ui相关推荐

  1. vue2+element ui 导入和导出后端传过来的文件

    结合element-ui Upload 上传组件 (官网地址:https://element.eleme.io/#/zh-CN/component/upload) 导入/上传 默认版:只需填入地址参数 ...

  2. element ui - el-select 添加可输入功能

    element ui - el-select 可以支持输入功能 场景 思路 方法 场景 vue2 + element ui 的项目中,产品希望 el-select 可以支持输入功能,也就说用户既可以下 ...

  3. DataGear 制作基于Vue2、Element UI前端框架的数据可视化看板

    DataGear 数据可视化看板内置了一些基本.简单的页面交互组件,当它们无法满足实际看板需求时,可以引入更流行和强大的前端框架. 本文以Vue2.Element UI前端框架为例,介绍如何制作具有更 ...

  4. vue2.x 音频播放器 使用element ui + Audio实现一款完整的音频播放器

    项目背景 audio 音频播放在多媒体开发中非常常见,但是实际项目中你就会发现,每个系统的audio音频界面都长的不一样,百花齐放... pw怎么会同意呢[哈哈],马上掏出手机,你改成长这个样子就好了 ...

  5. vue2.0 + element ui 实现表格穿梭框

    element ui 官网里介绍了穿梭框(Transfer),但在实际使用过程中,会出现一些问题: 1.穿梭框里能放置的内容太少,不能满足复杂的业务需求. 2.当选项过多时,穿梭框很难实现分页,左右两 ...

  6. VUE2版本引入Element UI

    一句话的事儿 1,在cmd中打开vue项目文件夹,输入命令: vue add element 2,加载后的选项如下: How do you want to import Element? Fully ...

  7. vue2 - 基于Element UI实现上传Excel表单数据功能

    一.项目场景 批量数据上传后台,需要从后台下载一个固定格式的 Excel表格,然后在表格里面添加数据,将数据格式化,再上传给后台,后台做解析处理,往数据库添加数据 二.实现功能展示 点击导入excel ...

  8. vue2引入Element UI的详细步骤

    目录 一.Element UI介绍 Element UI的特点: vue3引入Element plus的文章: 二.操作步骤 三.快速上手测试(可做可不做) 一.Element UI介绍 Elemen ...

  9. 基于vue2.x和element ui的达达尼可采购平台

    1. 项目实现 达达尼可采购平台最终目标是做成类似间采通.慧聪网.1688采购等b2b平台,但最终并未完成 具体详情请访问www.bixiaoyi.cn -项目主要分为用户注册登陆.企业用户主体和公司 ...

最新文章

  1. 模块化的 Windows 7
  2. 转:Oracle 应用服务器 MapViewer 10.1.2截图
  3. Vue2.0 入门 安装Vue-cli
  4. createbitmap 旋转90度_小学数学,图形的运动,平移与旋转
  5. 语言孪生素数问题_刘建亚教授讲述“素数的故事”
  6. iOS开发-OC语言 (七)继承、多态、类别
  7. ask的matlab代码,二进制ASK调制matlab仿真代码
  8. 斐波那契数列(java)
  9. ggplot2|详解八大基本绘图要素,你需要的都在这-目录版
  10. 星浩资本-以流程为中心
  11. English - Grammar(未完)
  12. 提供在Linux上运行最新版腾讯QQ与TIM的解决方案 Easiest Way to Run QQTIM on Linux
  13. 激活windows系列地址
  14. R语言使用cph函数和rcs函数构建限制性立方样条cox回归模型、使用anova函数进行方差分析通过p值确认指定连续变量和风险值HR之间是否存在非线性关系
  15. 面试小结一:关于操作系统的面试题整理
  16. 正式-日常作息(2020.11)
  17. 在Windows 2003下安装ZoneAlarm Pro 7
  18. 2020数模国赛c题论文latex
  19. 360移动开发者平台上架App
  20. 携手唐天下:牛气冲天创富无限,赢2021网络营销

热门文章

  1. 北大青鸟培训第四天:HTML和CSS相关知识 (持续更新)
  2. 机器学习之局部加权、岭回归和前向逐步回归
  3. 有关游戏配音的小知识
  4. Part 14  PhilClaire
  5. WIN10+CUDA 10.2+CUDNN v8.0安装配置
  6. HTTP请求工具类,支持https
  7. python群发邮件并将excel附件添加到正文
  8. 解决小新Air指纹识别失效问题
  9. Zend_Registry
  10. shopeeman智能多店软件教你Shopee本土多店铺商品管理操作方法