*vue知识点
*创建vue脚手架
=>安装npm
=>安装node.js
=>安装vue-cli
npm install vue-cli -g //全局安装 vue-cli
=>创建 vue create ”项目名称“
=>运行vue项目 npm run serve
=>安装常用图标 npm install font—awesome
*vue项目通用
创建vue项目选择条件引用Element-UI时所用到通用部分
=>vue.config.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| let proxyObj = {};
proxyObj['/'] = { ws: false, target: 'http://dongeast.top:8181', changeOrigin: true, pathWewrite: { "^/": '/', } }
proxyObj['/ws'] = { ws: true, target: 'ws://dongeast.top:8181' };
module.exports = { devServer: { host: "localhost", port: 8080, proxy: proxyObj, } }
|
=>main.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| import Vue from 'vue' import App from './App.vue' import ElementUI from 'element-ui'; import router from './router' import 'element-ui/lib/theme-chalk/index.css';
Vue.config.productionTip = false Vue.use(ElementUI);
new Vue({ router, render: h => h(App), }).$mount('#app')
|
=>router.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| import Vue from 'vue' import VueRouter from 'vue-router' import Login from '../views/Login'
Vue.use(VueRouter)
const routes = [{ path:'/', name:'Login', component:Login, children: [
{ path: '/adminInfo', name: '个人中心', component: AdminInfo }] }, ..., ..., ..., ] const router = new VueRouter({ routes }) const originalPush = VueRouter.prototype.push; VueRouter.prototype.push = function push(location) { return originalPush.call(this, location).catch((err) => err); }; export default router
|
=>api.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
| import axios from 'axios'; import { Loading, Message } from 'element-ui' import router from '../router';
axios.interceptors.request.use(success => { if (window.sessionStorage.getItem('tokenStr')) { success.headers['Authorization'] = window.sessionStorage.getItem('tokenStr'); } return success; }, error => { console.log(error); })
axios.interceptors.response.use(success=>{ if(success.status && success.status == 200){ if(success.data.code == 500 || success.data.code == 401 || success.data.code == 403){ Message.error({message:success.data.message}); return; } if(success.data.message){ Message.success({message:success.data.message}) } } return success.data; },error =>{ if(error.response.code == 504 || error.response.code == 404){ Message.error({Message:'服务器错误!'}); }else if(error.response.code == 403){ Message.error({message:'权限不足,请联系管理员!'}) }else if(error.response.code == 401){ Message.error({message:'尚未登录,请登录!'}) router.replace('/'); }else{ if(error.response.data.message){ Message.error({message:error.response.data.message}) }else{ Message.error({message:'未知错误!'}); } } return; });
let base = '';
export const postRequest = (url,params)=>{ return axios({ method:'post', url:`${base}${url}`, data:params }) }
export const putRequest = (url, params) => { return axios({ method: 'put', url: `${base}${url}`, data: params }) }
export const getRequest = (url, params) => { return axios({ method: 'get', url: `${base}${url}`, data: params, }) }
export const deleteRequest = (url, params) => { return axios({ method: 'delete', url: `${base}${url}`, params, }) }
|
=>App.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <template> <div id="app"> <router-view /> <!-- 默认跳转 --> </div> </template>
<script> export default { name: 'App'
} </script> <style>
</style>
|
*选择导航器
menu.js部分
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| import { getRequest } from "./api";
export const initMenu = (router, store) => { if (store.state.routes.length > 0) { return; } getRequest("/system/cfg/menu").then(data => { if (data) { let fmtRoutes = formatRoutes(data); router.addRoutes(fmtRoutes); store.commit('initRoutes', fmtRoutes); } }) }
export const formatRoutes = (routes) => { let fmtRoutes = []; routes.forEach(router => { let { path, component, name, iconCls, children } = router; if (children && children instanceof Array) { children = formatRoutes(children); } let fmRouter = { path: path, name: name, iconCls: iconCls, children: children, component(resolve) { if (component.startsWith('Home')) { require(['../views/' + component + '.vue'], resolve); } else if (component.startsWith('Emp')) { require(['../views/emp/' + component + '.vue'], resolve); } else if (component.startsWith('Per')) { require(['../views/per/' + component + '.vue'], resolve); } else if (component.startsWith('Sal')) { require(['../views/sal/' + component + '.vue'], resolve); } else if (component.startsWith('Sta')) { require(['../views/sta/' + component + '.vue'], resolve); } else if (component.startsWith('Sys')) { require(['../views/sys/' + component + '.vue'], resolve); } } } fmtRoutes.push(fmRouter) }); return fmtRoutes; }
|
vue部分
①不定死(推荐)(首页左侧)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| <el-container> <el-aside width="200px"> <el-menu router unique-opened><!-- 默认不展开列表 --> <el-submenu :index="index + ''" v-for="(item, index) in routes" :key="index"> <template slot="title"> <i :class="item.iconCls" style="color: skyblue; margin-right: 5px"></i> <span>{{ item.name }}</span> </template> <el-menu-item :index="children.path" v-for="(children, indexj) in item.children" :key="indexj"> {{ children.name }} </el-menu-item> </el-submenu> </el-menu> </el-aside> <el-main> <el-breadcrumb v-if="this.$router.currentRoute.path != '/home'"> <el-breadcrumb-item :to="{path:'/home'}">首页</el-breadcrumb-item> <el-breadcrumb-item>{{this.$router.currentRoute.name}}</el-breadcrumb-item> </el-breadcrumb> <div class="homeWelcome" v-if="this.$router.currentRoute.path == '/home'"> 欢迎来到云E办系统! </div> <router-view class="homeRouterView"></router-view> </el-main> </el-container> export default { name:'Home', computed:{ routes(){ return this.$store.state.routes; } } }
|
②定死(不推荐)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| <el-container> <el-aside width="200px"> <el-menu @select="menuClick"> <!-- 菜单点击事件 --> <el-submenu index="1"> <template slot="title"><i class="el-icon-location"></i>导航一</template> <el-menu-item-group> <el-menu-item index="/adminInfo">选项1</el-menu-item> <el-menu-item index="1-2">选项2</el-menu-item> </el-menu-item-group> </el-submenu> </el-menu> </el-aside> <el-main> <router-view /> </el-main> </el-container> methods:{ menuClick(index){ this.$router.push(index) } }
|
*图标
=>安装 npm install font—awesome 或 npm install font-awesome —save
在main.js添加
1
| import 'font-awesome/css/font-awesome.css'
|
在vue中添加
1 2 3 4 5
| <template slot="title"> <i :class="item.iconCls" style="color: skyblue; margin-right: 5px"></i> <!-- :class="item.iconCls"绑定数据库里的图标 --> <span>{{ item.name }}</span> </template>
|
*登录功能
*规则问题:输入框提示为空
1 2 3 4 5 6 7 8 9 10
| <el-form :rules="rules" v-loading="loading" ref="loginForm" :model="loginForm" class="loginContainer"> 出现红色提示为空 </el-form> data(){ rules:{ username:[{required:true,message:'请输入用户名',trigger:'blur'}], password:[{required:true,message:'请输入密码',trigger:'blur'}], code:[{required:true,message:'请输入验证码',trigger:'blur'}], } }
|
*获取用户登录信息
main.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| router.beforeEach((to, from, next) => { if (window.sessionStorage.getItem('tokenStr')) { initMenu(router, store); if (!window.sessionStorage.getItem('user')) { return getRequest('/admin/info').then(resp => { if (resp) { window.sessionStorage.setItem('user', JSON.stringify(resp)); store.commit("INIT_ADMIN", resp); next(); } }); } next(); } else { if (to.path == '/') { next(); } else { next('/?redirect=' + to.path) } } })
|
vue部分
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| <el-header class="homeHeader"> <div class="title">云E办</div> <div> <el-dropdown class="userInfo" @command="commandHandler"> <span class="el-dropdown-link"> {{user.name}}<i><img :src="user.userFace"></i> </span> <el-dropdown-menu slot="dropdown"> <el-dropdown-item command="userinfo">个人中心</el-dropdown-item> <el-dropdown-item command="setting">设置</el-dropdown-item> <el-dropdown-item command="logout">注销登录</el-dropdown-item> </el-dropdown-menu> </el-dropdown> </div> </el-header> data(){ return{ user:JSON.parse(window.sessionStorage.getItem('user')) } }, computed:{ routes(){ return this.$store.state.routes; } }, methods:{ commandHandler(command){ if(command == 'logout'){ this.$confirm('此操作将注销登录, 是否继续?', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(() => { //注销登录 this.postRequest('/logout'); window.sessionStorage.removeItem('tokenStr'); window.sessionStorage.removeItem('user'); //清空菜单 this.$store.commit('initRoutes',[]); //跳转登录页面 this.$router.replace('/') }).catch(() => { this.$message({ type: 'info', message: '已取消操作' }); }); } } }
|
*主界面
*面包屑
1 2 3 4 5 6 7 8 9
| <el-breadcrumb v-if="this.$router.currentRoute.path != '/home'"><!-- 判断书否为首页,如果是则不展示面包屑 --> <el-breadcrumb-item :to="{path:'/home'}">首页</el-breadcrumb-item> <!-- 当前路由名称 --> <el-breadcrumb-item>{{this.$router.currentRoute.name}}</el-breadcrumb-item> </el-breadcrumb> <div class="homeWelcome" v-if="this.$router.currentRoute.path == '/home'"> 欢迎来到云E办系统! </div> <router-view class="homeRouterView"></router-view>
|
*login.vue
1 2 3 4 5 6 7 8 9 10 11
| this.postRequest('/login',this.loginForm).then(resp=>{ if(resp){ this.loading = false; //存储用户token const tokenStr = resp.obj.tokenHead + resp.obj.token; window.sessionStorage.setItem('tokenStr',tokenStr); //页面跳转首页 let path = this.$router.replace('/home'); this.$$router.replace((path=='/'||path==undefined)?'/home': path) } })
|
*选择框
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| <el-select size="small" v-model="jl.titleLevel" placeholder="职称等级" style="margin-left: 10px; margin-right: 10px"> <el-option v-for="item in titleLevels" :key="item" :label="item" :value="item"> </el-option> data() { return { jl: { name: "", titleLevel: "", }, titleLevels: ["正高级", "副高级", "中级", "初级", "员级"], }, }
|
*组件
1 2 3 4 5
| @keydown.enter.native='事件' 键盘事件 icon="图标" 添加图标 placeholder="请输入中文名" 提示内容 size="mini" 变小输入框 :title="数据" 动态绑定标题
|
1 2 3
| show-checkbox 默认选中子节点 :key="index" key绑定的是index索引值,索引变化,key也会改变 :props=" " 组件数据的一个字段,期望从父组件传下来
|