之后执行 npm install 进行安装依赖,如果安装速度有点慢的话,pm ,具体安装和用法自行查找。
简单介绍下项目的目录结构:
├─build // 构建配置 ├─config // 配置文件 ├─src // vue 开发源文件目录 ├────assets // css/js 文件 ├────components // vue 组件 ├────router // 路由 ├────App.vue // 启动组件 ├────main.js // 入口文件 ├─static // 静态文件目录 ├─test // 测试目录
之后在项目根目录执行 npm run dev ,打开浏览器输入 p>
目标
登录页面,登录,退出功能
首页,调用接口渲染列表
路由
路由使用的是 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
登录页面 首页 App src/App.vue 调用 API src/api/index.js config src/config.js 这里配置登录 oauth 需要的 client_id 和 secret main.js src/main.js api 接口 主要用到两个接口,一个是 api/oauth/token 登录获取 token 接口,一个获取列表 api/user/list。 第一个接口是用到 laravel oauth,第二个接口直接是一个简单的查询用户列表接口,详细讲会在
template
div
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
template
div
el-table
stripe
v-loading="loading"
element-loading-background="#dddddd"
:data="tableData"
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"
@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
template
div id="app"
el-row v-if="token"
menus
h3 a href="/" rel="external nofollow" Admin /a /h3
/menus
el-col :span="21" :gutter="0" :offset="3"
el-breadcrumb separator-
el-breadcrumb-item :to="{ path: '/' }" 首页 /el-breadcrumb-item
el-breadcrumb-item 列表 /el-breadcrumb-item
/el-breadcrumb
el-dropdown @command="operate"
img src="/static/image/head.jpg" /
el-dropdown-menu slot="dropdown" :click="true"
el-mand="/user/profile" 基本资料 /el-dropdown-item
el-mand="/logout" 安全退出 /el-dropdown-item
/el-dropdown-menu
/el-dropdown
router-view/
/el-col
el-col :span="21" :gutter="0" :offset="3" 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.$mand)
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
import axios from 'axios'
axios.defaults.baseURL = ''
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'
axios.mon['Authorization'] = 'Bearer ' + localStorage.getItem('token')
localStorage.setItem('token', token)
axios.mon['Authorization'] = 'Bearer ' + token
login: function (param) {
return axios.post('oauth/token', param)
index: function (params) {
return axios.get('api/user/list', {
params: params
}
export default {
oauth_client_id: 2,
oauth_secret: ''
}
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/ '
})