學(xué)什么?
- 1 如何使用 Vue 開發(fā)一個(gè)項(xiàng)目
- 2 ElementUI 組件庫的使用
- 3 業(yè)務(wù)邏輯(登錄、權(quán)限、商品)
創(chuàng)建項(xiàng)目
- 通過 vue-cli 腳手架工具直接生成一個(gè)項(xiàng)目
- 1 創(chuàng)建:
vue init webpack shop-admin
- 2 配置(根據(jù)腳手架的引導(dǎo)來選擇配置項(xiàng))
- 3
cd shop-admin
- 4 啟動(dòng)項(xiàng)目:
npm run dev
或npm start
手動(dòng)配置路由
- 1 安裝:
npm i vue-router
- 2 在
src
目錄中,新建router
文件夾,在文件中新建index.js
路由的配置文件 - 3 在
index.js
中,配置路由,并導(dǎo)出路由實(shí)例 - 4 在
main.js
中導(dǎo)入 路由配置,并且與 Vue實(shí)例 關(guān)聯(lián)到一起 - 5 在
App.vue
中,添加路由出口
element-ui 組件庫的使用
- 1 安裝:
npm i element-ui
- 2 在 main.js 中,導(dǎo)入 element-ui、樣式,并安裝插件
- 3 直接在文檔中找到對應(yīng)的組件使用即可
項(xiàng)目接口本地搭建
- 0 解壓
shop-api.zip
文件 - 1 打開 phpStudy 啟動(dòng) MySql 服務(wù)
- 2 打開
navicat for mysql
工具,連接數(shù)據(jù)庫 - 3 在鏈接上,點(diǎn)右鍵新建數(shù)據(jù)庫,數(shù)據(jù)庫名稱為:
shop_admin
- 4 雙擊啟用數(shù)據(jù)庫,再右鍵
運(yùn)行SQL文件
,選中 shop_admin.sql,并導(dǎo)入 - 5 打開
shop-api
目錄,修改config/default.json
中的數(shù)據(jù)庫用戶名和密碼(如果需要) - 6 在
shop-api
目錄中,打開終端,輸入:npm start
啟動(dòng)接口服務(wù)
以后每天寫項(xiàng)目之前要做的事情
- 1 開啟 phpStudy 中的 MySql 服務(wù)
- 2 在
shop-api
目錄中,執(zhí)行npm start
啟動(dòng)接口服務(wù)
使用 git 管理項(xiàng)目
# 原始提交到遠(yuǎn)程倉庫的命令
git push https://gitee.com/zqran/shop_admin_31.git master
# 有了 remote 后:
git push shop master
# 使用 -u 命令后:
git push shop
# 將 倉庫地址 與 shop 這個(gè)名稱關(guān)聯(lián)到一起
git remote add shop https://gitee.com/zqran/shop_admin_31.git
# -u 就是將 master 設(shè)置為默認(rèn),提交的時(shí)候,就不需要每次都指定 master 分支了
# -u 命令只需要執(zhí)行一次即可
git push -u shop master
登錄功能
搭建登錄表單結(jié)構(gòu)
- 1 到 element-ui 文檔中找到 表單組件
- 2 找到合適的組件,點(diǎn)擊顯示代碼,將 文檔中提供的 示例代碼拷貝到我們自己的 Login.vue 組件中
- 目的:為了讓這個(gè)組件能夠在項(xiàng)目中先正常運(yùn)行起來
- 3 分析 組件結(jié)構(gòu)
- 先從整體分析這個(gè)結(jié)構(gòu)
- 4 修改這個(gè)結(jié)構(gòu),讓其變?yōu)檫m合我們功能的結(jié)構(gòu)
登錄邏輯
調(diào)整登錄組件的樣式
ref
- 作用:添加給 DOM元素或組件,將來可以通過
this.$refs.ref的值
來獲取到這個(gè)DOM對象或組件。然后,就可以進(jìn)行DOM操作或獲取組件數(shù)據(jù)、調(diào)用組件方法了
編程式導(dǎo)航 - JS代碼實(shí)現(xiàn)路由跳轉(zhuǎn)功能
-
this.$router.push('/home')
- 參數(shù) /home:表示要跳轉(zhuǎn)到的路由地址
-
this.$router.push({ name: 'home' })
- 通過 name 屬性來實(shí)現(xiàn)路由跳轉(zhuǎn)
element-ui 消息提示組件
// 這是 element-ui 中提供的一個(gè)方法,用來做消息提示:
this.$message({
// 提示信息
message: res.data.meta.msg,
// 消息提示的類型
type: 'error',
// 表示消息顯示時(shí)長
duration: 1000
})
登錄訪問控制
- 1 如果沒有登錄,只能訪問登錄頁面,而不能訪問其他
- 2 如果沒有登錄,訪問其他頁面,應(yīng)該跳回到登錄頁面
- 3 如果登錄了,就可以訪問其他頁面了
如何知道有沒有登錄
-
1 Vue項(xiàng)目使用
token
來作為登錄成功的標(biāo)識- 只要有 token 就說明已經(jīng)登錄了
- 如果沒有 token 就說明還沒有登錄
-
2 原來,通過 sessionid + cookie 機(jī)制,來實(shí)現(xiàn)登錄狀態(tài)保持
- 將 sessionid 存儲到 cookie 中,這樣,登錄狀態(tài)標(biāo)識(sessionid),就會隨著每一次請求都發(fā)送給服務(wù)器,服務(wù)器從 cookie 中獲取到sessionid,就知道是否登錄過了
-
這兩種不同機(jī)制都是為了解決同一個(gè)問題:
登錄狀態(tài)保持
- 為什么需要狀態(tài)保持? 因?yàn)?HTTP 協(xié)議是無狀態(tài)的
現(xiàn)在,登錄成功后,需要將 token 保存起來,存儲到 localStorage 中,其他地方用到了,就直接從 localStorage 中取出來使用就可以了
樣式調(diào)整
- 哪個(gè)組件的結(jié)構(gòu),就把樣式放在哪個(gè)組件的 style 標(biāo)簽中
菜單組件結(jié)構(gòu)分析
<!--
el-menu 菜單組件
default-active="2" 設(shè)置默認(rèn)菜單高亮,值是el-menu-item的index值
@open="handleOpen" 菜單展開事件
@close="handleClose" 菜單收起事件
background-color="#545c64" 菜單背景色
text-color="#fff" 菜單文字顏色
active-text-color="#ffd04b" 菜單高亮文字顏色
el-submenu 二級菜單,也就是一個(gè)可以展開收起的組件。
這個(gè)組件可以嵌套,形成多級菜單
index="1" 唯一標(biāo)志,可以用來設(shè)置菜單高亮
el-menu-item 可點(diǎn)擊的菜單項(xiàng)組件
disabled 表示禁用這個(gè)菜單
-->
<el-menu
default-active="4"
background-color="#545c64"
text-color="#fff"
active-text-color="#ffd04b"
>
<el-submenu index="1">
<template slot="title">
<!-- 指定了菜單的圖標(biāo) -->
<i class="el-icon-location"></i>
<!-- 指定了菜單名稱 -->
<span>導(dǎo)航一</span>
</template>
<!-- 分組菜單: -->
<el-menu-item-group>
<template slot="title">分組一</template>
<el-menu-item index="1-1">選項(xiàng)1</el-menu-item>
<el-menu-item index="1-2">選項(xiàng)2</el-menu-item>
</el-menu-item-group>
<el-menu-item-group title="分組2">
<el-menu-item index="1-3">選項(xiàng)3</el-menu-item>
</el-menu-item-group>
<el-submenu index="1-4">
<template slot="title">選項(xiàng)4</template>
<el-menu-item index="1-4-1">選項(xiàng)1</el-menu-item>
</el-submenu>
</el-submenu>
<el-menu-item index="2">
<i class="el-icon-menu"></i>
<span slot="title">導(dǎo)航二</span>
</el-menu-item>
<el-menu-item index="3" disabled>
<i class="el-icon-document"></i>
<span slot="title">導(dǎo)航三</span>
</el-menu-item>
<el-menu-item index="4">
<i class="el-icon-setting"></i>
<span slot="title">導(dǎo)航四</span>
</el-menu-item>
</el-menu>
props類型的說明
-
:router="true"
此時(shí),router 的值是 布爾值 類型的- 設(shè)置為字符串類型:
:router=" 'true' "
- 設(shè)置為數(shù)值類型:
:router="123"
- 設(shè)置為字符串類型:
-
router="true"
此時(shí),router的值是 字符串 類型的
嵌套路由使用步驟
- 1 在創(chuàng)建路由規(guī)則的時(shí)候,要配置子路由規(guī)則,而不是普通的路由
- 子路由是通過路由中的 children 屬性來配置的
- 2 在需要切換內(nèi)容的組件中,添加一個(gè)子路由的出口
<router-view />
接口使用說明
- 注意:除了登錄接口意外,其他所有的接口都需要將 token 傳遞給服務(wù)器,這樣,服務(wù)器才知道用戶有沒有登錄
- 如何傳遞 token ?
- 在 header 中添加 Authorization 請求頭
用戶列表功能
獲取用戶列表數(shù)據(jù)
- 1 在
data
配置中,添加數(shù)據(jù)userList: []
- 2 在
created
鉤子函數(shù)中,發(fā)送請求,獲取用戶列表數(shù)據(jù)- 根據(jù)接口文檔,找到接口和需要的參數(shù)
- 3 將接口返回的數(shù)據(jù)交給
userList
- 4 修改
el-table
表格組件中的 prop 屬性,使其與接口返回的數(shù)據(jù)匹配
分頁獲取數(shù)據(jù)
- 0 封裝 分頁獲取數(shù)據(jù) 方法
- 1 給組件綁定
@current-change
事件 - 2 通過事件參數(shù)獲取到當(dāng)前頁碼
- 3 在事件中,調(diào)用封裝好的方法,獲取當(dāng)前頁數(shù)據(jù)
退出功能
- 1 給 退出 按鈕綁定單擊事件
- 2 在事件中調(diào)用 element-ui 的彈框組件,彈出一個(gè)確認(rèn)對話框
- 3 在用戶點(diǎn)擊 確定 按鈕的時(shí)候,執(zhí)行 退出 功能
- 3.1 返回到登錄頁面
- 3.2 從 localStorage 中移除token
項(xiàng)目中的作用域插槽使用
- 如果想要獲取表格中的數(shù)據(jù),就通過 slot-scope 的值 scope.row 來獲取
<template slot-scope="scope">
<!--
scope.row 表示當(dāng)前行數(shù)據(jù)
mg_state 就是當(dāng)前用戶的狀態(tài)
-->
<el-switch v-model="scope.row.mg_state"></el-switch>
</template>
切換用戶狀態(tài)功能
- 1 給 開關(guān)組件 綁定
change
事件 - 2 在事件中獲取到當(dāng)前用戶的狀態(tài)
- 3 將狀態(tài)發(fā)送接口,來完成切換用戶狀態(tài)功能
優(yōu)化axios的使用
- 1 每次發(fā)送請求的時(shí)候,都要拷貝完整的基準(zhǔn)地址
- 期望:配置基準(zhǔn)地址,在發(fā)送請求的時(shí)候,只需要填寫當(dāng)前接口地址
// 配置基準(zhǔn)路徑:
axios.defaults.baseURL = 'http://localhost:8888/api/private/v1'
- 2 每次發(fā)送請求的時(shí)候,都需要設(shè)置一次請求頭
- 期望:配置請求頭,在發(fā)送請求的時(shí)候,就不需要每次都單獨(dú)設(shè)置請求頭
// 請求攔截器
// 說明:因?yàn)橹灰?axios 發(fā)送的請求,都會執(zhí)行 請求攔截器 中的代碼
// 所以,可以在 請求攔截器 中, 一次性添加請求頭
axios.interceptors.request.use(config => {
// 統(tǒng)一添加 Authorization 請求頭
config.headers.Authorization = localStorage.getItem('token')
// 一定要返回 config
return config
})
- 3 每個(gè)組件中都要單獨(dú)導(dǎo)入axios
- 期望:導(dǎo)入一次,而不是每個(gè)組件中都單獨(dú)導(dǎo)入
// main.js
import axios from 'axios'
Vue.prototype.$http = axios
用戶列表 - 查詢
- 1 從 element-ui 中找到搜索組件
- 2 給搜索按鈕綁定單擊事件
- 3 在事件中獲取到文本框中輸入的搜索內(nèi)容
- 4 根據(jù)搜索內(nèi)容,調(diào)用查詢接口,查詢數(shù)據(jù)
- 注意:新功能對老功能的影響,也就是說:添加了一個(gè)新的功能進(jìn)來,實(shí)現(xiàn)后,要自己測試一下有沒有對老的功能產(chǎn)生影響
用戶列表 - 刪除
- 1 給刪除按鈕綁定單擊事件,并且傳遞 id 參數(shù)
- 2 事件中彈出確認(rèn)對話框,防止用戶誤操作
- 3 當(dāng)用戶點(diǎn)擊確定的時(shí)候,根據(jù)id調(diào)用接口刪除用戶
- 4 刪除成功后,重新獲取用戶列表數(shù)據(jù)
用戶列表 - 添加用戶
- 1 給添加用戶按鈕,綁定單擊事件
- 2 在事件中,彈出一個(gè)對話框
- 3 進(jìn)行表單結(jié)構(gòu)、數(shù)據(jù)、驗(yàn)證的處理
- 4 給 確定 按鈕綁定單擊事件,來進(jìn)行表單驗(yàn)證,驗(yàn)證成功后,再添加用戶
- 5 添加成功后,關(guān)閉對話框,重新刷新列表數(shù)據(jù)
- 關(guān)閉對話框的時(shí)候,要重置表單(1 數(shù)據(jù) 2 校驗(yàn)狀態(tài))
- 給對話框綁定關(guān)閉事件
close
- 在事件中,重置表單
- 給對話框綁定關(guān)閉事件
表單驗(yàn)證的說明
- element-ui 中的表單驗(yàn)證規(guī)則,依賴于:async-validator
- 具體的驗(yàn)證規(guī)則,應(yīng)該從這個(gè)庫中查找
使用組件的注意點(diǎn)
- 1 首先想到的是 組件自身 有沒有提供對應(yīng)的功能
- 2 查看文檔,看有沒有對應(yīng)的功能
- 3 如果提供了,就直接使用提供的方式即可
- 4 如果沒有提供,就自己實(shí)現(xiàn)
用戶列表 - 編輯
- 1 給編輯按鈕綁定單擊事件
- 2 在單擊事件中,彈出對話框
- 3 獲取到當(dāng)前用戶數(shù)據(jù),并且展示在 編輯對話框 中
- 4 給 確定 按鈕,綁定單擊事件
- 5 獲取當(dāng)前用戶數(shù)據(jù),發(fā)送請求,修改數(shù)據(jù)
- 6 修改成功后,關(guān)閉對話框、提示用戶編輯用戶成功、刷新列表數(shù)據(jù)
抽離組件為三部分
- 注意:三個(gè)部分的文件名稱可以是任意的
<!-- 三個(gè)內(nèi)容中,都是通過 src 屬性,引用內(nèi)容的 -->
<template src="./template.html"></template>
<script src="./script.js"></script>
<style src="./style.css"></style>
<!-- 如果要使用 less 這樣配置: -->
<!-- 1 -->
<style src="./style.less" lang="less"></style>
<!-- 2 安裝: npm i -D less less-loader -->
VScode 生成SFC模板
// vue 文件中:
{
"vue SFC": {
"prefix": "vuetss",
"body": [
"<template src=\"./template.html\"></template>",
"<script src=\"./script.js\"></script>",
"<style lang=\"less\" src=\"./style.less\"></style>",
""
],
"description": "快速生成單文件組件分離后的結(jié)構(gòu)"
}
}
權(quán)限模塊 - 業(yè)務(wù)邏輯
權(quán)限模塊的組成: 權(quán)限、角色、用戶
-
權(quán)限和角色的關(guān)系:每個(gè)角色都有自己的權(quán)限,權(quán)限是屬于角色的
- 一個(gè)權(quán)限可以屬于多個(gè)角色,一個(gè)角色可以有多個(gè)權(quán)限
- 權(quán)限 和 角色的關(guān)系:多對多
-
角色和用戶的關(guān)系:每個(gè)用戶只能有一個(gè)角色,一個(gè)角色可以屬于多個(gè)用戶
- 角色 和 用戶:一對多
權(quán)限 和 用戶,間接的就有關(guān)系了,因?yàn)?權(quán)限和角色 是有關(guān)系的,角色和用戶也是由關(guān)系的,所以,權(quán)限 和 用戶,間接的就有了關(guān)系
-
問題:如何給用戶分配權(quán)限???
- 1 給用戶分配角色
- 2 給角色分配權(quán)限
- 3 這樣,只要用戶有某個(gè)角色,那么,他就擁有了這個(gè)角色下面的所有權(quán)限
-
比如:
- 用戶:
test5
,他的角色是:產(chǎn)品經(jīng)理
- 產(chǎn)品經(jīng)理這個(gè)角色擁有的權(quán)限:
商品管理
、訂單管理
、權(quán)限管理
- 用戶:
權(quán)限和菜單
- 權(quán)限和菜單也是關(guān)聯(lián)在一起的
- 也就是說:有什么權(quán)限,就有什么菜單
- 權(quán)限是有三級的,但是菜單只有兩級。因?yàn)?三級權(quán)限 就是具體的 CRUD 功能了
總結(jié)
- 權(quán)限模塊中的4個(gè)內(nèi)容: 菜單、權(quán)限、角色、用戶
- 一個(gè)用戶登錄系統(tǒng)后,這個(gè)用戶是由自己的角色的,角色又有自己的權(quán)限,權(quán)限又關(guān)聯(lián)到了具體的菜單
- 實(shí)現(xiàn)權(quán)限模塊功能的時(shí)候,要做的事情:
- 1 給角色分配權(quán)限
- 2 給用戶分配角色
角色列表
- 1 從文檔中找到表格組件
- 2 拷貝到項(xiàng)目中,先跑起來
- 3 修改 表格組件 ,改為我們要用的功能
分析用戶擁有的權(quán)限數(shù)據(jù)結(jié)構(gòu)
- tree 樹形結(jié)構(gòu),類似于 DOM 樹
children: [
// 權(quán)限名稱
roleName: '一級權(quán)限',
// 二級權(quán)限列表
children: [
{
roleName: '二級權(quán)限 1',
// 三級權(quán)限列表:
children: []
},
{
roleName: '二級權(quán)限 2',
// 三級權(quán)限列表:
children: []
}
]
]
給角色分配權(quán)限
- 1 先給 分配權(quán)限 按鈕綁定單擊事件
- 2 在事件中先彈出一個(gè)對話框
- 3 從 文檔 中找到 樹形組件 ,拷貝到項(xiàng)目中,先跑起來
- 4 分析結(jié)構(gòu)
- 5 進(jìn)入頁面時(shí),發(fā)送請求,獲取權(quán)限列表的樹形結(jié)構(gòu)數(shù)據(jù),并渲染到 tree 中
- 6 給 確定按鈕 綁定單擊事件
- 7 在事件中,獲取到選中所有節(jié)點(diǎn)id
- 8 發(fā)送請求,完成給角色授權(quán)
Vue組件樣式的問題說明
- 注意:組件中的樣式應(yīng)該只對當(dāng)前組件生效,而不是要對其他組件產(chǎn)生影響!!!
- 如果產(chǎn)生影響,會到組件之間的樣式?jīng)_突、覆蓋等問題
- Vue 中提供了一個(gè)屬性
scoped
,只要給 組件的style標(biāo)簽 添加這個(gè)屬性,那么,樣式就只會對當(dāng)前組件生效,而不會影響其他組件 - 所以,推薦在使用組件的時(shí)候,給 style 標(biāo)簽,添加 scoped 屬性!!!
- scoped 原理:動(dòng)態(tài)給組件中的標(biāo)簽添加一個(gè)
data-v-組件唯一標(biāo)識
屬性,并且樣式中自動(dòng)添加了屬性選擇器。因?yàn)槊總€(gè)組件的 唯一標(biāo)識 是不一樣的,所以,樣式就只會對當(dāng)前組件生效了
element-tree-grid
- 1 安裝:
npm i element-tree-grid
("element-tree-grid": "^0.1.3") - 2 在 main.js 中,注冊全局組件:
import ElTreeGrid from 'element-tree-grid'
Vue.component(ElTreeGrid.name, ElTreeGrid)
<!--
label :設(shè)置列名稱
prop :提供列內(nèi)容的屬性名
tree-key :區(qū)分其他菜單,不添加該key會導(dǎo)致所有菜單同時(shí)展開,添加該key只展開該菜單
level-key :設(shè)置菜單級別,以縮進(jìn)形式表示子菜單
parent-key :父級菜單id,不添加該key,則無法收起子菜單
child-key :指定使用哪個(gè)屬性名稱表示子菜單,默認(rèn)值為:children
-->
<el-table-tree-column
tree-key="cat_id"
level-key="cat_level"
child-key="children"
parent-key="cat_pid"
label="分類名稱"
prop="cat_name"
width="320"
:indent-size="20"
>
<template slot-scope="scope">
<span>{{ scope.row.cat_name }}</span>
</template>
</el-table-tree-column>
富文本編輯器
- vue-quill-editor
- 1 安裝:
npm i vue-quill-editor
- 2 在當(dāng)前組件中導(dǎo)入, 注冊為局部組件并使用
// 導(dǎo)入樣式文件:
import 'quill/dist/quill.core.css'
import 'quill/dist/quill.snow.css'
import 'quill/dist/quill.bubble.css'
import { quillEditor } from 'vue-quill-editor'
export default {
components: {
quillEditor
}
}
<quill-editor v-model="goodsAddForm.goods_introduce"></quill-editor>
動(dòng)態(tài)獲取菜單
- 菜單是動(dòng)態(tài)獲取的,不同的用戶有不同的角色,不同的角色有不同的權(quán)限,每個(gè)權(quán)限都對應(yīng)到了菜單
- 所以,不同的用戶能夠看到不同的菜單
- 問題:不管哪個(gè)用戶都是通過
/menus
這個(gè)接口來獲取菜單數(shù)據(jù)的,沒有傳id,但是,服務(wù)器返回的數(shù)據(jù)不一樣,服務(wù)器是如何區(qū)分不同用戶的?- 根據(jù) token ,token中是包含了用戶身份信息的
加載中效果
- 說明: element-ui 中提供了一個(gè) 自定義指令 v-loading 這個(gè)指令用來添加 loading 效果
- 使用: 想要哪個(gè)組件(那塊區(qū)域出現(xiàn))加載中效果,就給哪個(gè)組件添加自定義指令 v-loading 即可
<!--
loading 是一個(gè)布爾值數(shù)據(jù),如果為true表示展示加載中效果;如果為false,表示隱藏加載中效果
-->
<el-table v-loading="loading"></el-table>
添加分類
- 1 給添加分類按鈕綁定單擊事件,在事件中彈出對話框
- 2 從 elemenet-ui 組件庫中拷貝對話框組件到項(xiàng)目中,跑起來
- 3 分析 級聯(lián)選擇器 結(jié)構(gòu)
- 4 獲取 級聯(lián)選擇器 中的所有分類數(shù)據(jù)( created 鉤子函數(shù)中獲取 )
- 5 獲取 級聯(lián)選擇器 中選擇項(xiàng)的值(id)
- 6 給 確定 按鈕綁定單擊事件,在事件中獲取到接口需要的數(shù)據(jù)
- 7 發(fā)送請求,完成添加分類功能
商品列表
- 實(shí)現(xiàn) 路由版的分頁 功能
- 1 刷新頁面的時(shí)候,路由中顯示的是第幾頁,就要獲取到這一頁的數(shù)據(jù)
- 1.1 如何在刷新頁面的時(shí)候,從路由中獲取當(dāng)前頁(路由參數(shù))?
- 1.2 因?yàn)槭窃谒⑿马撁娴臅r(shí)候獲取,因此,需要在 created 鉤子函數(shù)中
- 1.3 通過 this.$route.params.page 獲取到當(dāng)前路由參數(shù)(頁碼)
- 2 切換分頁的時(shí)候,要改變路由中的路由參數(shù)(頁碼)
- 2.1 要改變哈希值就直接調(diào)用 this.
{curPage}`)
- 2.1 要改變哈希值就直接調(diào)用 this.
樣式 scoped 屬性的問題說明
- 注意:添加
scoped
屬性后,樣式只對組件內(nèi)部的結(jié)構(gòu)生效。對于動(dòng)態(tài)生成的結(jié)構(gòu)無效!!! - 結(jié)論:
- 1 推薦在使用style給組件添加樣式的時(shí)候,使用
scoped
屬性 - 2 如果發(fā)現(xiàn)在 scoped 添加的樣式無效,此時(shí),有可能就是動(dòng)態(tài)生成結(jié)構(gòu)的問題,此時(shí),就去掉 scoped 屬性,來看下樣式是否生效
- 3 如果生效了,就說明是動(dòng)態(tài)生成元素的問題,此時(shí),就創(chuàng)建一個(gè)新的 style 標(biāo)簽并且不添加scoped屬性,將動(dòng)態(tài)生成元素的樣式放在這個(gè)style標(biāo)簽中
- 4 如果不生效,則可能是 類名 錯(cuò)了等問題~
- 1 推薦在使用style給組件添加樣式的時(shí)候,使用
項(xiàng)目打包和優(yōu)化
- 打包命令:
npm run build
優(yōu)化:按需加載
- 說明:基于 webpack 的代碼分離 和 Vue異步組件
- 1 修改
router/index.js
中導(dǎo)入組件的語法
// 使用:
const Home = () => import('@/components/home/Home')
// 替換:
// import Home from '@/components/home/Home'
// 給打包生產(chǎn)的JS文件起名字
const Home = () =>
import(/* webpackChunkName: 'home' */ '@/components/home/Home')
// chunkName相同,將 goods 和 goods-add 兩個(gè)組件,打包到一起
const Goods = () => import(/* webpackChunkName: 'goods' */ '@/components/goods')
const GoodsAdd = () =>
import(/* webpackChunkName: 'goods' */ '@/components/goods-add')
- 2 (該步可省略)修改
/build/webpack.prod.conf.js
中的 chunkFilename
{
// [name] 代替 [id]
chunkFilename: utils.assetsPath('js/[name].[chunkhash].js')
}
優(yōu)化:使用CDN
項(xiàng)目中使用CDN
- 問題:打包后
vendor
(第三方資源文件) 體積過大 - 原因:項(xiàng)目中用到了很多的第三方包,這些包在打包的過程中,全部打包到了
vendor
這個(gè)一個(gè)JS文件中,導(dǎo)致體積過大 - 如何優(yōu)化
vendor
體積? 使用CDN - 原理:使用CDN處理第三方包,是引用的在線地址。此時(shí),這些包不會被打包到
vendor
文件中,因此,vendor
體積就會變的更小
CDN使用步驟
1 在
index.html
中引入 CDN 提供的 JS 文件2 在
/build/webpack.base.conf.js
中(resolve 前面)添加配置 externals注意:通過 CDN 引入 element-ui 的樣式文件后,就不需要在 main.js 中導(dǎo)入 element-ui 的 CSS 文件了。所以,直接注釋掉 main.js 中的導(dǎo)入 element-ui 樣式即可
externals
配置:
externals: {
// 鍵:表示 導(dǎo)入包語法 from 后面跟著的名稱
// 值:表示 script 引入JS文件時(shí),在全局環(huán)境中的變量名稱
// window.Vue / window.axios / window.VueRouter
vue: 'Vue',
axios: 'axios',
'vue-router': 'VueRouter',
// 注意:帶有樣式文件的第三方包,需要在 代碼中 將樣式注釋掉!!!
'element-ui': 'ELEMENT',
'element-tree-grid': 'ElTableTreeColumn',
'vue-quill-editor': 'VueQuillEditor'
BMap: 'BMap',
echarts: 'echarts',
}
常用包 CDN
-
說明:
- 1 先在官方文檔查找提供的 CDN
- 2 如果沒有,在
https://www.bootcdn.cn/
或其他 CDN 提供商 查找
Quill
<!-- Include the Quill library -->
<script src="https://cdn.bootcss.com/quill/1.3.4/quill.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue-quill-editor@3.0.4/dist/vue-quill-editor.js"></script>
<!-- Include stylesheet -->
<link rel="stylesheet"/>
<link rel="stylesheet"/>
<link rel="stylesheet"/>
緩存和保留組件狀態(tài)
- keep-alive
- 解決方式:使用
keep-alive
,步驟如下:
1 在需要被緩存組件的路由中添加 meta 屬性 meta
屬性用來給路由添加一些元信息(其實(shí),就是一些附加信息)
{
path: '/',
name: 'home',
component: Home,
// 需要被緩存
meta: { keepAlive: true }
}
2 修改路由出口,替換為以下形式: 根據(jù) meta 是否有 keepAlive
屬性,決定該路由是否被緩存
<keep-alive>
<!-- 這里是會被緩存的視圖組件 -->
<router-view v-if="$route.meta.keepAlive"> </router-view>
</keep-alive>
<!-- 這里是不被緩存的視圖組件 -->
<router-view v-if="!$route.meta.keepAlive"> </router-view>
啟用路由的 History 模式
- 通過在路由中添加
mode: 'history'
可以去掉 瀏覽器地址欄中的 # - 在開發(fā)期間,只需要添加這個(gè)配置即可
- 但是,在項(xiàng)目打包以后,就會出現(xiàn)問題
// 去掉 # 后,地址變?yōu)椋?http://localhost:8080/goods 那么,服務(wù)器需要正確處理
/goods 才能正確的響應(yīng)內(nèi)容, 但是,/goods 不是服務(wù)端的接口,而是
用來在瀏覽器中實(shí)現(xiàn) VueRouter 路由功能的
后端的處理方式
- 1 優(yōu)先處理靜態(tài)資源
- 2 對于非靜態(tài)資源的請求,全部統(tǒng)一處理返回 index.html
- 3 當(dāng)瀏覽器打開 index.html 就會加載 路由的 js 文件,那么路由就會解析 URL 中的 /login 這種去掉#的路徑了
反向代理
- webpack-dev-server proxy 參考文檔
- 修改
config/index.js
配置文件
proxyTable: {
// 使用:/api/movie/in_theaters
// 訪問 ‘/api/movie/in_theaters’ ==> 'https://api.douban.com/v2/movie/in_theaters'
'/api': {
// 代理的目標(biāo)服務(wù)器地址
target: 'https://api.douban.com/v2',
// https請求需要該設(shè)置
secure: false,
// 必須設(shè)置該項(xiàng)
changeOrigin: true,
// '/api/movie/in_theaters' 路徑重寫為:'/movie/in_theaters'
pathRewrite: {"^/api" : ""}
}
}