image.png
api index
import request from '../utils/request'
export const Login = (params) => {
return request({
method: 'post',
url: '/login',
data: params
})
}
components breadcrumb
<template>
<el-breadcrumb separator-class="el-icon-arrow-right">
<el-breadcrumb-item
v-for="(item,index) in breadList"
:key="item.path"
>
<router-link
to="/welcome"
v-if="index=== 0"
>首页</router-link>
<span v-else>
{{item.meta.title}}
</span>
</el-breadcrumb-item>
</el-breadcrumb>
</template>
<script>
export default {
data() {
return {
}
},
created() {
// console.log(this.$route.matched)
},
computed: {
breadList() {
return this.$route.matched
}
}
}
</script>
<style lang="scss" scoped>
</style>
layout components appmain
<template>
<div class="app-main">
<router-view></router-view>
</div>
</template>
<script>
export default {
data() {
return {
}
}
}
</script>
<style lang="scss" scoped>
.app-main {
background-color: #eee;
height: calc(100vh - 50px);
padding: 10px;
box-sizing: border-box;
}
</style>
navbar
<template>
<div class="navbar">
<i
:class="getIcon"
@click="hanldeToggleSideBar"
></i>
<Breadcrumb class="bread"></Breadcrumb>
</div>
</template>
<script>
import Breadcrumb from '@/components/Breadcrumb'
import { mapGetters } from 'vuex'
export default {
computed: {
...mapGetters(['sidebar']),
getIcon() {
return this.sidebar.opened ? 'el-icon-s-fold' : 'el-icon-s-unfold'
}
},
components: {
Breadcrumb
},
data() {
return {
}
},
methods: {
hanldeToggleSideBar() {
this.$store.dispatch('app/toggleSidebar')
}
}
}
</script>
<style lang="scss" scoped>
.navbar {
height: 100%;
display: flex;
align-items: center;
.bread {
margin-left: 12px;
}
}
</style>
image.png
slidebar index
<template>
<div class="sidebar">
<logo :isCollapse="isCollapse"></logo>
<el-menu
:collapse="isCollapse"
:collapse-transition="false"
class="sidebar-menu"
>
<sidebar-item></sidebar-item>
</el-menu>
</div>
</template>
<script>
import Logo from './Logo'
import SidebarItem from './SidebarItem'
export default {
props: ['isCollapse'],
// data() {
// return {
// isCollapse: false
// }
// },
components: {
Logo,
SidebarItem
}
}
</script>
<style lang="scss" scoped>
.sidebar {
.sidebar-menu {
border-right: none;
}
}
</style>
logo
<template>
<div class="logo">
<img
src="@/assets/images/logo.png"
alt=""
>
<span
class="title"
v-show="!isCollapse"
>fly-admin</span>
</div>
</template>
<script>
export default {
props: ['isCollapse'],
data() {
return {
}
}
}
</script>
<style lang="scss" scoped>
.logo {
height: 50px;
background-color: #000;
display: flex;
align-items: center;
justify-content: center;
padding: 10px;
box-sizing: border-box;
img {
width: 32px;
height: 32px;
}
.title {
margin-left: 20px;
}
}
</style>
slidebaritem
<template>
<!-- <div class="side-item"> -->
<el-submenu index="1">
<template slot="title">
<i class="el-icon-location"></i>
<span slot="title">导航一</span>
</template>
<el-menu-item-group>
<span slot="title">分组一</span>
<el-menu-item index="1-1">选项1</el-menu-item>
<el-menu-item index="1-2">选项2</el-menu-item>
</el-menu-item-group>
</el-submenu>
<!-- </div> -->
</template>
<script>
export default {
data() {
return {
}
}
}
</script>
<style lang="scss" scoped>
</style>
index.js
export { default as AppMain } from './AppMain/index.vue'
export { default as Navbar } from './NavBar/index.vue'
export { default as Sidebar } from './Sidebar/index.vue'
layout index
<template>
<div class="app-wrapper">
<!-- 左侧 -->
<sidebar
:class="['sidebar-container', isCollapse ?'fold': 'unfold' ]"
:isCollapse="isCollapse"
></sidebar>
<!-- 右侧 -->
<div :class="['main-container', isCollapse ?'fold': 'unfold']">
<div class="fixed-header">
<navbar></navbar>
</div>
<app-main></app-main>
</div>
</div>
</template>
<script>
import { Navbar, AppMain, Sidebar } from './components'
import { mapGetters } from 'vuex'
export default {
computed: {
...mapGetters(['sidebar']),
isCollapse() {
return !this.sidebar.opened
}
},
components: {
Navbar,
AppMain,
Sidebar
}
}
</script>
<style lang="scss">
.app-wrapper {
position: relative;
.sidebar-container {
position: fixed;
width: 200px;
// background-color: #000;
height: 100vh;
color: #fff;
transition: width 0.3s;
&.fold {
width: 64px;
}
&.unfold {
width: 200px;
}
}
.main-container {
margin-left: 200px;
height: 100vh;
color: #000;
background-color: pink;
transition: margin-left 0.3s;
&.fold {
margin-left: 64px;
}
&.unfold {
margin-left: 200px;
}
.fixed-header {
height: 50px;
background-color: #fff;
padding: 10px;
box-sizing: border-box;
}
}
}
</style>
router
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const routes = [
{
path: '/',
component: () => import('../layout'),
redirect: '/welcome',
meta: {
title: '首页'
},
children: [
{
path: 'welcome',
component: () => import('../views/Welcome.vue'),
meta: {
title: '欢迎'
}
}
]
},
{
path: '/login',
component: () => import('../views/Login.vue')
},
{
path: '*',
component: () => import('../views/PageNoFound.vue')
}
]
const router = new VueRouter({
routes
})
export default router
store
modules
export default {
namespaced: true,
state: {
sidebar: {
opened: true
}
},
mutations: {
TOGGLE_SIDEBAR(state) {
state.sidebar.opened = !state.sidebar.opened
}
},
actions: {
toggleSidebar({ commit }) {
commit('TOGGLE_SIDEBAR')
}
}
}
getters.js
export default {
sidebar: state => state.app.sidebar
}
index.js
import Vue from 'vue'
import Vuex from 'vuex'
import app from './modules/app'
import getters from './getters'
Vue.use(Vuex)
export default new Vuex.Store({
modules: {
app
},
getters
})
utils
request
import axios from 'axios'
// import { Message } from 'element-ui'
// 配置aixos对象
const service = axios.create({
// baseURL: '/api'
baseURL: process.env.VUE_APP_BASE_API
})
// 请求拦截
service.interceptors.request.use(config => {
return config
}, err => {
Promise.reject(err)
})
// 响应拦截
service.interceptors.response.use(response => {
console.log(response)
return response
}, err => {
// Message({
// type: 'error',
// message: '网络请求失败'
// })
Promise.reject(err)
})
export default service
storage
const namespace = 'mall-admin'
export default {
setItem(key, val) {
const storage = this.getStorage()
storage[key] = val
window.localStorage.setItem(namespace, JSON.stringify(storage))
},
getItem(key) {
return this.getStorage()[key]
},
getStorage() {
return JSON.parse(window.localStorage.getItem(namespace) || "{}")
},
clearItem(key) {
const storage = this.getStorage()
delete storage[key]
window.localStorage.setItem(namespace, JSON.stringify(storage))
},
clearAll() {
window.localStorage.clear()
}
}