vue + ElementUI 搭建后台管理系統記錄
本文檔記錄了該系統從零配置的完整過程
項目源碼請訪問:https://gitee.com/szxio/vue2Admin,如果感覺對你有幫助,請點一個小星星,O(∩_∩)O
新建項目
vue create vueadmin
安裝 less-loader
安裝
這里是一個小坑,安裝 less-loader
時推薦安裝指定版本,如果安裝默認高版本會導致項目出錯
cnpm i less-loader@6.0.0 -D
使用
<style lang="less" scoped>
div{
b{
span{
color: red;
}
}
}
</style>
引入 ElementUI
安裝
cnpm i element-ui -S
配置
import Vue from 'vue'
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import App from './App.vue'
Vue.use(ElementUI);
Vue.config.productionTip = false
new Vue({
render: h => h(App)
}).$mount('#app')
使用
<template>
<div>
<el-row>
<el-button>默認按鈕</el-button>
<el-button type="primary">主要按鈕</el-button>
<el-button type="success">成功按鈕</el-button>
<el-button type="info">信息按鈕</el-button>
<el-button type="warning">警告按鈕</el-button>
<el-button type="danger">危險按鈕</el-button>
</el-row>
</div>
</template>
配置 VueRouter
npm安裝
- 安裝
npm install vue-router
- 新建
scr/router/index.js
,並添加如下代碼
import Vue from "vue";
import VueRouter from "vue-router";
Vue.use(VueRouter);
const routes = [
{
path: "/",
name: "首頁",
component: () => import("../views/Home.vue"),
},
{
path: "/about",
name: "About",
component: () => import("../views/About.vue"),
},
];
const router = new VueRouter({
mode: "history",
base: process.env.BASE_URL,
routes,
});
// 前置路由攔截器
router.beforeEach((to, from, next) => {
// 設置當前頁簽名稱
document.title = to.name;
next();
});
export default router;
配置前置路由攔截器動態設置每個頁面的瀏覽器頁簽名稱
- 修改
main.js
import Vue from 'vue'
import VueRouter from 'vue-router'
import router from './router'
new Vue({
router,
render: h => h(App)
}).$mount('#app')
- 修改
App.vue
<template>
<div id="app">
<router-view />
</div>
</template>
- 重啟項目,分別訪問如下地址可以查看頁面效果
VueCli安裝
如果項目是使用vue-cli創建的,則可以使用下面的命令直接生成上述代碼及兩個示例路由。它也會覆蓋你的 App.vue
,因此請確保在項目中運行以下命令之前備份這個文件
vue add router
動態生成左側菜單
添加layout組件
- 修改路由文件
首先我們要創建好 router
路由,修改 src\router\index.js
文件
import Vue from "vue";
import VueRouter from "vue-router";
import Layouts from "../layouts";
Vue.use(VueRouter);
const routes = [
{
path: "",
redirect: "home",
component: Layouts,
children: [
{
path: "/home",
meta: { title: "首頁", icon: "el-icon-s-home" },
component: () => import("../views/home"),
},
{
path: "system",
meta: { title: "系統管理", icon: "el-icon-s-home" },
component: Layouts,
children: [
{
path: "item1",
meta: { title: "用戶管理", icon: "el-icon-s-home" },
component: () => import("../views/system/item1"),
},
{
path: "item2",
meta: { title: "產品管理", icon: "el-icon-s-home" },
component: () => import("../views/system/item2"),
},
],
},
],
},
];
const router = new VueRouter({
mode: "history",
base: process.env.BASE_URL,
routes,
});
// 前置路由攔截器
router.beforeEach((to, from, next) => {
// 設置當前頁簽名稱
document.title = to.meta.title;
next();
});
export default router;
代碼說明:
- path:路由地址
- redirect:重定向到指定路由
- component:頁面對應的組件
- children:設置子路由,二級菜單
- meta:頁面的補充,用來聲明頁面的名稱和圖標等
我們將所有的頁面都放在根路由的 children 下面,如果下面的菜單沒有配置 children 屬性,則表示該菜單是一級菜單,如果設置了則表示二級菜單,可以多級嵌套。上面的路由對應的修改views
文件夾下的文件結構:
- 新建
src\layouts\index.vue
這個文件用來配置項目頁面的外殼,左側的菜單和頂部的面包屑都會在該文件夾中
頁面結構分成三大部分:
- 左側菜單
- 頂部面包屑
- 內容展示區域
對應成代碼結構如下
<template>
<div>
<div>左側菜單</div>
<div>
<div>頭部面包屑</div>
<div>內容展示區</div>
</div>
</div>
</template>
我們既然要將頁面在內容展示區顯示,所以我們對應的創建專門用來展示頁面的組件。
所以接下來新建 src\layouts\components\AppContent.vue
組件。組件代碼如下
<template>
<div>
<router-view/>
</div>
</template>
沒有看錯,很簡單,只要放置一個 router-view
標簽即可。然后將 AppContent
組件注冊到 layouts\index.vue
中
<template>
<div>
<div>左側菜單</div>
<div>
<div>頭部面包屑</div>
<div>
<AppContent />
</div>
</div>
</div>
</template>
<script>
import AppContent from "./components/AppContent.vue";
export default {
components: {
AppContent,
},
};
</script>
- 修改
App.vue
只保留 router-view
<template>
<div>
<router-view/>
</div>
</template>
現在我們打開頁面看到如下效果
修改頁面樣式
我們首頁雖然已經展示到了 appcontent
組件中,但是樣式並不是我們想要的效果。現在去修改src\layouts\index.vue
文件,添加如下代碼
<template>
<div class="app-wrapper">
<div class="sidebar-container">
左側菜單
</div>
<div class="main-container">
<div class="header-main">頭部面包屑</div>
<AppContent class="app-main" />
</div>
</div>
</template>
<script>
import AppContent from "./components/AppContent.vue";
export default {
components: {
AppContent,
}
}
</script>
<style lang="less" scoped>
.app-wrapper {
position: relative;
height: 100%;
width: 100%;
.sidebar-container {
-webkit-transition: width 0.28s;
transition: width 0.28s;
width: 200px !important;
background-color: #304156;
height: 100%;
position: fixed;
font-size: 0px;
top: 0;
bottom: 0;
left: 0;
z-index: 1001;
overflow: hidden;
-webkit-box-shadow: 2px 0 6px rgb(0 21 41 / 35%);
box-shadow: 2px 0 6px rgb(0 21 41 / 35%);
& > div {
width: 211px !important;
}
}
.main-container {
min-height: 100%;
-webkit-transition: margin-left 0.28s;
transition: margin-left 0.28s;
margin-left: 200px;
position: relative;
}
.main-container {
-webkit-transition: margin-left 0.28s;
transition: margin-left 0.28s;
position: fixed;
width: calc(100vw - 210px);
top: 50px;
right: 0;
bottom: 0;
left: 0;
.header-main {
position: fixed;
height: 50px;
width: calc(100% - 200px);
right: 0;
top: 0;
display: flex;
align-items: center;
border-bottom: 1px solid #ddd;
padding-left: 15px;
box-sizing: border-box;
}
.app-main {
min-height: 100%;
width: 100%;
position: relative;
overflow: hidden;
}
}
}
</style>
效果展示
引入左側菜單
- 新建
src\layouts\components\ElMenu\index.vue
組件,初始化代碼
<template>
<div>
<el-menu
default-active="2"
class="el-menu-vertical-demo"
background-color="#545c64"
text-color="#fff"
active-text-color="#ffd04b"
>
<!-- 可展開菜單 -->
<el-submenu index="1">
<template slot="title">
<i class="el-icon-location"></i>
<span>導航一</span>
</template>
<el-menu-item index="3">
<i class="el-icon-document"></i>
<span slot="title">導航三</span>
</el-menu-item>
</el-submenu>
<!-- 點擊菜單 -->
<el-menu-item index="2">
<i class="el-icon-menu"></i>
<span slot="title">導航二</span>
</el-menu-item>
</el-menu>
</div>
</template>
- 注冊
ElMenu
組件添加到src\layouts\index.vue
中
<template>
<div class="app-wrapper">
<!-- 左側菜單 -->
<ElMenu class="sidebar-container"/>
<!-- 右側操作區域 -->
<div class="main-container">
<!-- 頭部面包屑 -->
<div class="header-main">頭部面包屑</div>
<!-- 內容展示區 -->
<AppContent class="app-main" />
</div>
</div>
</template>
<script>
import AppContent from "./components/AppContent.vue";
import ElMenu from "./components/ElMenu/index.vue";
export default {
components: {
AppContent,
ElMenu,
},
};
</script>
<style lang="less" scoped>
...和上面一樣,這里省略
</style>
- 此時打開頁面可以看到左側菜單
遞歸菜單組件
目前我們看到的只是一個寫死的菜單,我們想要的是根據 router
文件自動生成對應的菜單,那么應該怎么做呢?
首先左側菜單的每一項都可以當做一個組件,然后獲取到 router
中的所有菜單,循環展示每一項菜單即可,那么就開始做吧!
新建 src\layouts\components\ElMenu\MenuItem.vue
組件,用來展示每一項的菜單名稱
修改 src\layouts\components\ElMenu\index.vue
頁面,引入 router.js
獲取定義的路由數據,並且引入 MenuItem
組件去循環展示每一項菜單
<template>
<div>
<el-menu
:default-active="$route.path"
class="el-menu-vertical-demo"
background-color="#545c64"
text-color="#fff"
active-text-color="#ffd04b"
>
<MenuItem
v-for="(route, index) in routersList"
:key="index"
:item="route"
:fatherPath="route.path"
></MenuItem>
</el-menu>
</div>
</template>
<script>
import routers from "../../../router";
import MenuItem from "./MenuItem.vue";
export default {
components: {
MenuItem,
},
data() {
return {
routersList: [],
};
},
mounted() {
// 獲取所有定義的一級菜單和多級菜單
this.routersList = routers.options.routes[0].children;
}
};
</script>
代碼說明:
在el-menu
標簽中我們定義了 :default-active="$route.path"
,這個含義表示默認選中當前路由菜單,如果是子級菜單會自動展開並選中,這是因為下面的代碼中我們會將每一個頁面的 path
作為菜單的 index
。
另外代碼中我們遍歷 MenuItem
組件時傳遞了每個菜單的對象 item
和每個菜單的路徑 fatherPaht
,現在我們要到 MenuItem
組件去根據這個兩個屬性做遞歸展示根菜單和多級菜單結構。來到 MenuItem
組件中,編寫如下代碼
<template>
<div>
<!-- 根菜單 -->
<router-link tag="span" :to="resolvePath()" v-if="!item.children">
<el-menu-item :index="resolvePath()">
<i :class="item.meta.icon"></i>
<span slot="title">{{ item.meta.title }}</span>
</el-menu-item>
</router-link>
<!-- 可展開菜單 -->
<el-submenu :index="resolvePath()" v-else>
<template slot="title">
<i :class="item.meta.icon"></i>
<span slot="title">{{ item.meta.title }}</span>
</template>
<!-- 這里遞歸去展示多級菜單 -->
<menu-item
v-for="(route, index) in item.children"
:key="index"
:item="route"
:fatherPath="resolvePath(route.path)"
>
</menu-item>
</el-submenu>
</div>
</template>
<script>
// 引入path用來處理路徑
import path from "path";
export default {
// 做組件遞歸時必須定義一個name。然后遞歸時的組件名就是這里的name值
name: "MenuItem",
props: {
// 上一級的路由信息
item: {
type: Object,
default: null,
},
// 上一級的路徑
fatherPath: {
type: String,
default: "",
},
},
data() {
return {};
},
methods: {
resolvePath(routePath = "") {
return path.resolve(this.fatherPath, routePath);
},
},
};
</script>
代碼說明
- 在做組件遞歸時,必須要在遞歸組件內聲明
name
屬性,屬性值就是當前組件的名稱,這樣才能實現多級嵌套循環效果。
另外在ElementUI 中的菜單分成兩種類型,分別如下
<el-menu-item index="4">
<i class="el-icon-setting"></i>
<span slot="title">導航四</span>
</el-menu-item>
- 這種的表示根菜單
<el-submenu index="1">
<template slot="title">
<i class="el-icon-location"></i>
<span>導航一</span>
</template>
<el-menu-item index="4">
<i class="el-icon-setting"></i>
<span slot="title">導航四</span>
</el-menu-item>
</el-submenu>
- 這種的表示一個可展開的菜單,我們根據路由有沒有
children
來判斷這個菜單是否有子菜單
在根菜單外層添加了一個 router-link
實現了點擊菜單跳轉到不同頁面
現在我們來查看效果
菜單上出現了一個根菜單和一個二級菜單
添加路由自動完成菜單嵌套
現在我們已經完成了一個二級菜單的展示,那么我們添加一個三級路由會不會自動出現三級菜單呢?
首先新建一個測試頁面,在文件夾 item2
下面新建一個 item2-1
,並且在里面添加一個 index.vue
文件,如下圖:
然后去 src\router\index.js
添加這個頁面的路由
添加完成后可以發現產品管理菜單自動變成了一個可展開的菜單,展開后里面有一個類別列表菜單
添加頭部面包屑
基礎用法
我們想要在頭部添加一個如下的效果,可以很清晰的知道當前瀏覽的是哪個頁面
- 在
layouts
文件夾添加HeaderNav
組件,組件地址:src\layouts\components\HeaderNav.vue
,添加如下初始代碼
<template>
<div>
<el-breadcrumb separator="/">
<el-breadcrumb-item :to="{ path: '/' }">首頁</el-breadcrumb-item>
<el-breadcrumb-item><a href="/">活動管理</a></el-breadcrumb-item>
<el-breadcrumb-item>活動列表</el-breadcrumb-item>
<el-breadcrumb-item>活動詳情</el-breadcrumb-item>
</el-breadcrumb>
</div>
</template>
- 然后再
src\layouts\index.vue
文件中引入HeaderNav
組件
<template>
<div>
<div class="app-wrapper">
<!-- 左側菜單 -->
<ElMenu class="sidebar-container" />
<!-- 右側操作區域 -->
<div class="main-container">
<!-- 頭部面包屑 -->
<HeaderNav class="header-main" />
<!-- 內容展示區 -->
<AppContent class="app-main" />
</div>
</div>
</div>
</template>
<script>
import AppContent from "./components/AppContent.vue";
import ElMenu from "./components/ElMenu/index.vue";
import HeaderNav from "./components/HeaderNav.vue";
export default {
components: {
AppContent,
ElMenu,
HeaderNav,
}
};
</script>
<style lang="less" scoped>
樣式省略。。。
</style>
- 此時我們的頁面效果是這樣的
是不是有點感覺了呢
- 接下只需要監聽頁面的變化去實時獲取最新的路由信息即可,然后循環遍歷顯示
實現代碼:
<template>
<div>
<el-breadcrumb separator-class="el-icon-arrow-right">
<el-breadcrumb-item
v-for="(route, index) in breadcrumbItems"
:key="index"
>
<i :class="route.icon"></i>
<span>{{ route.title }}</span>
</el-breadcrumb-item>
</el-breadcrumb>
</div>
</template>
<script>
export default {
data() {
return {
breadcrumbItems: [],
};
},
mounted() {
this.geBreadcrumbItems(this.$route);
},
methods: {
geBreadcrumbItems(route) {
// 獲取當前頁面的路由組
this.breadcrumbItems = route.matched;
// 從下標為1的位置開始獲取路由,去除了最外層定義的根路由信息,並且獲取到的數組里面只有meta數據,方便我們取值
this.breadcrumbItems = this.breadcrumbItems
.map((item) => item.meta)
.splice(1);
},
},
watch: {
$route: function (newVal) {
this.geBreadcrumbItems(newVal);
},
},
};
</script>
效果展示
添加首頁快速入口
我們已經實現了基本效果,但是我們還想在面包屑的首位添加首頁的連接,點擊首頁文字快速跳轉到到首頁
修改 src\layouts\components\HeaderNav.vue
代碼為如下
<template>
<div>
<el-breadcrumb separator-class="el-icon-arrow-right">
<el-breadcrumb-item
v-for="(route, index) in breadcrumbItems"
:key="index"
>
<!-- 判斷面包屑是否有path屬性,如果有則顯示router-link標簽 -->
<router-link v-if="route.path" :to="route.path">
<i :class="route.icon"></i>
<span>{{ route.title }}</span>
</router-link>
<!-- 如果沒有path屬性則不跳轉 -->
<template v-else>
<i :class="route.icon"></i>
<span>{{ route.title }}</span>
</template>
</el-breadcrumb-item>
</el-breadcrumb>
</div>
</template>
<script>
export default {
data() {
return {
breadcrumbItems: [],
};
},
mounted() {
this.geBreadcrumbItems(this.$route);
},
methods: {
geBreadcrumbItems(route) {
// 獲取當前頁面的路由組
this.breadcrumbItems = route.matched;
// 從下標為1的位置開始獲取路由,去除了最外層定義的根路由信息,並且獲取到的數組里面只有meta數據,方便我們取值
this.breadcrumbItems = this.breadcrumbItems
.map((item) => item.meta)
.splice(1);
// 判斷當前頁面是否已經是首頁
let nowPath = route.path;
// 如果當前頁面不是首頁,則在面包屑的首位置添加一個首頁鏈接
if (nowPath !== "/home") {
this.breadcrumbItems.unshift({
title: "首頁",
icon: "el-icon-s-home",
path: "/home",
});
}
},
},
watch: {
$route: function (newVal) {
this.geBreadcrumbItems(newVal);
},
},
};
</script>
修改之后頁面效果是當我們進入非首頁頁面時,面包屑前面會有一個首頁的快速入口,當進入首頁時不會展示首頁連接
個性化菜單配置
配置獨立頁面
現在我們看到的頁面都嵌套在左側菜單和面包屑下面,但是有些頁面時不能在這個嵌套頁面的,例如登錄頁面。那么我們怎么通過配置路由來實現這樣的效果呢?
首先添加登錄頁面,新建 src\views\login\index.vue
,編寫如下代碼
<template>
<div>
登錄頁面
</div>
</template>
添加完登錄頁面后前往 src\router\index.js
文件添加路由信息,如下圖
我們在登錄頁面的路由信息中的增加一個 oneself:true
的標識,用來標識這個頁面時獨自打開的,不需要嵌套在菜單下
添加完路由后找到 src\layouts\index.vue
頁面修改為如下代碼
<template>
<div>
<!-- 判斷是否在空白頁打開 -->
<template v-if="!isOneself">
<div class="app-wrapper">
<div class="sidebar-container">
<ElMenu />
</div>
<div class="main-container">
<HeaderNav class="header-main" />
<AppContent class="app-main" />
</div>
</div>
</template>
<!-- 如果在空白頁打開則不顯示框架 -->
<template v-else>
<AppContent />
</template>
</div>
</template>
<script>
import AppContent from "./components/AppContent.vue";
import ElMenu from "./components/ElMenu/index.vue";
import HeaderNav from "./components/HeaderNav.vue";
export default {
components: {
AppContent,
ElMenu,
HeaderNav,
},
data() {
return {
isOneself: false,
};
},
mounted() {
// 獲取當前路由是否是獨自打開的
this.isOneself = this.$route.meta.oneself;
},
watch: {
// 監聽路由變化,實時獲取路由信息
$route: function (newVal) {
this.isOneself = newVal.meta.oneself;
},
},
};
</script>
<style lang="less" scoped>
css省略。。。
</style>
修改完成后查看頁面效果
效果很明顯,點擊了登錄后左側的菜單和面包屑都沒有了,瀏覽器只會展示登錄頁面信息。
到這里我們會發現登錄頁面作為了一個菜單項顯示到了左側菜單中,這個問題怎么解決呢?
配置隱藏菜單
找到 src\router\index.js
文件,為登錄頁面添加一個 hide:true
,如下圖,這個屬性用來表示這個頁面不在左側菜單中顯示
添加完成后找到 src\layouts\components\ElMenu\MenuItem.vue
文件,在根標簽上添加一個 v-if
判斷,用來判斷當前菜單是否需要被渲染
由於這個功能所添加的代碼極少,所以就不貼代碼了。修改完之后查看頁面
通過動畫可以看到登錄頁面已經不在菜單中展示,修改頁面地址也會正常的在新頁面中打開。
配置外部連接
現在我們配置的地址只能配置我們項目中的地址,那么我需要點擊菜單直接打開百度怎么做呢?
首先添加路由信息如下
此時我們點擊菜單並不能正常的打開百度
這是因為我們並沒有判斷頁面的 path
類型。
接下來新建 src\layouts\components\ElMenu\MenuLink.vue
,編寫如下代碼
下面代碼的含義是定義了一個動態組件,根據父組件傳遞過來的路徑類型顯示不同的組件
<template>
<component :is="type" v-bind="linkProps(to)">
<slot />
</component>
</template>
<script>
export default {
props: {
// 接收從父組件傳遞過來的頁面地址
to: {
type: String,
required: true,
},
},
computed: {
isExternal() {
return /^(https?:|mailto:|tel:)/.test(this.to);
},
type() {
// 根據路徑判斷組件類型,如果是外部連接則用a標簽
if (this.isExternal) {
return "a";
}
// 如果不是外部連接則用router-link組件包裹
return "router-link";
},
},
methods: {
// 綁定組件屬性
linkProps(to) {
// 如果是外部連接則設置a標簽的href地址為傳遞過來的地址,並且設置在新標簽打開
if (this.isExternal) {
return {
href: to,
target: "_blank",
style: {
"text-decoration": "none",
},
};
}
// 如果是內部地址則設置router-link的to屬性值,以及tag屬性值為span
return {
to: to,
tag: "span",
};
},
},
};
</script>
然后找到 src\layouts\components\ElMenu\MenuItem.vue
文件,引入剛剛新建 MenuLink
組件
修改代碼如下
<template>
<!-- 判斷當前頁面是否顯示,如果hide為true,則不渲染該菜單 -->
<div v-if="!item.meta.hide">
<!-- 根菜單 -->
<MenuLink :to="resolvePath()" v-if="!item.children">
<el-menu-item :index="resolvePath()">
<i :class="item.meta.icon"></i>
<span slot="title">{{ item.meta.title }}</span>
</el-menu-item>
</MenuLink>
<!-- 可展開菜單 -->
<el-submenu :index="resolvePath()" v-else>
<template slot="title">
<i :class="item.meta.icon"></i>
<span slot="title">{{ item.meta.title }}</span>
</template>
<!-- 這里遞歸去展示多級菜單 -->
<menu-item
v-for="(route, index) in item.children"
:key="index"
:item="route"
:fatherPath="resolvePath(route.path)"
>
</menu-item>
</el-submenu>
</div>
</template>
<script>
// 引入path用來處理路徑
import path from "path";
import MenuLink from "./MenuLink.vue";
export default {
// 做組件遞歸時必須定義一個name。然后遞歸時的組件名就是這里的name值
name: "MenuItem",
components: {
MenuLink,
},
props: {
// 上一級的路由信息
item: {
type: Object,
default: null,
},
// 上一級的路徑
fatherPath: {
type: String,
default: "",
},
},
data() {
return {};
},
methods: {
// 判斷路徑是否是外部地址
isExternal(path) {
return /^(https?:|mailto:|tel:)/.test(path);
},
// 解析頁面地址
resolvePath(routePath = "") {
// 判斷當前頁面地址是否為外部地址
if (this.isExternal(routePath)) {
return routePath;
}
// 判斷從父組件傳遞過來的地址是否為外部地址
if (this.isExternal(this.fatherPath)) {
return this.fatherPath;
}
// 格式化頁面地址
return path.resolve(this.fatherPath, routePath);
},
},
};
</script>
圖片說明修改點
修改完成后查看頁面效果
現在可以看到點擊百度搜索菜單后在新頁簽打開了百度。
配置多環境地址
首先安裝 cross-env
npm i --save-dev cross-env
然后修改 package.json
文件中的 scripts
對象
{
......省略其他
"scripts": {
"serve": "cross-env VUE_APP_ENV=dev vue-cli-service serve",
"build": "cross-env VUE_APP_ENV=production vue-cli-service build",
"lint": "vue-cli-service lint"
},
......省略其他
}
我們在啟動命令和打包命令前添加 cross-env
關鍵字,然后使用鍵值對的方式對一個變量賦值 VUE_APP_ENV=dev
然后新建src\utils\baseurl.js
文件,編寫如下代碼
// 封裝公共的請求api
const apiConfig = {
// 開發環境
dev: {
fayongApi: "https://192.168.199.100"
},
// 生產環境
production: {
fayongApi: "https://appsh.yikongenomics.com"
},
};
// 根據全局全局變量自動切換請求地址前綴
export default apiConfig[process.env.VUE_APP_ENV];
關鍵代碼:process.env.VUE_APP_ENV
通過這個可以獲取到輸入不同命令式設置的不同值。
最后我們在頁面中引入 baseurl
來查看當前獲取的環境地址
<template>
<div>
首頁
</div>
</template>
<script>
import env from "../../utils/baseurl"
export default {
data() {
return{
}
},
mounted(){
console.log(env.fayongApi); //=> https://192.168.199.100
}
}
</script>
此時獲取到的就是本地的一個地址,當我們打包后,這里就會自動變成線上地址,從而實現了多套環境的搭建和根據打包命令自動切換的功能。
配置代理和publicPath
在項目根目錄新建 vue.config.js
。配置代碼如下
module.exports = {
publicPath: "./",
devServer: {
disableHostCheck: true, //禁用主機檢查
proxy: {
"/fayong": { // 設置以什么前綴開頭的請求用來代理
target: "http://w79f7c.natappfree.cc/index", //要訪問的跨域的域名
secure: false, // 使用的是http協議則設置為false,https協議則設置為true
changOrigin: true, //開啟代理
pathRewrite: {
"^/fayong": "",
},
}
},
},
};
然后重啟項目生效
簡單封裝一下 axios
首先安裝 axios
npm i axios --save
然后新建 src\utils\http.js
,編寫如下代碼
// 引入axiox
import axios from 'axios'
// 創建axios實例
const service = axios.create()
// 請求攔截器
axios.interceptors.request.use(function (config) {
// 在這里可以添加請求頭,請求token等信息
return config;
}, function (error) {
// 對請求錯誤做些什么
return Promise.reject(error);
});
// 響應攔截器
service.interceptors.response.use(function (result) {
// 判斷成功
const { status, data } = result
// 判斷接口返回狀態
if (status === 200) {
// 如果接口正常則返回接口給的數據
return data
} else {
// 如果不正常則返回一個錯誤信息
return Promise.reject('系統未知錯誤,請反饋給管理員')
}
}, function (error) {
// 返回錯誤信息
return Promise.reject(error)
})
export default service
最后來使用一下
import http from '../../utils/http'
export default {
data() {
return {}
},
methods: {
test() {
http
.get(`node/search/users?q=songzx`)
.then((res) => {
console.log(res)
})
.catch((err) => {
console.log(err)
})
},
},
}
查看控制台拿到的數據就是接口直接返回的數據
封裝全局Loading方法
在 main.js
中添加如下方法
/**
* 配置全局loading提示框
* 顯示loading this.showLoading()
* 關閉loading this.hideLoading()
*/
Vue.prototype.loading = null
Vue.prototype.showLoading = function (msg = 'Loading') {
Vue.prototype.loading = this.$loading({
lock: true,
text: msg,
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
});
}
Vue.prototype.hideLoading = function(){
Vue.prototype.loading.close();
}