電商后台管理系統
項目源碼:碼雲
微信號:RanY_Luck
1、前端項目的技術棧
- vue
- vue-router
- Element-UI
- Axios
- Echarts
2、后端項目技術棧
- Node.js
- Express
- Jwt
- Mysql
- sequelize
項目前端初始化
- 安裝Vue腳手架
- 通過Vue腳手架創建項目
- 配置Vue路由
- 配置Element—UI組件庫
- 配置Axios庫
- 初始化git遠程倉庫
- 將本地項目托管到github或碼雲中
1、安裝Vue腳手架
npm install -g @vue/cli
2 、通過Vue腳手架創建項目(通過可視化創建)
vue ui
3、安裝Element-UI
4、配置Axios庫
5、配置less、less-loader開發依賴
項目所有依賴
啟動服務並啟動app
你會看到這樣的一個畫面
5、將本地項目托管到碼雲中
測試一下:
項目后端初始化
1、安裝MySql數據庫
2、安裝Node.js環境
3、配置項目相關信息
4、啟動項目
node app.js
5、使用Postman測試后台項目接口是否正常
登錄/退出功能
原理
登錄功能代碼實現
通過Element-UI組件實現布局
- el-form
- el-form-item
- el-input
- el-button
- 字體圖標
代碼解讀
main.js
刪除views
清空頁面
<template>
<div id="app">
</div>
</template>
<script>
// 導入helloword
export default {
name: 'app'
}
</script>
<!-- style樣式 -->
<style>
</style>
創建一個comments目錄
創建Login.vue文件
<template>
<div class="login_container">
<!-- 登錄主體邊框 -->
<div class="login_box">
<!-- 頭像區域 -->
<div class="avater_box">
<img src="../assets/logo.png" alt="頭像logo">
</div>
<!-- 登錄表單區域 -->
<el-form :model="loginForm" :rules="rules" ref="loginFormRef" label-width="0px" class="login_form">
<!-- 用戶名 -->
<el-form-item prop="username">
<el-input v-model="loginForm.username" placeholder="請輸入賬號" prefix-icon="iconfont icon-RectangleCopy"></el-input>
</el-form-item>
<!-- 密碼 -->
<el-form-item prop="password">
<el-input v-model="loginForm.password" placeholder="請輸入密碼" prefix-icon="iconfont icon-RectangleCopy1" type="password"></el-input>
</el-form-item>
<!-- 按鈕區域 -->
<el-form-item class="btns">
<el-button type="primary" @click="login">登錄</el-button>
<el-button type="info" @click="resetLoginForm('loginForm')">重置</el-button>
</el-form-item>
</el-form>
</div>
</div>
</template>
<script>
export default {
data () {
return {
// 這是登錄表單的數據綁定對象
loginForm: {
username: 'admin',
password: '123456'
},
// 這是表單的驗證規則對象
rules: {
// 驗證用戶名是否合法
username: [
{ required: true, message: '請輸入登錄賬號', trigger: 'blur' },
{ min: 3, max: 10, message: '長度在 3 到 10 個字符', trigger: 'blur' }
],
// 驗證密碼是否合法
password: [
{ required: true, message: '請輸入登錄密碼', trigger: 'blur' },
{ min: 6, max: 15, message: '長度在 6 到 15 個字符', trigger: 'blur' }
]
}
}
},
methods: {
// 點擊重置按鈕,重置登錄表單
resetLoginForm () {
// 前提是先獲取ref節點
this.$refs.loginFormRef.resetFields()
},
login () {
// 表單之前的預驗證
this.$refs.loginFormRef.validate(async valid => {
if (!valid) return;
const { data: res } = await this.$http.post('login', this.loginForm);
if (res.meta.status !== 200) return this.$message.error('登錄失敗! ');
this.$message.success('登錄成功');
// 1. 將登陸成功之后拿到后端返回的token值,保存到客服端也就是臨時瀏覽器sessionStorage中
// 1.1 項目中出了登錄之外的其他api接口,必須在登錄之后才能訪問
// 1.2 token只應在當前網站打開期間生效,所以將token保存在sessionStorage中
const data = res.data.token;
window.sessionStorage.setItem('token', data);
// 2. 通過編程式導航跳轉到后台主頁,路由地址是 /home
this.$router.push('/home');
})
}
}
}
</script>
<style lang="less" scoped="">
.login_container {
background: #2b4b6b;
height: 100%;
}
.login_box {
width: 450px;
height: 300px;
background-color: #fff;
border-radius: 3px;
position: absolute; // 絕對定位
left: 50%;
top: 50%;
transform: translate(-50%, -50%); // 在橫軸上進行位移-50%,縱軸上位移-50%
// 語法嵌套
.avater_box {
height: 130px;
width: 130px;
border: 1px solid #eee; // 邊框
border-radius: 50%; // 添加圓角邊框
padding: 10px; // 內邊距
box-shadow: 0 0 10px #ddd; // 添加陰影
position: absolute; // 絕對定位
left: 50%;
transform: translate(-50%, -50%); // 在橫軸上進行位移-50%,縱軸上位移-50%
background-color: #fff;
img {
width: 100%;
height: 100%;
border-radius: 50%; // 添加圓角邊框
background-color: #eee;
}
}
}
.btns {
display: flex; // 彈性布局
justify-content: flex-end; // 位於容器的結尾
}
.login_form {
position: absolute; // 絕對定位
bottom: 0; // 底部對齊
width: 100%;
padding: 0 20px;
box-sizing: border-box; // 將元素限制到寬度里面
}
</style>
<div id="app">
<!-- 路由占位符 -->
<router-view></router-view>
</div>
<script>
// 導入helloword
export default {
name: 'app'
}
</script>
<!-- style樣式 -->
<style>
</style>
訪問頁面
現在需要讓用戶訪問根目錄就自動跳轉到login頁面
tips:
post返回值是一個Promise 對象,為了簡化Promise操作,我們可以用async await 來優化
await 只能用在async的方法中,所以需要把vaild修飾成異步,這樣就能直接拿到服務器返回的數據{ data: res }中的data 才是服務器的真實數據,然后重命名為res對象,然后在根據res的meta屬性來判斷是否為200,為200就登錄成功並打印,不為200就失敗並打印。
進行登錄跳轉
第一步:你需要進行組件導入
進行全局導入后,以后用到message就可以直接用this.$message.xxx()
第二步:代碼使用
路由導航守衛控制訪問權限
// 為路由對象,添加 beforeEach 導航守衛
router.beforeEach((to, form, next) =>{
// 如果用戶訪問的登錄頁,直接放行
if(to.path === '/login') return next()
// 從 sessionStorage 中獲取保存的token值
const tokenStr = window.sessionStorage.getItem('token')
// 沒有token,強制跳轉到登錄頁
if(!tokenStr) return next('/login')
next()
})
判斷用戶在沒有token了自動跳轉到登錄界面
需要進行router.js改寫
退出功能
退出功能實現原理
基於token的方式實現退出比較簡單,只需要銷毀本地的token即可。這樣,后續的請求就不會攜帶token,必須重新登錄生成一個新的token之后才可以訪問
// 清空token
window.sessionStorage.clear();
// 跳轉到登錄頁
this.$router.push('/login')
主頁布局
<el-container>
// 頭部區域
<el-header></el-header>
<el-container>
// 側邊欄區域
<el-asider></el-asider>
// 右側主體區域
<el-main></el-main>
</el-container>
</el-container>
左側菜單布局
<el-menus>
<el-submenu>
// 這個template 是一級菜單的內容模版
<i class="el-icon-menu"></i>
<span>一級菜單</span>
// 在一級菜單中,可以嵌套二級菜單
<el-menu-item>
<i class="el-icon-menu"></i>
<span slot="title">二級菜單</span>
</el-menu-item>
</el-submenu>
</el-menus>
<!-- 側邊欄 -->
<el-aside width="200px">
<!-- 側邊欄菜單區 -->
<el-menu background-color="#333744" 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="1-4-1">
<!-- 圖標 -->
<i class="el-icon-location"></i>
<!-- 文本 -->
<span>二級菜單</span>
</el-menu-item>
</el-submenu>
</el-menu>
</el-aside>
需要element.js進行注冊
通過接口獲取菜單數據
通過axios請求攔截器添加token,保證擁有獲取數據的權限
// axios請求攔截(預處理)
axios.interceptors.request.use(config =>{
// 為請求頭對象添加Token驗證的Authorization字段
config.headers.Authorization = window.sessionStorage.getItem('token')
return config
})
對接口請求,獲取詳細信息:
就可以看到已經獲取到數據,所有的一級菜單都放在了data數據中,二級菜單就嵌到了children中
拿到了數據 我們就需要渲染到頁面中
第一步:需要在一級菜單進行v-for循環
第二步:需要在一級菜單的基礎上對二級菜單再進行v-for循環
代碼:
不過可以看到一級菜單的圖標都為統一不是很好看,我們需要整改下
第一步:先自定義iconsObj
第二步:在一級菜單的圖標中進行v-bind雙向綁定
效果:
fix展開后對不齊的問題,先看效果:
經過分析:
於是可以在css選擇器中添加個border-right: none;就可以了
fix可以將一級菜單全部展開,先看效果:
經過分析:element-ui是默認展開的,不過也提供了只保持一個子菜單展開的api
水平折疊收起菜單
經過分析:element-ui是默認不折疊的,不過也提供了只保持一個子菜單展開的api
第一步:在el-menu新增
第二步:自定義一個div,並賦予click事件
第三步:在data()定義初始值
第四步:動態賦值側邊欄寬度
路由重定向
第一步:創建個Welcome.vue文件
第二步:在router里面導入Welcome.vue
第三步:在Home.vue中渲染出Welcome.vue的內容
側邊欄路由跳轉
步驟一:
步驟二:
效果:
用戶列表的開發
第一步:在comments里新建一個user的文件夾,創一個Users.vue的文件
第二步:在router里面引用
效果:
fix點擊二級菜單不會高亮,刷新后又重置
步驟一:在側邊欄增加default-active語法
第二步:我們需要動態渲染路徑
組件創建了需要執行created生命周期函數
在點擊不同連接的時候,我們需要給activePath重新賦值
這樣就不會點了其他高亮然后再點回來不高亮啦(可能有點繞)
用戶列表
增加面包屑
步驟一:element-ui給出了面包屑的方案
我們只需要復制過來
步驟二:需要在element.js中進行按需引入
效果:
增加Card卡片
步驟一:element-ui給出了卡片的方案
我們只需要復制過來刪除不必要的東西
增加Layout布局之分欄間隔
步驟一:element-ui給出了卡片的方案
我們只需要復制過來刪除不必要的東西
效果:
tips:
需要對card做樣式修改。可以在global.css中做全局設定,當然也可以自建class進行修改樣式
增加獲取用戶列表數據
第一步:查看接口文檔
第二步:將接口請求參數定義到data中
第三步:進行axios請求
第四步:定義空列表
第五步:賦值數據到空列表中
增加渲染用戶列表數據
快速入門Table表格(element-ui提供了方法)
第一步:
第二步:copy代碼
第三步:重置樣式
效果:
發現序號id,值非常大,不便於查看,我們需要自己創建一個索引,特別簡單
效果:
增加狀態開關
快速入手Switch開關(element-ui提供了方法)
步驟一:作用域插槽
步驟二:將v-model綁定到作用域的mg_state
效果:
fix更改后刷新重置,沒有更改數據庫值
步驟一:element-ui給了一個解決方法api
步驟二:修改用戶狀態接口(put)方法
步驟三:監聽switch開關狀態的改變
接口地址分析:
效果:
增加操作按鈕
快速入手Tooltip 文字提示(element-ui提供了方法)
步驟一:
步驟二:在element.js按需導入
效果:
增加分頁模塊
快速入手Pagination分頁(element-ui提供了方法)
步驟一:
事件名稱 | 說明 |
---|---|
size-change | pageSize 改變時會觸發 |
current-change | currentPage 改變時會觸發 |
current-page | 當前頁數 |
page-sizes | 每頁顯示個數選擇器的下拉 |
page-size | 每頁顯示條目個數 |
layout | 組件布局,子組件名需要用逗號隔開 |
total | 總條目數 |
步驟二:傳參
第三步:在element.js按需導入
第四步:重置樣式(global.css)
效果:
增加搜索/清空功能
效果:
增加添加用戶對話框
快速入手Dialog對話框(element-ui提供了方法)
第二步:進入element.js按需引入
第三步:初始化對話框為隱藏
第四步:在添加用戶這個按鈕上給一個click事件,並賦值為true
效果:
完善添加用戶表單
步驟一:
model數據綁定對象 rules驗證規則對象 ref引用對象 label-width確定了文本所占寬度
步驟二:添加表單用戶的表單數據
步驟三:添加表單的驗證規則對象
效果:
新增郵箱、手機校驗規則
快速入手Form表單自定義校驗規則(element-ui提供了方法)
步驟一:查看官方文檔示例
因為郵箱/手機這種校驗規則比較復雜,這里推薦大家下個插件
步驟二:增加校驗規則
效果:
fix填寫完表單后重新打開未重置效果
第一步:element-ui給出了Form表單重置方案
第二步:寫一個close的關閉事件
第三步:
效果:
添加用戶
請求預校驗
步驟一:當點擊確定時,我們需要預加載數據看是否符合規則
效果:
請求添加一個新用戶
第一步:查看接口文檔
第二步:發起axios請求
效果:
操作之編輯
增加修改用戶對話框
第一步:使用Dialog對話框(element-ui給出了例子)
第二步:在編輯按鈕上增加click事件
第三步:增加編輯對話框
第四步:methods增加顯示為true
第五步:控制修改用戶對話框顯示與隱藏
效果:
增加根據用戶id查詢用戶信息
第一步:使用scope.row.id獲取到用戶id
第二步:查看接口文檔
第三步:進行接口文檔的調用
第四步:在data中創建editForm
第五步:res的數據保存到第四步中
效果:點擊編輯按鈕后將id傳入到api接口中
增加編輯表單
第一步:制作表單
第二步:定義驗證規則
效果:
fix驗證不通過存留狀態
第一步:添加一個click事件
第二步:監聽修改用戶關閉對話框
增加提交修改預校驗表單
第一步:在提交按鈕上增加一個click事件
第二步:進行預校驗
效果:
增加修改用戶信息操作
步驟一:看后端接口
步驟二:在確定按鈕上添加click事件
效果:
增加刪除用戶信息操作
第一步:導入MessageBox 彈框(element-ui給出了方案)
第二步:在刪除按鈕上增加一個click(id)事件
第三步:根據id刪除對應用戶信息(參考elementui給出的方案)
效果:
第四步:使用接口文檔進行刪除用戶信息
第五步:調用接口
效果:
增加分配角色操作
第一步:導入Dialog對話框 彈框(element-ui給出了方案)
第二步:在分配角色按鈕新增click事件
第三步:在data中定義對話框初始化為隱藏
第四步:點擊角色分配按鈕就進行展示為true
效果:
增加分配角色操作之下拉選擇職位
第一步:在data創建接收對象
第二步:查看接口文檔
第三步:接口請求
第四步:導入Select選擇器(element-ui給出了方案)
第五步:賦予一個接收選中對象的值
第六步:進行組件注冊
效果:
新增選擇職位后點擊確定應用
第一步:在確定按鈕增加click事件
第二步:查看接口文檔
第三步:接口調用
效果:
fix第二次選擇進行重置
第一步:給分配角色一個close事件
第二步:重置列表
效果:
權限列表
增加權限列表路由
第一步:寫Rights.vue
第二步:在路由引入步驟一
注意:因為在home里面繼續跳轉,所以權限列表為home的子路由
效果:
權限列表的基本布局
第一步:使用面包屑
第二步:使用card卡片
效果:
權限列表的數據獲取
第一步:創建一個權限列表的接收對象
第二步:創建生命周期
第三步:查看接口文檔
第四步:創建方法並聲明
效果:
表格渲染
第一步:使用el-card
第二步:使用el-table表格
第三步:使用el-table-column 填入數據 label 定義列名 width定義列寬
第四步:使用el-tag標簽
效果:
角色列表
增加角色列表路由
第一步:寫Rights.vue
第二步:在路由引入步驟一
注意:因為在home里面繼續跳轉,所以權限列表為home的子路由
效果:
角色列表基本布局
第一步:使用面包屑
第二步:使用card卡片
角色列表的數據獲取
第一步:創建一個權限列表的接收對象
第二步:創建生命周期
第三步:查看接口文檔
第四步:創建方法並聲明
效果:
表格渲染
第一步:使用el-card
第二步:使用el-row Layout布局
第三步:使用el-table/el-table-column 表格
效果:
新增下拉列表數據展示
第一步:使用插槽進行數據展示/v-for進行循環取出值
效果:
美化一級權限表格
第一步:增加樣式
第二步:
效果:
美化二級權限表格
第一步:
效果:
美化三級權限表格
第一步:
效果:
總體效果:
美化權限表格
第一步:創建一個樣式
第二步:將樣式放到需要的位置
效果:
新增刪除權限
第一步:使用可移除標簽(element ui給出了方案)
第二步:點擊移除標簽是觸發的事件
第三步:寫二次彈框(element ui 給出了方案)
效果:
fix刪除權限完整功能
第一步:查看接口文檔
第二步:接口請求
效果:
新增分配權限獲取所有權限數據
第一步:新增一個click事件
第二步:點擊分配權限彈框(element ui 給出了方案)
第三步:默認分配權限對話框為隱藏
第四步:點擊對話框就顯示
效果:
第五步:查看接口文檔
第六步:接口調用
效果:
新增分配權限樹形組件
快速入門Tree樹形控件(element-ui提供了方法)
第一步:
第二步:將控件樹形樹形控件屬性綁定對象
第三步:進行組件注冊
效果:
fix分配權限復選框/默認展開
第一步:在el-tree增加屬性(element-ui給了方案)
效果:
獲取角色原有權限
第一步:默認勾選節點key的數組(element ui給出了方案)
第二步:在data中定義一個接收對象
第三步:進行遞歸函數遍歷權限接口
第四步:在分配權限增加click事件並拿到所有數據
第五步:將role進行傳參,將獲取到的id傳入第三步defkeys中
效果:
fix點擊不同角色分配權限造成權限id累積
第一步:新增close事件
第二步:監聽分配權限對話框關閉事件,沒關閉一次,就像defkeys賦值一個空數組
新增角色權限增加
第一步:新增一個click事件在確定按鈕上
第二步:定義一個dom元素
第三步:選中權限點擊確定
el-tree給了2個函數,getCheckedKeys 節點選擇后返回節點的key所組成的數組
getHalfCheckedKeys 節點被選擇,返回目前半選節點的key所組成的數組
tips:...為JS中展開運算符
let a={x:1,y:2};
let b={z:3};
let ab={...a,...b};
ab //{x:1,y:2,z:3}
效果:
fix勾選權限點擊確定並應用
第一步:查看接口文檔
第二步:進行接口請求
效果:
商品分類
增加商品分類骨架
第一步:需要重新創建一個分支取名為:goods_cate
第二步:在comments創建一個goods目錄,創建Cate.vue
第三步:寫基礎骨架
// Cate.vue
<template>
<div>
商品分類組件
</div>
</template>
<script>
export default {
data() {
return {}
},
// 生命周期函數
created() {
},
// 所有的事件處理函數
methods: {
}
}
</script>
<style lang="less">
</style>
第四步:在路由引入
效果:
增加面包屑/按鈕/卡片基礎頁面
第一步:引入面包屑
第二步:引入卡片視圖
第三步:引入button按鈕
效果:
獲取商品分類后端數據
第一步:查看接口文檔
第二步:創建data數據
第三步:創建生命周期
第四步:接口請求
效果:
首次使用Vue-table-with-tree插件
第一步:安裝插件
進入到vue ui中依賴--安裝依賴---vue-table-with-tree-grid
第二步:在main.js引入插件
第三步:運用插件
data:指定綁定數據;columns:表格各列的配置;selection-type:關閉復選框
expand-type:關閉展開項;show-index:增加索引;index-text:索引名稱;border:顯示縱向邊框;show-row-hover:鼠標懸停是否高亮
第四步:錄入數據
效果:
美化表格
第一步:增加自定義模版列渲染,表格數據,定義插槽
第二步:添加對應樣式
效果:
新增排序/操作
第一步:增加自定義模版列渲染,表格數據,定義插槽
第二步:添加對應樣式
效果:
新增分頁區域
第一步:引入Pagination分頁(element ui給出了方案)
size-change:監聽pagesize事件;current-change:監聽pagenum事件;current-page:當前頁;page-sizes:顯示下拉條數;page-size:默認顯示條數;
total:總條數
第二步:在methods創建對應事件
效果:
新增添加分類彈出框
第一步:引入Dialog對話框(element ui給出了方案)
第二步:在data中初始化該對話框為隱藏
第三步:在添加分類button上增加一個click事件
第四步:在methods中處理事件
效果;
新增添加分類數據
第一步:引入Form表單(element ui給出了方案)
第二步:查看接口文檔
第三步:添加分類相關數據
效果:
獲取商品分類數據列表
第一步:查看接口文檔
第二步:接口請求
第三步:在data中定義一個接收對象
第四步:在點擊添加分類按鈕時進行觸發
效果:
新增父級分類下拉列表
第一步:引入Cascader級聯選擇器(element ui給出了方案)
步驟二:進行數據綁定
第三步:在勾選選項的時候觸發日志打印
效果:
第四步:進行組注冊
fix下拉數據過多導致顯示不全
效果:
將分類名稱數據綁定到父級分類中
第一步:進行數組length判斷
第二步:給確定按鈕增加一個click事件
第三步:日志打印
效果:
添加分類關閉清空已選數據
第一步:新增一個close事件
第二步:進行數據重置
效果:
新增點擊確定添加新的分類
第一步:查看接口文檔
第二步:調用接口
效果:
后續補寫編輯/刪除功能
分類參數
增加分類參數骨架
第一步:需要重新創建一個分支取名為:goods_params
第二步:在goods目錄創建Params.vue
第三步:寫基礎骨架
<template>
<div>
分類參數
</div>
</template>
<script>
export default {
data() {
},
created() {
},
methods: {
}
}
</script>
<style lang="less" scoped="">
</style>
第四步:在路由引入
效果:
增加面包屑/警告框/卡片基礎頁面
第一步:引入面包屑
第二步:引入卡片視圖
第三步:引入alert組件(element ui給出了方案)
第四步:進行組件注冊
第五步:增加商品分類
效果:
商品分類數據獲取
第一步:查看接口文檔
第二步:調用接口
效果:
商品分類的級聯選擇框
第一步:引入Cascader級聯選擇器(element ui給出了方案)
第二步:在data中定義數據
第三步:
效果:
fix不在同一水平面上展示
在樣式上添加屬性:
效果:
控制級聯選擇器的選擇范圍
第一步:獲取selectedCateKeys的長度后進行判斷
效果:
新增動態參數/靜態屬性 Tabs 標簽頁
第一步:引入Tabs標簽頁(element ui給出了方案)
第二步:在data中加入activeName參數
第三步:進行tabs頁簽點擊事件處理函數
第五步:注冊組件
效果:
新增添加按鈕和屬性/並控制禁用
第一步:新增button按鈕
第二步:新增一個計算屬性(computed)
效果:
獲取參數列表
第一步:查看接口文檔
第二步:在computed創建一個函數獲取到三級分類的id
第三步:接口調用
第四步:更改tabs標簽頁中的name
第五步:更改被激活的頁簽名稱
效果:
fix切換標簽沒有重新進行請求
第一步:將handleChange中的數據抽離出來,創建一個getParamsData函數
第二步:單獨添加該函數
效果:
動態參數表格和靜態參數表格渲染
第一步:在data中定義空數組
第二步:進行判斷數據屬於哪個標簽
第三步:進行表格渲染
效果:
新增添加參數/屬性對話框/form表單校驗
在添加參數按鈕新增一個click事件
第一步:引入Dialog對話框(element ui給出了方案)
第二步:在data中定義對話框默認隱藏
第三步:在computed中新增titleText達到對話框titile賦值
第四步:引入Form表單(element ui給出了方案)
第五步:在data中新增屬性
第六:監聽添加對話框的關閉事件
效果:
新增點擊確定添加動態參數或靜態屬性
第一步:查看接口文檔
第二步:在確定按鈕上新增click事件
第三步:接口請求
效果:
新增編輯功能
在編輯按鈕增加一個click事件
第二步:在data中定義對話框默認隱藏
第三步:引入Form表單(element ui給出了方案)
第四步:在data中新增屬性
第五步:關閉對話框進行重置
效果:
獲取動態參數值
采用作用域插槽進行attr_id獲取
第一步:查看接口文檔
第二步:調用接口
效果:
新增修改屬性值
第一步:查看接口文檔
第二步:調用接口
效果:
新增刪除功能
在刪除按鈕新增一個click事件
第一步:查看接口文檔
第二步:接口調用
引入MessageBox彈框(element ui給出了方案)
效果:
新增展開頁標簽
第一步:將數據進行分割重組
第二步:在展開行新增tag標簽頁,for循環
效果:
新增New Tags
第一步:引入New Tags(element ui給出了方案)
第二步:在data中定義相關初始值
第三步:在methods中定義方法
第四步:修改下寬度
效果:
fix修改New Tags 數據 關聯到其他New Tags
第一步:找到獲取參數列表的方法
每一行數據都有自己的bool和value
第二步:使用作用域插槽指定數據
第三步:刪除data中定義相關初始值
第四步:在click事件中傳入scope.row
第五步:在函數的形參中傳入row
效果:
fix點擊New Tags 自動獲取焦點
第一步:引入New Tags獲取焦點(element ui給出了方案)
效果:
fix失去焦點文本框與按鈕切換
第一步:在屬性框增加scope.row
第二步:失去焦點后,從input過度到tags
效果:
fix判斷用戶是否輸入無效字符(空格)進行重置
第一步:進行輸入值長度判斷
效果:
新增添加tags到數據庫操作
第一步:查看接口文檔
第二步:調用接口
效果:
新增刪除tag標簽
第一步:在tags中增加close事件
第二步:將添加tags到數據庫的方法單獨封裝一下
第三步:刪除對應參數可選項
效果:
fix選擇三級分類后再選擇二級分類數據依舊存在
第一步:
效果:
商品列表
增加商品列表參數骨架
第一步:需要重新創建一個分支取名為:goods_list
第二步:在goods目錄創建List.vue
第三步:寫基礎骨架
<template>
<div>
商品列表
</div>
</template>
<script>
export default {
data() {
return {}
},
created() {
},
methods: {}
}
</script>
<style lang="less" scoped="">
</style>
第四步:在路由引入
效果:
增加面包屑/輸入框/按鈕
第一步:引入面包屑
第二步:引入卡片視圖
第三步:引入輸入框/按鈕
效果:
商品列表數據獲取
第一步:查看接口文檔
第二步:定義參數
第三步:接口調用
效果:
新增表格區域數據渲染
第一步:
效果:
fix創建時間未格式化
第一步:全局定義格式化時間的過濾器
第二步:進行調用
新增分頁標簽功能
第一步:引入Pagination分頁(element-ui提供了方法)
第二步:創建方法
效果:
新增搜索/清空功能
第一步:在input輸入框增加數據綁定,清空,清空觸發功能
效果:
新增刪除功能
第一步:在刪除按鈕上新增click事件
第二步:查看接口文檔
第三步:調用接口文檔
引入MessageBox彈框(element-ui提供了方法)
效果:
新增添加商品單獨頁面
第一步:在添加商品新增一個click事件
第二步:在methods寫一個路由跳轉的方法
第三步:新增一個Add.vue
第四步:編寫Add.vue骨架
第五步:在index.js注冊該路由
效果:
新增添加商品
第一步:引入面包屑
第二步:引入卡片
第三步:引入Alert警告(element ui給出了方案)
第三步:引入Steps步驟條(elementui給出了方案)
效果:
新增tabs欄渲染
第一步:引入Tabs標簽頁(element ui給了方案)
效果:
新增步驟條與tab欄數據聯動效果
第一步:新增name索引值、v-model數據綁定
第二步:長得像數字的字符串
第三步:
效果:
新增商品基本信息繪制
第一步:引入Form表單、表格校驗
第二步:加入校驗規則
效果:
商品分類的數據獲取
第一步:查看接口文檔
第二步:創建聲明周期函數
第三步:調用接口函數
效果:
新增商品列表級聯選擇器
第一步:引入級聯選擇器
第二步:在addForm新增一個goods_cat接收數據和校驗
第三步:級聯選擇器數據
效果:
控制Tabs標簽切換
第一步:使用element ui 提供函數
第二步:判斷是不是選中第一個tabs標簽或是否選擇了3級選擇
效果:
商品參數面板對應數據獲取
第一步:新增tab被選中時觸發(element ui給出了方案)
第二步:查看接口文檔
第三步:判斷激活面板是否等於1、接口調用
第四步:請求成功后保存到manyTableData
效果:
新增商品參數面板繪制
第一步:在tab被選中時觸發
第二步:引入復選框(element ui給出了方案)
第三步:進行組件注冊
效果:
fix復選框樣式優化
第一步:
效果:
商品屬性面板對應數據獲取
第一步:
第二步:將獲取到的數據保存到onlyTableData
效果:
新增商品屬性面板繪制
第一步:進行表單循環(和商品參數一致)
效果:
新增圖片上傳功能
第一步:引入Upload上傳組件(element ui 給出了方案)
第二步:將Url寫在data中,注意這個url是baseURL的根路徑
第三步:寫方法
第四步:組件注冊
效果:
fix上傳圖片不成功
第一步:點擊上傳圖片后在網絡請求中可以看到是無效token,就證明發起這個請求並沒有攜帶
第二步:Upload上傳給了一個設置上傳請求頭部的事件
第三步:在el-upload中添加這個事件
第四步:在data中寫入請求頭
效果:
新增圖片上傳成功之后操作
第一步:Upload圖片上傳給出了文件上傳成功時的鈎子(element ui給出了方案)
第二步:將圖片信息對象push到pisc中,先創建一個接收對象
第三步:寫方法
效果:
新增圖片移除操作
第一步:Upload圖片上傳給出了文件移除時的鈎子(element ui給出了方案)
第二步:處理移動圖片的操作
效果:
新增圖片預覽功能
第一步:Upload圖片上傳給出了文件上傳時的鈎子(element ui給出了方案)
第二步:引入Dialog對話框
第三步:獲取圖片預覽地址
第四步:控制dialog對話框的顯示與隱藏
當點擊圖片名稱就觸發
第五步:修改樣式
效果:
新增富文本框
第一步:安裝vue-quil-editor
第二步:man.js進行全局引用富文本編輯器
第三步:在Add.vue引入富文本
第四步:在addForm創建一個goods_introduce接收富文本內容
第五步:修飾樣式
效果:
新增添加商品預驗證
第一步:新增添加商品按鈕、click事件
第二步:寫click事件方法
知識點:validate是校驗表單項prop值,校驗是否通過
效果:
添加商品前數據轉換
第一步:
第二步:引入深拷貝依賴庫
第三步:在代碼中導入深拷貝庫官方地址
為什么需要進行深拷貝呢?因為在此之前級聯選擇器希望是數組,而另外個希望是字符串產生了分歧,所以同時滿足就采用深拷貝。
效果:
添加商品時數據轉換
第一步:
第二步:新增attrs數組
第三步:
效果:
完善添加商品
第一步:查看接文檔
第二步:接口請求
效果:
新增訂單管理分支
新增訂單管理骨架
第一步:需要重新創建一個分支取名為:order
第二步:在order目錄創建Order.vue
第三步:寫基礎骨架
<template>
<div>
訂單管理
</div>
</template>
<script>
export default {
// 初始化基礎數據節點
data(){
return {}
},
// 聲明周期函數
created() {},
// 事件處理函數
methods: {}
}
</script>
<style lang="less" scoped="">
</style>
第四步:在路由引入
效果:
增加面包屑/卡片/輸入框基礎頁面
第一步:引入面包屑
第二步:引入卡片
第三步:引入input搜索框
效果:
商品訂單數據獲取
第一步:查看接口文檔
第二步:增加查詢信息
第三步:接口請求
效果:
商品訂單數據渲染
第一步:引入el-tab表格
第二步:
效果:
新增分頁功能
第一步:引入Pagination分頁
第二步:寫對應方法
效果:
新增省市區/縣聯動效果
第一步:給編輯按鈕新增clikc事件
第二步:引入Dialog對話框
第三步:控制默認對話框為隱藏
第四步:點擊編輯按鈕控制對話框顯示
第五步:引入表單校驗
第六步:表單校驗規則
第七步:引入城市列表(citydata.js)
第八步:引入級聯選擇器,並將城市數據綁定到opthions
第九步:新增dialog對話框close事件
第十步:關閉對話框后觸發清空表單事件
效果:
新增物流進度的對話框/物流進度數據獲取
第一步:在定位圖標新增click 事件
第二步:引入Dialog對話框
第三步:設置對話框為隱藏狀態
第四步:查看接口文檔
第五步:接口請求
效果:
新增時間線
第一步:引入時間線(element ui)給出了方案
第二步:注冊組建
效果:
合並分支到master
Report報告
新增報表骨架
第一步:需要重新創建一個分支取名為:report
第二步:在report目錄創建Report.vue
第三步:寫基礎骨架
<template>
<div>
報表組件
</div>
</template>
<script>
export default {
data() {},
created() {},
methods: {}
}
</script>
<style lang="less" scoped="">
</style>
第四步:在路由引入
效果:
添加面包屑/卡片
第一步:引入面包屑
第二步:引入卡片
效果:
引入Echars圖表
第一步:安裝Echars插件
第二步:在項目中引入Echarts
1.導入Echarts
2.創建一個Dom節點
3.創建一個mounted鈎子 該鈎子的作用是Dom創建完成之后才會執行,此時,頁面上的元素已經渲染完畢了
4.准備Echarts展示數據和配置項
5.在頁面上展示Echarts
效果:
數據報表渲染
第一步:查看接口文檔
第二步:請求接口
第三步:進行數據合並
效果:
優化項目
新增頂部加載進度條
第一步:下載nprogress插件
第二步:在main.js導入nprogress
第三步:在發起axios請求前調用Nprogress.start()
第四步:在發起axios請求后調用Nprogress.done()
效果:
安裝生產環境禁止console.*打印
第一步:在開發依賴下載對應插件
第二步:在build過程中,新增該插件
關於插件在生產環境禁止console.log()輸出
第一步:下載插件【babel-plugin-transform-remove-console】
第二步:在根目錄可以看到babel.config.js這個文件
第三步:進行判斷為什么環境,如果為生產環境,則使用這個插件,非正式環境則不使用這個插件
效果:現在在開發環境,所以可以正常打印console.log
項目生產打包報告
- 生成打包報告
// 通過 vue-cli 的命令選項可以生成打包報告
// --report 選項可以生成 report.html 以幫助分析包內容
vue-cli-service build --report
- 通過可視化的UI面板直接查看報告
在可視化UI面板中,通過控制台和分析面板,可以方便看到項目中所存在的問題
修改webpack默認配置
第一步:在根目錄創建vue.config.js這個配置文件
第二步:固定寫法
// vue.config.js
// 這個文件中,應該導出一個包含了自定義配置選項的對象
module.exports = {
// 選項...
}
chainWebpack 自定義打包入口
- 新增一個自己的打包入口文件
第一步:將原來main.js修改成dev和prod模式
第二步:定義打包入口
通過 externals 加載外部CDN資源
默認情況下,通過import語法導入第三方依賴包,最終會被打包合並到同一個文件中,從而導致打包成功后,單個文件體積過大的問題。
第一步:配置externals
第二步:刪除在main.js引入的資源,進行
第三步:在public文件夾下找到index.html
效果:編譯后體積明顯變小
通過CDN優化ElementUI的打包
- 在main-prod.js中,注釋掉element-ui按需加載的代碼
- 在index.html的頭部區域中,通過CDN加載element-ui的js和css樣式
效果:編譯后體積明顯變小
首頁內容定制
在public/index.html首頁中,可以根據isProd的值,來決定如何渲染頁面結構
第一步:在vue.config.js中增加一個自定義屬性
chainWebpack: config => {
// 發布模式默認打包入口
config.when(process.env.NODE_ENV === 'production', config => {
// html插件新增一個自定義屬性
config.plugin('html').tap(args =>{
args[0].isProd = true
return args
})
})
// 開發模式默認打包入口
config.when(process.env.NODE_ENV === 'production', config => {
config.plugin('html').tap(args =>{
args[0].isProd = false
return args
})
})
}
第二步:在index.html中進行判斷
效果:編譯后體積明顯變小
路由的懶加載
不同路由對應的組件分割成不同的代碼塊,然后當路由被訪問的時候才加載對應組件
- 安裝@babel/plugin-syntax-dynamic-import包
- 在babel.config.js配置文件中聲明該插件
- 將路由改為按需加載的形式
效果:
項目上線
導入阿里icon到自己項目
第一步:首先去網站進行注冊並選好需要的圖標下載到本地
第二步:將這個目錄放在src/assets里
第三步:去main.js進行引入
第四步:使用圖標
git使用大全
創建子分支
git checkout -b 分支名字
查看當前所有分支
git branch
將代碼添加到暫存區
git add .
查看上次提交之后是否有進行再次修改
git status
提交代碼
git commit -m "備注"
切換主分支
git checkout master
合並代碼
git merge 分支
推送到代碼管理倉庫(碼雲/github)
git push -u origin 倉庫名(-u 是沒有將分支推送到倉庫的操作)
git push
目錄結構
├─README
├─babel.config.js
├─package-lock.json
├─package.json
├─src
├─vue.config.js
└─電商管理后台 API 接口文檔