详解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中:not选择器用法实例
Dec 30 Javascript
Node.js抓取中文网页乱码问题和解决方法
Feb 10 Javascript
跟我学习javascript的异步脚本加载
Nov 20 Javascript
关于动态执行代码(js的Eval)实例详解
Aug 15 Javascript
AngularJS实现网站换肤实例
Feb 19 Javascript
JS中的三个循环小结
Jun 20 Javascript
jQuery.Form实现Ajax上传文件同时设置headers的方法
Jun 26 jQuery
javascript 跨域问题以及解决办法
Jul 17 Javascript
微信小程序之页面拦截器的示例代码
Sep 07 Javascript
vue.js实现会动的简历(包含底部导航功能,编辑功能)
Apr 08 Javascript
javascript原型链学习记录之继承实现方式分析
May 01 Javascript
Js图片点击切换轮播实现代码
Jul 27 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 上传功能实例代码
2010/04/13 PHP
php数组函数序列之krsort()- 对数组的元素键名进行降序排序,保持索引关系
2011/11/02 PHP
PHP字符串长度计算 - strlen()函数使用介绍
2013/10/15 PHP
在IE下获取object(ActiveX)的Param的代码
2009/09/15 Javascript
jquery获取div距离窗口和父级dv的距离示例
2013/10/10 Javascript
jQuery的deferred对象详解
2014/11/12 Javascript
JS实现网页顶部向下滑出的全国城市切换导航效果
2015/08/22 Javascript
总结JavaScript设计模式编程中的享元模式使用
2016/05/21 Javascript
vue-cli 自定义指令directive 添加验证滑块示例
2017/10/19 Javascript
Vue.js用法详解
2017/11/13 Javascript
webpack多入口文件页面打包配置详解
2018/01/09 Javascript
jQuery插件实现弹性运动完整示例
2018/07/07 jQuery
解决vue 绑定对象内点击事件失效问题
2018/09/05 Javascript
Vue CLI项目 axios模块前后端交互的使用(类似ajax提交)
2019/09/01 Javascript
jquery实现直播弹幕效果
2019/11/28 jQuery
python实现socket端口重定向示例
2014/02/10 Python
python异步任务队列示例
2014/04/01 Python
有关wxpython pyqt内存占用问题分析
2014/06/09 Python
Pycharm学习教程(7)虚拟机VM的配置教程
2017/05/04 Python
Tensorflow之构建自己的图片数据集TFrecords的方法
2018/02/07 Python
Python获取指定字符前面的所有字符方法
2018/05/02 Python
Python自定义函数实现求两个数最大公约数、最小公倍数示例
2018/05/21 Python
Python实现通过继承覆盖方法示例
2018/07/02 Python
python破解bilibili滑动验证码登录功能
2019/09/11 Python
Python开发之基于模板匹配的信用卡数字识别功能
2020/01/13 Python
使用Bazel编译TensorBoard教程
2020/02/15 Python
paramiko使用tail实时获取服务器的日志输出详解
2020/12/06 Python
selenium3.0+python之环境搭建的方法步骤
2021/02/01 Python
孕妇装中的著名品牌:Isabella Oliver(伊莎贝拉·奥利弗)
2016/10/31 全球购物
莫斯科大型旅游休闲商品超市:Camping.ru
2020/09/16 全球购物
英语简历自我评价
2014/01/26 职场文书
中层干部竞聘演讲稿
2014/05/15 职场文书
球队口号
2014/06/18 职场文书
庆祝国庆节标语
2014/10/09 职场文书
投资入股合作协议书
2014/10/28 职场文书
Redis配置外网可访问(redis远程连接不上)的方法
2022/12/24 Redis