Vue項(xiàng)目說明

學(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 devnpm 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"
  • 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
    • 在事件中,重置表單

表單驗(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.router.push(`/goods/{curPage}`)

樣式 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ò)了等問題~

項(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

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 這種去掉#的路徑了

反向代理

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" : ""}
  }
}

Vuex

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 目錄 UI組件 開發(fā)框架 實(shí)用庫 服務(wù)端 輔助工具 應(yīng)用實(shí)例 Demo示例 UI組件 element★13489 ...
    余生社會閱讀 20,072評論 7 233
  • Vue開源項(xiàng)目庫 Vue.js開源項(xiàng)目速查表:https://www.ctolib.com/cheatsheets...
    cctN閱讀 1,036評論 0 13
  • 打卡1:晚上在公交車上,一名微醉酒男士罵了司機(jī),司機(jī)憋著一肚子氣,我真想說點(diǎn)什么去安慰一下司機(jī),正好這之后不一會兒...
    吳寧歸一閱讀 241評論 0 0
  • 流血流淚不怕,但最起碼要流老板血老板淚。
    墨無文閱讀 284評論 0 0
  • 在現(xiàn)在這個(gè)社會中有太多的人對未來的道路感到迷茫,但是在通往未來的道路上一定是充滿荊棘的你只有不停的往前跑才會...
    NULRIY閱讀 582評論 0 1