上一篇中已将完成了基础结构的搭建,这一篇将开始正式开发。页面直接使用了一位小伙伴的源码,可以在https://github.com/taylorchen709/vue-admin下载
修改入口main.js
在入口函数中添加对element-ui,vue-router,vuex,vue-source等组件的引用
import Vue from 'vue'import App from './App'import ElementUI from 'element-ui'import 'element-ui/lib/theme-default/index.css'import VueRouter from 'vue-router'import store from './vuex/store'import Vuex from 'vuex'import VueSource from 'vue-resource'import routes from './routes'import 'font-awesome/css/font-awesome.min.css'Vue.use(ElementUI)Vue.use(VueRouter)Vue.use(Vuex)Vue.use(VueSource)//创建路由实例const router = new VueRouter({routes})router.beforeEach((to, from, next) => {//这里进行了简单的登录验证//访问login时直接清除userif (to.path == '/login') {sessionStorage.removeItem('user');}let user = JSON.parse(sessionStorage.getItem('user'));if (!user && to.path != '/login') {next({ path: '/login' })} else {next()}})new Vue({router,store,render: h => h(App)}).$mount('#app')
修改App.vue
<template><div id="app"><transition name="fade"mode="out-in"><router-view></router-view></transition></div></template><script>export default {name: 'app',components: {}}</script>
增加viewes文件夹,并增加模块视图
login.vue
<template><el-form :model="ruleForm2" :rules="rules2" ref="ruleForm2" label-position="left" label-width="0px" class="demo-ruleForm login-container"><h3 class="title">系统登录</h3><el-form-item prop="account"><el-input type="text" v-model="ruleForm2.account" auto-complete="off" placeholder="账号"></el-input></el-form-item><el-form-item prop="checkPass"><el-input type="password" v-model="ruleForm2.checkPass" auto-complete="off" placeholder="密码"></el-input></el-form-item><el-checkbox v-model="checked" checked class="remember">记住密码</el-checkbox><el-form-item style="width:100%;"><el-button type="primary" style="width:100%;" @click.native.prevent="handleSubmit2" :loading="logining">登录</el-button></el-form-item></el-form></template><script>export default {data() {return {logining: false,ruleForm2: {account: 'admin',checkPass: '123456'},rules2: {account: [{ required: true, message: '请输入账号', trigger: 'blur' },//{ validator: validaePass }],checkPass: [{ required: true, message: '请输入密码', trigger: 'blur' },//{ validator: validaePass2 }]},checked: true};},methods: {handleReset2() {this.$refs.ruleForm2.resetFields();},handleSubmit2(ev) {var _this = this;this.$refs.ruleForm2.validate((valid) => {if (valid) {this.logining = true;//NProgress.start();var loginParams = { username: this.ruleForm2.account, password: this.ruleForm2.checkPass };if (loginParams.username != 'admin') {this.$message({message: '用户不存在',type: 'error'});this.logining = false;return false;}if (loginParams.password != '123456') {this.$message({message: '密码不正确',type: 'error'});this.logining = false;return;}let user = {id: 1,username: 'admin',password: '123456',avatar: 'resources/img/user.png',name: '管理员'}sessionStorage.setItem('user', JSON.stringify(user));this.$router.push({ path: '/' });} else {return false;}});}}}</script><style scoped>.login-container {/*box-shadow: 0 0px 8px 0 rgba(0, 0, 0, 0.06), 0 1px 0px 0 rgba(0, 0, 0, 0.02);*/-webkit-border-radius: 5px;border-radius: 5px;-moz-border-radius: 5px;background-clip: padding-box;margin: 180px auto;width: 350px;padding: 35px 35px 15px 35px;background: #fff;border: 1px solid #eaeaea;box-shadow: 0 0 25px #cac6c6;}.title {margin: 0px auto 40px auto;text-align: center;color: #505458;}.remember {margin: 0px 0px 35px 0px;}</style>
home.vue
<template><el-row class="container"><el-col :span="24" class="header"><el-col :span="10" :class="collapsed?'logo-collapse-width logo-collapsed':'logo-width logo'">{{collapsed?'':sysName}}<!--<img :src="logo" v-show="collapsed" />--></el-col><el-col :span="10"><div class="tools" @click.prevent="collapse"><i class="fa fa-align-justify"></i></div></el-col><el-col :span="4" class="userinfo"><el-dropdown trigger="hover"><span class="el-dropdown-link userinfo-inner"><img :src="this.sysUserAvatar" /> {{sysUserName}}</span><el-dropdown-menu slot="dropdown"><el-dropdown-item>我的消息</el-dropdown-item><el-dropdown-item>设置</el-dropdown-item><el-dropdown-item divided @click.native="logout">退出登录</el-dropdown-item></el-dropdown-menu></el-dropdown></el-col></el-col><el-col :span="24" class="main"><aside :class="collapsed?'menu-collapsed':'menu-expanded'"><!--导航菜单--><el-menu :default-active="$route.path" class="el-menu-vertical-demo" @open="handleopen" @close="handleclose" @select="handleselect"unique-opened router v-show="!collapsed"><template v-for="(item,index) in $router.options.routes" v-if="!item.hidden"><el-submenu :index="index+''" v-if="!item.leaf"><template slot="title"><i :class="item.iconCls"></i>{{item.name}}</template><el-menu-item v-for="child in item.children" :index="child.path" :key="child.path" v-if="!child.hidden">{{child.name}}</el-menu-item></el-submenu><el-menu-item v-if="item.leaf&&item.children.length>0" :index="item.children[0].path"><i :class="item.iconCls"></i>{{item.children[0].name}}</el-menu-item></template></el-menu><!--导航菜单-折叠后--><ul class="el-menu el-menu-vertical-demo collapsed" v-show="collapsed" ref="menuCollapsed"><li v-for="(item,index) in $router.options.routes" v-if="!item.hidden" class="el-submenu item"><template v-if="!item.leaf"><div class="el-submenu__title" style="padding-left: 20px;" @mouseover="showMenu(index,true)" @mouseout="showMenu(index,false)"><i :class="item.iconCls"></i></div><ul class="el-menu submenu" :class="'submenu-hook-'+index" @mouseover="showMenu(index,true)" @mouseout="showMenu(index,false)"><li v-for="child in item.children" v-if="!child.hidden" :key="child.path" class="el-menu-item" style="padding-left: 40px;" :class="$route.path==child.path?'is-active':''" @click="$router.push(child.path)">{{child.name}}</li></ul></template><template v-else><li class="el-submenu"><div class="el-submenu__title el-menu-item" style="padding-left: 20px;height: 56px;line-height: 56px;padding: 0 20px;" :class="$route.path==item.children[0].path?'is-active':''" @click="$router.push(item.children[0].path)"><i :class="item.iconCls"></i></div></li></template></li></ul></aside><section class="content-container"><div class="grid-content bg-purple-light"><el-col :span="24" class="breadcrumb-container"><!--<strong class="title">{{$route.name}}</strong>--><el-breadcrumb separator="/" class="breadcrumb-inner"><el-breadcrumb-item v-for="item in $route.matched" :key="item.path">{{ item.name }}</el-breadcrumb-item></el-breadcrumb></el-col><el-col :span="24" class="content-wrapper"><transition name="fade" mode="out-in"><router-view></router-view></transition></el-col></div></section></el-col></el-row></template><script>export default {data() {return {sysName:'Simple',logo:'dist/resources/img/logo.png',collapsed:false,sysUserName: '',sysUserAvatar: '',form: {name: '',region: '',date1: '',date2: '',delivery: false,type: [],resource: '',desc: ''}}},methods: {onSubmit() {console.log('submit!');},handleopen() {//console.log('handleopen');},handleclose() {//console.log('handleclose');},handleselect: function (a, b) {},//退出登录logout: function () {var _this = this;this.$confirm('确认退出吗?', '提示', {//type: 'warning'}).then(() => {sessionStorage.removeItem('user');_this.$router.push('/login');}).catch(() => {});},//折叠导航栏collapse:function(){this.collapsed=!this.collapsed;},showMenu(i,status){this.$refs.menuCollapsed.getElementsByClassName('submenu-hook-'+i)[0].style.display=status?'block':'none';}},mounted() {var user = sessionStorage.getItem('user');if (user) {user = JSON.parse(user);this.sysUserName = user.name || '';this.sysUserAvatar = user.avatar || '';}}}</script><style scoped >.container {position: absolute;top: 0px;bottom: 0px;width: 100%;}.container .header {height: 60px;line-height: 60px;background: #20a0ff;color: #fff;}.container .header .userinfo {text-align: right;padding-right: 35px;float: right;}.container .header .userinfo .userinfo-inner {cursor: pointer;color: #fff;}.container .header .userinfo .userinfo-inner img {width: 40px;height: 40px;border-radius: 20px;margin: 10px 0px 10px 10px;float: right;}.container .header .logo {height: 60px;font-size: 22px;padding-left: 20px;padding-right: 20px;border-color: rgba(238, 241, 146, 0.3);border-right-width: 1px;border-right-style: solid;}.container .header .logo img {width: 40px;float: left;margin: 10px 10px 10px 18px;}.container .header .logo .txt {color: #fff;}.container .header .logo-collapsed {padding: 0;font-size: 22px;padding-left: 0px;padding-top: 10px;border-color: rgba(238, 241, 146, 0.3);border-right-width: 1px;border-right-style: solid;}.container .header .logo-collapsed img {width: 60px;float: left;margin: 0px;}.container .header .logo-collapsed .txt {color: #fff;}.container .header .logo-width {width: 230px;}.container .header .logo-collapse-width {width: 60px;}.container .header .tools {padding: 0px 23px;width: 14px;height: 60px;line-height: 60px;cursor: pointer;}.container .main {display: flex;position: absolute;top: 60px;bottom: 0px;overflow: hidden;}.container .main aside {flex: 0 0 230px;width: 230px;}.container .main aside .el-menu {height: 100%;}.container .main aside .collapsed {width: 60px;}.container .main aside .collapsed .item {position: relative;}.container .main aside .collapsed .submenu {position: absolute;top: 0px;left: 60px;z-index: 99999;height: auto;display: none;}.container .main .menu-collapsed {flex: 0 0 60px;width: 60px;}.container .main .menu-expanded {flex: 0 0 230px;width: 230px;}.container .main .content-container {flex: 1;overflow-y: scroll;padding: 20px;}.container .main .content-container .breadcrumb-container .title {width: 200px;float: left;color: #475669;}.container .main .content-container .breadcrumb-container .breadcrumb-inner {float: left;padding-bottom: 10px;}.container .main .content-container .content-wrapper {background-color: #fff;box-sizing: border-box;}</style>
此时编译运行可以看到下面的页面,由于还没有开发子页面,所以只显示主页和菜单:
添加模拟的后端API
这里模拟用户管理的功能。为.net开发,具体的开发流程不在赘述。
UserInfo.cs
public class UserInfo{public string uuid { get; set; }public string login_name { get; set; }public string real_name { get; set; }public string email { get; set; }public string birthday { get; set; }public int age { get; set; }}
UserInfoRepository.cs
public class UserInfoRepository{static List<UserInfo> db_users = new List<UserInfo>() {};public static IList<UserInfo> LoadAll() {return db_users;}public static string Insert(UserInfo u){u.uuid = Guid.NewGuid().ToString();db_users.Add(u);return u.uuid;}public static string Update(UserInfo u){db_users.Remove(db_users.Where(m => m.uuid.Equals(u.uuid)).FirstOrDefault());db_users.Add(u);return u.uuid;}public static UserInfo Get(string uuid) {return db_users.Where(m=>m.uuid.Equals(uuid)).FirstOrDefault();}public static void Delete(string uuid){var u = db_users.Where(m => m.uuid.Equals(uuid)).FirstOrDefault();db_users.Remove(u);}}
UserController.cs
[Route("api/[controller]")]public class UsersController : Controller{[HttpGet]public string Get(){return JsonConvert.SerializeObject(UserInfoRepository.LoadAll());}[HttpGet("{uuid}")]public string Get(string uuid){return JsonConvert.SerializeObject(UserInfoRepository.Get(uuid));}[HttpGet("p/")]public string Get(string name, int page = 1, int pagesize = 20){long count = 0;var list = UserInfoRepository.LoadAll();count = list.Count;var obj = new{total = count,list = list.Where(m => m.real_name.Equals(name)).Skip((page - 1) * pagesize).Take(pagesize)};return JsonConvert.SerializeObject(obj);}[HttpPost]public void Post([FromBody]UserInfo user){UserInfoRepository.Insert(user);}[HttpPut]public void Put([FromBody]UserInfo user){UserInfoRepository.Update(user);}[HttpDelete("{uuid}")]public void Delete(string uuid){UserInfoRepository.Delete(uuid);}}
添加列表页面
添加内容包括,users.vue页面、路由以及将登录后的默认页面修改为users
users.vue
<template><section><!--工具条--><el-col :span="24" class="toolbar" style="padding-bottom: 0px;"><el-form :inline="true" :model="filters"><el-form-item><el-input v-model="filters.name" placeholder="姓名"></el-input></el-form-item><el-form-item><el-button type="primary" v-on:click="search">查询</el-button></el-form-item><el-form-item><el-button type="success" v-on:click="add">添加</el-button></el-form-item></el-form></el-col><!--列表--><el-table :data="infos" highlight-current-row v-loading="listLoading" style="width: 100%;"><el-table-column type="selection" width="55"></el-table-column><el-table-column type="index" width="60"></el-table-column><el-table-column prop="login_name" label="登录名" sortable></el-table-column><el-table-column prop="real_name" label="真实姓名" sortable></el-table-column><el-table-column prop="email" label="邮箱" sortable></el-table-column><el-table-column prop="birthday" label="生日" sortable></el-table-column><el-table-column prop="age" label="年龄" sortable></el-table-column><el-table-column label="操作" width="150"><template scope="scope"><el-button type="warning" size="small" @click="edit(scope.$index, scope.row)">编辑</el-button><el-button type="danger" size="small" @click="del(scope.$index, scope.row)">删除</el-button></template></el-table-column></el-table><el-col :span="24" class="toolbar"><el-pagination layout="prev, pager, next" @current-change="handleCurrentChange" :page-size="10" :total="total" style="float:left;"></el-pagination></el-col></section></template><script>import ElCol from "element-ui/packages/col/src/col";export default {components: {ElCol}, data(){return {filters:{name:'',},infos:[],listLoading: false,page:1,total:0};},methods:{search:function(){var _self =this;_self.listLoading=true;this.$http.get('/api/users/s',{params:{name:_self.filters.name,page:_self.page,pagesize:10}}).then((response)=>{_self.infos=response.data.list;_self.total=response.data.total;_self.listLoading=false;},(response)=>{}).catch((response)=>{});},add:function(){this.$router.push('/useradd')},edit:function(index,row){this.$router.push({ path: '/useradd', query: { uuid: row.uuid }})},del:function(index,row){var _self =this;this.$confirm('确定删除吗?', '提示', {confirmButtonText: '确定',cancelButtonText: '取消',type: 'warning'}).then(() => {_self.$http.delete('/api/users/'+row.Uuid).then((res)=>{_self.search();_self.$message({type: 'success',message: '删除成功!'});},(res)=>{_self.$message({type: 'srror',message: '删除失败!'});}).catch();});},handleCurrentChange:function(p){this.page = p;this.search();}},mounted() {this.search();}}</script>
添加路由,在系统管理的children下添加users
{path: '/',component: Home,name: '系统管理',iconCls: 'el-icon-setting',//图标样式classchildren: [{path: '/users', component: Users, name: '用户管理' }]}
同样的方式增加用户添加和编辑页面,完成用户管理小模块。
总结
我们完成了在.net core下基于vue开发单页应用,这种方法实际上是利用webpack的打包功能,编译时将应用打包好,.net应用的cshtml页面再引用已打包的js文件。方案缺陷之一为:每次修改页面都需要重新build,不能同使用Node开发时实时预览页面,在实际的项目中可能并不会使用这种方式,仅供折腾。下面附上源码地址:
https://github.com/wenjq0911/simple.git
源博客地址使用的leanote,地址在此 http://blog.leanote.com/post/wenjq0911@gmail.com
本文通过实战演示了如何使用Vue.js结合.NET Core搭建单页应用,涵盖了基础结构搭建、页面开发、模拟API创建及列表页面展示等内容。
&spm=1001.2101.3001.5002&articleId=72764155&d=1&t=3&u=05b5cfb738dd4a4db64c90aad0095fe4)
1254

被折叠的 条评论
为什么被折叠?



