wordpress模板 门户网站,怎么建立挣流量的网站,百度网站上做推广受骗,刚成立公司如何做网站Vue2项目练手——通用后台管理项目 用户管理分页使用的组件Users.vuemock.js 关键字搜索区Users.vue 权限管理登录页面样式修改Login.vue 登录权限使用token对用户鉴#xff0c;使用cookie对当前信息保存#xff08;类似localstorage#xff09;Login.vuerouter/index.js 登… Vue2项目练手——通用后台管理项目 用户管理分页使用的组件Users.vuemock.js 关键字搜索区Users.vue 权限管理登录页面样式修改Login.vue 登录权限使用token对用户鉴使用cookie对当前信息保存类似localstorageLogin.vuerouter/index.js 登录接口逻辑实现使用的组件permission.jsmock.jsapi/index.jsLogin.vueCommonHeader.vue 用户管理
分页
使用的组件 Users.vue
新增的代码 div classcommon-tableel-tablestripeheight90%:datatableDatastylewidth: 100%el-table-columnpropnamelabel姓名/el-table-columnel-table-columnpropagelabel年龄/el-table-columnel-table-columnpropsexlabel性别!--自定义列使用插槽的方式element-ui上面有提供--template slot-scopescopespan{{ scope.row.sex1?男:女 }}/span/template/el-table-columnel-table-columnpropbirthlabel出生日期/el-table-columnel-table-columnpropaddrlabel地址/el-table-columnel-table-columnpropactionlabel操作!--自定义列使用插槽的方式element-ui上面有提供--template slot-scopescopeel-button sizemini clickhandleEdit(scope.row)编辑/el-buttonel-button sizemini clickhandleDelete(scope.row) typedanger删除/el-button/template/el-table-column/el-table!-- 分页--div classpagerel-paginationlayoutprev, pager, next:totaltotalcurrent-changehandleChange/el-pagination/div/divtotal:0, //当前的总条数pageData:{ //分页的page:1,limit:10}
getList(){//获取列表数据getUser({params:this.pageData}).then(({data}){console.log(data);this.tableDatadata.listthis.totaldata.count||0})},
//选择页码的回调函数handleChange(val){console.log(val)this.pageData.pagevalthis.getList()}style scoped langless
.manage{height: 90%;.common-table{position: relative;height: calc(100% - 62px);.pager{position: absolute;bottom: 0;right: 20px;}}
}
/stylemock.js
//若要传递参数使用正则方式
Mock.mock(/api\/user\/getUser/,user.getUserList)全部代码
import Mock from mockjs
import homeApi from /api/mockServeData/home;
import user from /api/mockServeData/user
/*//定义请求拦截
Mock.mock(/api/home/getData,function (){//拦截到请求后处理的逻辑console.log(拦截到了)
})*/
//定义请求拦截
Mock.mock(/api/home/getData,homeApi.getStatisticalData)//用户列表的数据
Mock.mock(/api/user/add,post,user.createUser)
Mock.mock(/api/user/edit,post,user.updateUser)
Mock.mock(/api/user/del,post,user.deleteUser)
//若要传递参数使用正则方式
Mock.mock(/api\/user\/getUser/,user.getUserList) 关键字搜索区
Users.vue
el-form :modeluserForm :inlinetrueel-form-itemel-input v-modeluserForm.name placeholder请输入名称 keyup.enteronSubmit/el-input/el-form-itemel-form-itemel-button typeprimary clickonSubmit查询/el-button/el-form-item/el-formuserForm:{name:}//封装获取列表的数据getList(){//获取列表数据getUser({params:{...this.userForm,...this.pageData}}).then(({data}){console.log(data);this.tableDatadata.listthis.totaldata.count||0})}//列表的查询onSubmit(){this.getList()}.manage-header{display: flex;justify-content: space-between;align-items: center;}全部代码
templatediv classmanageel-dialogtitle提示:visible.syncdialogVisiblewidth40%:before-closehandleClose!-- 用户的表单信息--el-form refform :inlinetrue :rulesrules :modelform label-width80pxel-form-item label姓名 propnameel-input v-modelform.name placeholder请输入姓名/el-input/el-form-itemel-form-item label年龄 propageel-input v-modelform.age placeholder请输入年龄/el-input/el-form-itemel-form-item label性别 propsexel-select v-modelform.sex placeholder请选择el-option label男 :value1/el-optionel-option label女 :value0/el-option/el-select/el-form-itemel-form-item label出生日期 propbirthel-date-pickertypedateplaceholder选择日期v-modelform.birth stylewidth: 100%;value-formatyyyy-MM-DD!-- 日期格式转变--/el-date-picker/el-form-itemel-form-item label地址 propaddrel-input v-modelform.addr placeholder请输入地址/el-input/el-form-item/el-formspan slotfooter classdialog-footerel-button clickcancel取 消/el-buttonel-button typeprimary clicksubmit确 定/el-button/span/el-dialogdiv classmanage-headerel-button typeprimary clickhandleAdd新增/el-button
!-- form搜索区--el-form :modeluserForm :inlinetrueel-form-itemel-input v-modeluserForm.name placeholder请输入名称 keyup.enteronSubmit clearable/el-input/el-form-itemel-form-itemel-button typeprimary clickonSubmit查询/el-button/el-form-item/el-form/divdiv classcommon-tableel-tablestripeheight90%:datatableDatastylewidth: 100%el-table-columnpropnamelabel姓名/el-table-columnel-table-columnpropagelabel年龄/el-table-columnel-table-columnpropsexlabel性别!--自定义列使用插槽的方式element-ui上面有提供--template slot-scopescopespan{{ scope.row.sex1?男:女 }}/span/template/el-table-columnel-table-columnpropbirthlabel出生日期/el-table-columnel-table-columnpropaddrlabel地址/el-table-columnel-table-columnpropactionlabel操作!--自定义列使用插槽的方式element-ui上面有提供--template slot-scopescopeel-button sizemini clickhandleEdit(scope.row)编辑/el-buttonel-button sizemini clickhandleDelete(scope.row) typedanger删除/el-button/template/el-table-column/el-table!-- 分页--div classpagerel-paginationlayoutprev, pager, next:totaltotalcurrent-changehandleChange/el-pagination/div/div/div/templatescript
import {addUser, getUser,editUser,delUser} from /api;export default {name: Users,data(){return {dialogVisible:false,form: {name: ,age: ,sex: ,birth: ,addr: ,},rules: {name: [{required: true, message: 请输入姓名}],age: [{required: true, message: 请输入年龄}],sex: [{required: true, message: 请选择性别}],birth: [{required: true, message: 请选择出生日期}],addr: [{required: true, message: 请输入地址}],},tableData: [],modalType:0, //0表示新增的弹窗1表示的是编辑total:0, //当前的总条数pageData:{ //分页的page:1,limit:10},userForm:{name:}}},methods:{//提交用户表单submit(){this.$refs.form.validate((valid){if(valid){// 后续对表单数据的处理console.log(this.form)if(this.modalType0){//新增addUser(this.form).then((){// 重新获取列表结果this.getList()})}else{// 编辑处理editUser(this.form).then((){// 重新获取列表结果this.getList()})}//清空表单数据this.$refs.form.resetFields()//关闭弹窗this.dialogVisiblefalse}})},//弹窗关闭的时候handleClose(){//清空表单this.$refs.form.resetFields()this.dialogVisiblefalse},cancel(){this.handleClose()},handleEdit(row){console.log(row,row)this.modalType1this.dialogVisibletrue//注意需要对当前行数据进行深拷贝否则会出错this.formJSON.parse(JSON.stringify(row))},handleDelete(row){this.$confirm(此操作将永久删除该文件, 是否继续?, 提示, {confirmButtonText: 确定,cancelButtonText: 取消,type: warning}).then(() {delUser({id:row.id}).then((){this.$message({type: success,message: 删除成功!});// 重新获取列表结果this.getList()})}).catch(() {this.$message({type: info,message: 已取消删除});});},//封装获取列表的数据getList(){//获取列表数据getUser({params:{...this.userForm,...this.pageData}}).then(({data}){console.log(data);this.tableDatadata.listthis.totaldata.count||0})},//新增的功能handleAdd(){this.modalType0this.dialogVisibletrue},//选择页码的回调函数handleChange(val){console.log(val)this.pageData.pagevalthis.getList()},//列表的查询onSubmit(){this.getList()}},mounted() {this.getList()}
}
/scriptstyle scoped langless
.manage{height: 90%;.manage-header{display: flex;justify-content: space-between;align-items: center;}.common-table{position: relative;height: calc(100% - 62px);.pager{position: absolute;bottom: 0;right: 20px;}}
}
/style 权限管理
登录页面
样式修改
Login.vue
templatediv idappdiv classmain-contentdiv classtitle系统登录/divdiv classcontentel-form label-width70px :inlinetrue :modelform status-icon :rulesrules refruleForm classdemo-ruleFormel-form-item label用户名 propusernameel-input v-modelform.username placeholder请输入账号/el-input/el-form-itemel-form-item label密码 proppasswordel-input v-modelform.password typepassword autocompleteoff placeholder请输入密码/el-input/el-form-itemel-form-itemel-button typeprimary clicksubmitForm(ruleForm)登录/el-button/el-col/el-form-item/el-form/div/div/div/templatescript
export default {name: login,data(){return{form: {username: ,password:},rules: {username: [{required: true, message: 请输入用户名, trigger: blur},{min: 3, max: 5, message: 长度在 3 到 5 个字符, trigger: blur}],password: [{required:true,message:请输入密码,trigger:blur}]}}},methods:{submitForm(formName) {this.$refs[formName].validate((valid) {if (valid) {console.log(ddddd)console.log(this.$router)// this.$router.push(/home)} else {console.log(error submit!!);return false;}});},}
}
/scriptstyle langless scoped
#app {display: flex;background-color: #333;height: 100vh;.main-content{height: 300px;width: 350px;//line-height: 100vh;background-color: #fff;margin: 200px auto;border-radius: 15px;padding: 35px 35px 15px 35px;box-sizing: border-box;box-shadow: 5px 5px 10px rgba(0,0,0,0.5),-5px -5px 10px rgba(0,0,0,0.5);.title{font-size: 20px;text-align: center;font-weight: 300;}.content{margin-top: 30px;}.el-input{width: 198px;}.el-button{margin-left: 105px;}}
}
/style 登录权限
使用token对用户鉴使用cookie对当前信息保存类似localstorage
安装cookie npm i js-cookie3.0.1 Login.vue
//登录submitForm(formName) {this.$refs[formName].validate((valid) {if (valid) {//token信息const tokenMock.Random.guid() //生成随机数//token信息存入cookie用于不同页面间的通信Cookie.set(token,token)//跳转到首页this.$router.push(/home)} else {console.log(error submit!!);return false;}});},全局代码
templatediv idappdiv classmain-contentdiv classtitle系统登录/divdiv classcontentel-form label-width70px :inlinetrue :modelform status-icon :rulesrules refruleForm classdemo-ruleFormel-form-item label用户名 propusernameel-input v-modelform.username placeholder请输入账号/el-input/el-form-itemel-form-item label密码 proppasswordel-input v-modelform.password typepassword autocompleteoff placeholder请输入密码/el-input/el-form-itemel-form-itemel-button typeprimary clicksubmitForm(ruleForm)登录/el-button/el-col/el-form-item/el-form/div/div/div/templatescript
import Mock from mockjs
import Cookie from js-cookie
export default {name: login,data(){return{form: {username: ,password:},rules: {username: [{required: true, message: 请输入用户名, trigger: blur},{min: 3, max: 5, message: 长度在 3 到 5 个字符, trigger: blur}],password: [{required:true,message:请输入密码,trigger:blur}]}}},methods:{//登录submitForm(formName) {this.$refs[formName].validate((valid) {if (valid) {//token信息const tokenMock.Random.guid() //生成随机数//token信息存入cookie用于不同页面间的通信Cookie.set(token,token)//跳转到首页this.$router.push(/home)} else {console.log(error submit!!);return false;}});},}
}
/scriptstyle langless scoped
#app {display: flex;background-color: #333;height: 100vh;.main-content{height: 300px;width: 350px;//line-height: 100vh;background-color: #fff;margin: 200px auto;border-radius: 15px;padding: 35px 35px 15px 35px;box-sizing: border-box;box-shadow: 5px 5px 10px rgba(0,0,0,0.5),-5px -5px 10px rgba(0,0,0,0.5);.title{font-size: 20px;text-align: center;font-weight: 300;}.content{margin-top: 30px;}.el-input{width: 198px;}.el-button{margin-left: 105px;}}
}
/style
router/index.js
//添加全局前置导航守卫
router.beforeEach((to,from,next){//判断token存不存在const tokenCookie.get(token)//token不存在说明当前用户是未登录应该跳转至登录页if(!tokento.name!login){next({name:login})}else if(token to.namelogin){ //token存在说明用户登录此时跳转至首页next({name:home})}else{next()}
})全部代码
import VueRouter from vue-router;
import Login from /pages/Login.vue;
import Users from /pages/Users.vue;
import Main from /pages/Main.vue
import Home from /pages/Home.vue;
import Mall from /pages/Mall.vue;
import PageOne from /pages/PageOne.vue;
import PageTwo from /pages/PageTwo.vue;
import Cookie from js-cookie;const router new VueRouter({// 浏览器模式设置设置为history模式// mode:history,routes:[{name:login,path:/login,component:Login,meta:{title:登录},},{// 子路由name:main,path:/,redirect:/home, //重定向 当路径为/则重定向homecomponent:Main,children:[{name:user,path:user,component:Users,meta:{title:用户管理}},{name:home,path:home,component:Home,meta:{title:首页}},{name:mall,path:mall,component:Mall,meta:{title:商品管理}},{name:page1,path:page1,component:PageOne,meta:{title:页面1}},{name:page2,path:page2,component:PageTwo,meta:{title:页面2}}]}]
})
//添加全局前置导航守卫
router.beforeEach((to,from,next){//判断token存不存在const tokenCookie.get(token)//token不存在说明当前用户是未登录应该跳转至登录页if(!tokento.name!login){next({name:login})}else if(token to.namelogin){ //token存在说明用户登录此时跳转至首页next({name:home})}else{next()}
})
// 后置路由守卫
router.afterEach((to,from){document.titleto.meta.title||通用后台管理系统
})
export default router 登录接口逻辑实现
使用的组件 permission.js
import Mock from mockjs
export default {getMenu: config {const { username, password } JSON.parse(config.body)// 先判断用户是否存在// 判断账号和密码是否对应if (username admin password admin) {return {code: 20000,data: {menu: [{path: /home,name: home,label: 首页,icon: s-home,url: Home.vue},{path: /mall,name: mall,label: 商品管理,icon: video-play,url: Mall.vue},{path: /user,name: user,label: 用户管理,icon: user,url: User.vue},{label: 其他,icon: location,children: [{path: /page1,name: page1,label: 页面1,icon: setting,url: PageOne.vue},{path: /page2,name: page2,label: 页面2,icon: setting,url: PageTwo.vue}]}],token: Mock.Random.guid(),message: 获取成功}}} else if (username xiaoxiao password xiaoxiao) {return {code: 20000,data: {menu: [{path: /home,name: home,label: 首页,icon: s-home,url: Home.vue},{path: /video,name: video,label: 商品管理,icon: video-play,url: Mall.vue}],token: Mock.Random.guid(),message: 获取成功}}} else {return {code: -999,data: {message: 密码错误}}}}
}
mock.js
import permission from /api/mockServeData/permission;
//传递数据并且对数据库产生影响的接口使用post方式
Mock.mock(/api\/permission\/getMenu/,post,permission.getMenu)全部代码
import Mock from mockjs
import homeApi from /api/mockServeData/home;
import user from /api/mockServeData/user
import permission from /api/mockServeData/permission;
/*//定义请求拦截
Mock.mock(/api/home/getData,function (){//拦截到请求后处理的逻辑console.log(拦截到了)
})*/
//定义请求拦截
Mock.mock(/api/home/getData,homeApi.getStatisticalData)//用户列表的数据
Mock.mock(/api/user/add,post,user.createUser)
Mock.mock(/api/user/edit,post,user.updateUser)
Mock.mock(/api/user/del,post,user.deleteUser)
//若要传递参数使用正则方式
Mock.mock(/api\/user\/getUser/,user.getUserList)
//传递数据并且对数据库产生影响的接口使用post方式
Mock.mock(/api\/permission\/getMenu/,post,permission.getMenu)
api/index.js
export const getMenu(data){return http.post(/permission/getMenu,data)
}全部代码
import http from /utils/request;//请求首页数据
export const getData(){//返回一个promise对象return http.get(/home/getData)
}export const getUser(params){//返回用户列表 axios的get请求是在params中return http.get(/user/getUser,params)
}export const addUser(data){//新增用户 axios的post请求是在data中return http.post(/user/add,data)
}export const editUser(data){//编辑用户 axios的post请求是在data中return http.post(/user/edit,data)
}
export const delUser(data){//删除用户 axios的post请求是在data中return http.post(/user/del,data)
}
export const getMenu(data){return http.post(/permission/getMenu,data)
}
Login.vue
import {getMenu} from /api;//登录submitForm(formName) {this.$refs[formName].validate((valid) {if (valid) {//token信息/*const tokenMock.Random.guid() //生成随机数//token信息存入cookie用于不同页面间的通信Cookie.set(token,token)*/getMenu(this.form).then(({data}){console.log(data)if(data.code20000){Cookie.set(token,data.data.token)//跳转到首页this.$router.push(/home)}else{this.$message.error(data.data.message)}})} else {console.log(error submit!!);return false;}});},全部代码
templatediv idappdiv classmain-contentdiv classtitle系统登录/divdiv classcontentel-form label-width70px :inlinetrue :modelform status-icon :rulesrules refruleForm classdemo-ruleFormel-form-item label用户名 propusernameel-input v-modelform.username placeholder请输入账号/el-input/el-form-itemel-form-item label密码 proppasswordel-input v-modelform.password typepassword autocompleteoff placeholder请输入密码/el-input/el-form-itemel-form-itemel-button typeprimary clicksubmitForm(ruleForm)登录/el-button/el-col/el-form-item/el-form/div/div/div/templatescript
// import Mock from mockjs
import Cookie from js-cookie
import {getMenu} from /api;
export default {name: login,data(){return{form: {username: ,password:},rules: {username: [{required: true, message: 请输入用户名, trigger: blur},{min: 3, max: 5, message: 长度在 3 到 5 个字符, trigger: blur}],password: [{required:true,message:请输入密码,trigger:blur}]}}},methods:{//登录submitForm(formName) {this.$refs[formName].validate((valid) {if (valid) {//token信息/*const tokenMock.Random.guid() //生成随机数//token信息存入cookie用于不同页面间的通信Cookie.set(token,token)*/getMenu(this.form).then(({data}){console.log(data)if(data.code20000){Cookie.set(token,data.data.token)//跳转到首页this.$router.push(/home)}else{this.$message.error(data.data.message)}})} else {console.log(error submit!!);return false;}});},}
}
/scriptstyle langless scoped
#app {display: flex;background-color: #333;height: 100vh;.main-content{height: 300px;width: 350px;//line-height: 100vh;background-color: #fff;margin: 200px auto;border-radius: 15px;padding: 35px 35px 15px 35px;box-sizing: border-box;box-shadow: 5px 5px 10px rgba(0,0,0,0.5),-5px -5px 10px rgba(0,0,0,0.5);.title{font-size: 20px;text-align: center;font-weight: 300;}.content{margin-top: 30px;}.el-input{width: 198px;}.el-button{margin-left: 105px;}}
}
/style
CommonHeader.vue
el-dropdown commandhandleClickspan classel-dropdown-linkimg src/assets/user.webp alt/spanel-dropdown-menu slotdropdownel-dropdown-item个人中心/el-dropdown-itemel-dropdown-item commandcancel退出/el-dropdown-item/el-dropdown-menu/el-dropdownhandleClick(command){if(commandcancel){console.log(登出)//清除Cookie的token信息Cookie.remove(token)this.$router.push(/login)}}全部代码
templatediv classheader-containerdiv classl-contentel-button stylemargin-right: 20px iconel-icon-menu sizemini clickhandleMenu/el-button!-- 面包屑--
!-- span classtext首页/span--el-breadcrumb separator/el-breadcrumb-item v-foritem in tags :keyitem.path :to{ path: item.path }{{ item.label }}/el-breadcrumb-item/el-breadcrumb/divdiv classr-contentel-dropdown commandhandleClickspan classel-dropdown-linkimg src/assets/user.webp alt/spanel-dropdown-menu slotdropdownel-dropdown-item个人中心/el-dropdown-itemel-dropdown-item commandcancel退出/el-dropdown-item/el-dropdown-menu/el-dropdown/div/div/templatescript
import {mapState} from vuex
import Cookie from js-cookie
export default {name: CommonHeader,methods:{handleMenu(){this.$store.commit(collapseMenu)},handleClick(command){if(commandcancel){console.log(登出)//清除Cookie的token信息Cookie.remove(token)this.$router.push(/login)}}},computed:{...mapState({tags: statestate.tab.tabsList})}
}
/scriptstyle scoped langless
.header-container {height: 60px;background-color: #333;display: flex;justify-content: space-between;align-items: center;padding: 0 20px;.text {color: #fff;font-size: 14px;margin-left: 10px;}.r-content{img{width: 40px;height: 40px;border-radius: 50%;}}.l-content{display: flex;align-items: center;/deep/.el-breadcrumb__item{ /*元素没有绑定data-v-5a90ec03这样的编号时候样式不起作用使用deep进行穿刺可解决问题*/.el-breadcrumb__inner{font-weight: normal;.is-link{color: #666;}}:last-child{.el-breadcrumb__inner {color: #fff;}}}}
}
/style