详解Vue Elememt-UI构建管理后台


Posted in Javascript onFebruary 27, 2018

安装

我使用的是 vue-cli 初始化项目,命令如下:

npm i -g vue-cli
mkdir my-project && cd my-project
vue init webpack

修改 package.json 文件:

...
"dependencies": {
 "vue": "^2.5.2",
 "vue-router": "^3.0.1",
 "element-ui": "^2.0.7", // element-ui
 "axios": "^0.17.1" // http 请求库
}
...

之后执行 npm install 进行安装依赖,如果安装速度有点慢的话,可以试一下 cnpm ,具体安装和用法自行查找。

简单介绍下项目的目录结构:

├─build // 构建配置
├─config // 配置文件
├─src // vue 开发源文件目录
├────assets // css/js 文件
├────components // vue 组件
├────router  // 路由
├────App.vue  // 启动组件
├────main.js // 入口文件
├─static // 静态文件目录
├─test // 测试目录

之后在项目根目录执行 npm run dev ,打开浏览器输入 http://localhost:8080 就可以查看了。

目标

  • 登录页面,登录,退出功能
  • 首页,调用接口渲染列表

路由

路由使用的是 vue-router,具体用法可参考 官方文档

我们这里需要两个路由:

src/router/index.js

import Vue from 'vue'
import Router from 'vue-router'
import Index from '@/components/Index'
import Login from '@/components/Login'

Vue.use(Router)

const routers = new Router({
 routes: [
  {
   path: '/index',
   name: 'index',
   component: Index
  },
  {
   path: '/login',
   name: 'login',
   component: Login
  }
 ]
})

routers.beforeEach((to, from, next) => {
 if (to.name !== 'login' && !localStorage.getItem('token')) {
  next({path: 'login'})
 } else {
  next()
 }
})

export default routers

登录页面

src/components/Login.vue

<template>
 <div class="login">
  <el-form name="aa" :inline="true" label-position="right" label-width="80px">
    <el-form-item label="用户名">
     <el-input v-model="user.name"></el-input>
    </el-form-item>
    <el-form-item label="密码">
     <el-input type="password" v-model="user.password"></el-input>
    </el-form-item>
    <el-form-item label=" ">
     <el-button type="primary" @click="login()">登录</el-button>
    </el-form-item>
  </el-form>
 </div>
</template>

<script>
import $http from '@/api/'
import config from '@/config'

export default {
 data () {
  return {
   user: {
    name: '',
    password: ''
   }
  }
 },
 mounted: function () {
  var token = localStorage.getItem('token')
  if (token) {
   this.$router.push('/index')
  }
 },
 methods: {
  login: function () {
   var data = {
    grant_type: 'password',
    client_id: config.oauth_client_id,
    client_secret: config.oauth_secret,
    username: this.user.name,
    password: this.user.password
   }
   var _this = this
   $http.login(data).then(function (res) {
    if (res.status === 200) {
     $http.setToken(res.data.access_token)
     _this.$message({
      showClose: false,
      message: '登录成功',
      type: 'success'
     })
     _this.$router.push('/index')
    } else {
     _this.$message({
      showClose: false,
      message: '登录失败',
      type: 'error'
     })
    }
   })
  }
 }
}
</script>

<style>
.login{
  width: 300px;
  margin: 100px auto;
  background-color: #ffffff;
  padding: 30px 30px 5px;
  border-radius: 5px;
}
</style>

首页

src/components/Index.vue

<template>
 <div class="main">
  <el-table
   stripe
   v-loading="loading"
   element-loading-background="#dddddd"
   :data="tableData"
   style="width: 100%">
   <el-table-column
    prop="id"
    label="ID">
   </el-table-column>
   <el-table-column
    prop="name"
    label="名称">
   </el-table-column>
  </el-table>
  <el-pagination
   background
   layout="prev, pager, next"
   :total="total"
   class="page"
   @current-change="pageList">
  </el-pagination>
 </div>
</template>

<script>
import $http from '@/api/'

export default {
 data () {
  return {
   tableData: [],
   total: 0,
   loading: false
  }
 },
 mounted: function () {
  this.getList()
 },
 methods: {
  pageList: function (page) {
   this.search.page = page
   this.getList()
  },
  getList: function () {
   var _this = this
   _this.loading = true
   $http.index().then(function (res) {
    if (res.status === 200) {
     _this.tableData = res.data.data.lists
     _this.total = res.data.data.total
    }
    _this.loading = false
   })
  }
 }
}
</script>

App

src/App.vue

<template>
 <div id="app">
  <el-row v-if="token">
   <menus class="left-menu">
    <h3 class="logo"><a href="/" rel="external nofollow" >Admin</a></h3>
   </menus>
   <el-col :span="21" :gutter="0" :offset="3">
    <el-breadcrumb separator-class="el-icon-arrow-right" class="breadcrumb">
     <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
     <el-breadcrumb-item class="active">列表</el-breadcrumb-item>
    </el-breadcrumb>
    <el-dropdown @command="operate" class="header">
     <img src="/static/image/head.jpg" />
     <el-dropdown-menu slot="dropdown" :click="true">
      <el-dropdown-item command="/user/profile">基本资料</el-dropdown-item>
      <el-dropdown-item command="/logout">安全退出</el-dropdown-item>
     </el-dropdown-menu>
    </el-dropdown>
    <router-view/>
   </el-col>
   <el-col :span="21" :gutter="0" :offset="3" class="footer">Copyright © 2017 Flyerboy All Rights Reserved</el-col> 
  </el-row>

  <router-view v-if="!token" />
 </div>
</template>

<script>
import Menus from '@/components/Menu'
export default {
 name: 'App',
 data () {
  return {
   token: false
  }
 },
 mounted: function () {
  this.token = localStorage.getItem('token') ? true : false
 },
 watch: {
  '$route.path': function ($newVal, $oldVal) {
   this.token = localStorage.getItem('token') ? true : false
  }
 },
 methods: {
   operate: function (command) {
   if (command === '/logout') {
    localStorage.removeItem('token')
    this.$router.push('login')
   } else {
    this.$router.push(command)
   }
  }
 },
 components: {
  Menus
 }
}
</script>

<style>
body{
 margin: 0;
 padding: 0;
 background-color: #eeeeee;
}
.header{
 position: absolute;
 top: 5px;
 right: 20px;
}
.header img{
 width: 38px;
 height: 38px;
 border-radius: 20px;
 border: 1px solid #aaaaaa;
}
#app {
 font-family: 'Avenir', Helvetica, Arial, sans-serif;
 -webkit-font-smoothing: antialiased;
 -moz-osx-font-smoothing: grayscale;
}
.main{
 padding: 20px;
 min-height: 600px;
 margin-bottom: 20px;
}
.main table{
 background: #ffffff;
}
.left-menu{
 background-color: #33374B;
}
.logo{
 padding: 20px 0 15px 20px;
 font-size: 24px;
 border-bottom: 2px solid #3a8ee6;
}
.logo a{
 color: #ffffff;
 text-decoration: none;
}

.left-menu .el-menu{
 border-right: 0;
}
.breadcrumb{
 line-height: 40px;
 padding: 5px 20px;
 background: #ffffff;
}
.breadcrumb span{
 color: #069;
 font-weight: normal;
}
.breadcrumb .active{
 color: #aaaaaa;
}
.page{
 margin: 20px 0 0;
 margin-left: -10px;
}
.page .el-pager li.number{
 background-color: #ffffff;
}
.el-submenu .el-menu-item{
 padding-left: 60px !important;
}
.footer{
 position: fixed;
 bottom: 0;
 right: 0;
 font-size: 12px;
 color: #888888;
 padding: 15px 20px;
 text-align: center;
 background-color: #ffffff;
 margin-top: 40px;
}
</style>

调用 API

src/api/index.js

import axios from 'axios'
axios.defaults.baseURL = 'http://localhost:8000/'
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'
axios.defaults.headers.common['Authorization'] = 'Bearer ' + localStorage.getItem('token')


export default {
 setToken: function (token) {
  localStorage.setItem('token', token)
  axios.defaults.headers.common['Authorization'] = 'Bearer ' + token
 },
 login: function (param) {
  return axios.post('oauth/token', param)
 },
 index: function (params) {
  return axios.get('api/user/list', {
   params: params
  })
 }
}

config

src/config.js 这里配置登录 oauth 需要的 client_id 和 secret

export default {
 oauth_client_id: 2,
 oauth_secret: ''
}

main.js

src/main.js

import Vue from 'vue'
import App from './App'
import router from './router'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'

Vue.use(ElementUI)

Vue.config.productionTip = false

new Vue({
 el: '#app',
 router,
 components: { App },
 template: '<App/>'
})

api 接口

主要用到两个接口,一个是 api/oauth/token 登录获取 token 接口,一个获取列表 api/user/list。

第一个接口是用到 laravel oauth,第二个接口直接是一个简单的查询用户列表接口,详细讲会在下一篇文章中讲述。

以上就是本次整理的关于Vue Elememt-UI构建管理后台的全部内容,感谢大家对三水点靠木的支持。

Javascript 相关文章推荐
使用jQuery实现dropdownlist的联动效果(sharepoint 2007)
Mar 30 Javascript
jquery.Jwin.js 基于jquery的弹出层插件代码
May 23 Javascript
jQuery之按钮组件的深入解析
Jun 19 Javascript
jquery复选框全选/取消示例
Dec 30 Javascript
javascript 获取浏览器版本
Jan 21 Javascript
基于Javascript实现弹出页面效果
Jan 01 Javascript
Bootstrap网格系统详解
Apr 26 Javascript
JS集成fckeditor及判断内容是否为空的方法
May 27 Javascript
H5手机端多文件上传预览插件
Apr 21 Javascript
angularjs实现时间轴效果的示例代码
Nov 29 Javascript
sharp.js安装过程中遇到的问题总结
Apr 02 Javascript
JS+css3实现幻灯片轮播图
Aug 14 Javascript
详解react-native WebView 返回处理(非回调方法可解决)
Feb 27 #Javascript
Vue2.5通过json文件读取数据的方法
Feb 27 #Javascript
vue2.5.2使用http请求获取静态json数据的实例代码
Feb 27 #Javascript
jQuery幻灯片插件owlcarousel参数说明中文文档
Feb 27 #jQuery
关于ES6箭头函数中的this问题
Feb 27 #Javascript
vue中echarts3.0自适应的方法
Feb 26 #Javascript
swiper 解决动态加载数据滑动失效的问题
Feb 26 #Javascript
You might like
聊天室php&amp;mysql(三)
2006/10/09 PHP
PHP校验ISBN码的函数代码
2011/01/17 PHP
PHP安装memcached扩展笔记
2015/05/28 PHP
php文件读取方法实例分析
2015/06/20 PHP
thinkPHP框架对接支付宝即时到账接口回调操作示例
2016/11/14 PHP
javascript 字符串连接的性能问题(多浏览器)
2008/11/18 Javascript
2010年最佳jQuery插件整理
2010/12/06 Javascript
js自动生成的元素与页面原有元素发生堆叠的解决方法
2013/10/24 Javascript
js获取html页面节点方法(递归方式)
2013/12/13 Javascript
js形成页面的一种遮罩效果实例代码
2014/01/04 Javascript
jQuery学习笔记之jQuery构建函数的7种方法
2014/06/03 Javascript
原生js和jquery实现图片轮播淡入淡出效果
2015/04/23 Javascript
javascript实现全局匹配并替换的方法
2015/04/27 Javascript
javascript函数特点实例分析
2015/05/14 Javascript
JavaScript中join()方法的使用简介
2015/06/09 Javascript
简述Jquery与DOM对象
2015/07/10 Javascript
JS实现快速的导航下拉菜单动画效果附源码下载
2016/11/01 Javascript
BootStrap的select2既可以查询又可以输入的实现代码
2017/02/17 Javascript
Vue.js实现一个漂亮、灵活、可复用的提示组件示例
2017/03/17 Javascript
使用AngularJS2中的指令实现按钮的切换效果
2017/03/27 Javascript
一个Js文件函数中调用另一个Js文件函数的方法演示
2017/08/14 Javascript
详解处理Vue单页面应用SEO的另一种思路
2018/11/09 Javascript
vue实现购物车抛物线小球动画效果的方法详解
2019/02/13 Javascript
[53:23]Secret vs Liquid 2018国际邀请赛淘汰赛BO3 第二场 8.25
2018/08/29 DOTA
使用Python进行稳定可靠的文件操作详解
2013/12/31 Python
python抓取百度首页的方法
2015/05/19 Python
python3+pyqt5+itchat微信定时发送消息的方法
2019/02/20 Python
使用python serial 获取所有的串口名称的实例
2019/07/02 Python
在Python中使用MongoEngine操作数据库教程实例
2019/12/03 Python
捷克原创男装和女装购物网站:Bolf.cz
2018/04/28 全球购物
英国领先的电视购物零售商:Ideal World
2019/03/18 全球购物
美国最佳选择产品网站:Best Choice Products
2019/05/27 全球购物
让世界充满爱演讲稿
2014/05/24 职场文书
党员批评与自我批评思想汇报(集锦)
2014/09/14 职场文书
考试作弊检讨书1000字(5篇)
2014/10/19 职场文书
Win11更新失败并提示0xc1900101
2022/04/19 数码科技