vue+element UI 學習總結筆記(一)

wh_xia_jun發表於2019-09-05

關鍵詞:

  • Webpack
  • vue-cli
  • Axios
  • vuex
  • router
  • login

技術選型:

由於公司現有專案多以後臺管理專案為主,且以後大多專案為針對原有專案的重構,因此,選擇一款成熟的後臺管理專案框架能夠極大的提高開發效率。這裡公司選用的是vue-element-admin,文件內容詳盡,可擴充性強,上手較快。

所以,對應的的前端主技術框架選用Vue,配套UI庫選用element-ui。所用到的一些技術棧和第三方庫類見下表展示:

技術

說明

版本

Vue-CLI-3

Vue腳手架工具

3.2.3

Vue

漸進式JavaScript 框架

2.5.17

Vue-router

官方的路由管理器

3.0.1

Vuex

全域性狀態管理模式

3.0.1

Axios

基於promise 的HTTP 庫

0.18.0

Element-UI

前端UI元件庫

2.8.2

echarts

百度開發的基於Javascript 的資料視覺化圖表庫。

4.2.1

Mockjs

介面寫好之前,模擬資料

1.0.1-beta3

Js-cookie

一款封裝好的cookie外掛

2.2.0

SCSS

CSS前處理器

 

eslint

語法規則和程式碼風格的檢查工具

4.19.1

Iconfont

國內功能很強大且圖示內容很豐富的向量圖示庫

 

 

Lodop(CLodop

第三方列印控制元件

 

 開發工具

系統

描述

VScode

主開發工具

Notepad++

臨時單檔案編輯[windows]

Svn

程式碼版本管理工具

Eclipse

處理報表

 

Webpack:

WebPack可以看做是模組打包機:它做的事情是,分析你的專案結構,找到JavaScript模組以及其它的一些瀏覽器不能直接執行的擴充語言(Scss,TypeScript等),並將其打包為合適的格式以供瀏覽器使用。

開發環境的啟動專案時,實際就是通過webpack打包後啟動的,只不過是打包的開發環境.

npm run dev的指令,實際執行額命令是npm run webpack-dev-server --inline --progress --config build/webpack.dev.conf.js

關於webpack相關具體內容見:vue+element UI 學習總結筆記(二十)--Webpack配置

開發環境、執行環境的區別?

vue腳手架的使用:

vue-cli:

全域性安裝vue-cli:

npm install vue-cli -g

初始化專案:

vue init <template-name> <project-name>

vue-cli參考文件:vue-cli詳解

ps:

package.json:

每個專案的根目錄下面,一般都有一個package.json檔案,定義了這個專案所需要的各種模組,以及專案的配置資訊(比如名稱、版本、許可證等後設資料)。npm install命令根據這個配置檔案,自動下載所需的模組,也就是配置專案所需的執行和開發環境。

我們專案是先github下來的一個基本框架?

ps:main.js  是主入口檔案,例項化vue

Axios:

Axios 是一個基於 promise 的 HTTP 庫,簡單的講就是可以傳送get、post請求。

我們專案中,request.js直接封裝的,感謝花褲衩。不過token還沒沒有弄明白。

每次請求中,我們都帶了token.

獲取token的方法在auth.js當中。

vuex

參考(抄襲):vuex的簡單使用

作用:

vuex解決了元件之間共享同一狀態的麻煩問題。當我們的應用遇到多個元件共享狀態時,會需要:

  1. 多個元件依賴於同一狀態。傳參的方法對於多層巢狀的元件將會非常繁瑣,並且對於兄弟元件間的狀態傳遞無能為力。這需要你去學習下,vue編碼中多個元件之間的通訊的做法。

  2. 來自不同元件的行為需要變更同一狀態。我們經常會採用父子元件直接引用或者通過事件來變更和同步狀態的多份拷貝。

以上的這些模式非常脆弱,通常會導致無法維護的程式碼。來自官網的一句話:Vuex 是一個專為 Vue.js 應用程式開發的狀態管理模式。它採用集中式儲存管理應用的所有元件的狀態。這裡的關鍵在集中式儲存管理。這意味著本來需要共享狀態的更新是需要元件之間通訊的,而現在有了vuex,就元件就都和store通訊了。問題就自然解決了。

這就是為什麼官網再次會提到Vuex構建大型應用的價值。如果您不打算開發大型單頁應用,使用 Vuex 可能是繁瑣冗餘的。確實是如此——如果您的應用夠簡單,您最好不要使用 Vuex

什麼可以用:

(需要牢記的一張圖) 

  • state (類似儲存全域性變數的資料)
    getters (提供用來獲取state資料的方法)
    actions (提供跟後臺介面打交道的方法,並呼叫mutations提供的方法)
    mutations (提供儲存設定state資料的方法)

我理解action中的方法,類似事件,只是在vuex中註冊,需要通過dispatch觸發這個方法

mutation中的方法,類似事件,只是在vuex中註冊,需要通過commit觸發這個方法

更詳細內容參見:vue+element UI 學習總結筆記(十七)_vuex在專案中的應用

使用步驟:

1. 搭建vue腳手架,安裝vuex依賴

2. 專案目錄src下新建store目錄和store.js檔案(檔名隨便取)

3、編寫index.js檔案

4、main.js引入這個檔案

登入:主要完成使用者驗證等

驗證規則:

驗證規則和elemnet -ui掛鉤:

我們是通過點選按鈕驗證的。

登入的時候,由於和後臺互動需要時間,所以按鈕上給個提示

當然 有個loading屬性相配合,具體可以查閱element-ui相關文件

登入頁面要保留使用者一些選擇專案,避免使用者每次都重新選擇:

我們是通過localstorage儲存的相關資訊。

 

至於登入的驗證,肯定得呼叫後臺介面,我們把呼叫放到vuex的action方法中。畢竟,登入資訊應該對全域性是可見的,具體實現方式就不展開了。

路由:

本段涉及:什麼是路由,路由的使用步驟 動態路由  路由懶載入

路由是根據不同的 url 地址展示不同的內容或頁面。

要使用router,必須先搞個路由地圖。

靜態路由:

1、定義元件

    const Foo = {
        template:'<div>foo</div>'
        };
    const Bar = {
        template:'<div>bar</div>'
    }   

2、定義路由地圖

const routes = [
        {
            path:'/foo',
            component:Foo,
        },{
            path:'/bar',
            component:Bar
        }
    ];

3、根據路由地圖建立路由例項:

const router = new VueRouter({
        routes:routes//可以簡寫 routes:routes
    })

4、路由例項注入到根例項:

    const app = new Vue({
        router
    }).$mount('#app')

5、 整個應用都具有路由功能,專案可以根據自己建立的路由,導航到到不同的頁面

<div id="app">
        <h1>hello app</h1>
        <p>
            <!-- 使用router-link元件來導航 -->
            <router-link to="/foo">Go to Foo</router-link>
            <router-link to="/bar">Go to Bar</router-link>
        </p>

        <!-- 
            路由出口路由匹配到的在這裡
         -->
         <router-view></router-view>
    </div>

總結一下:route 是一條路由,routes 是一組路由,router是一個機制,相當於管理者,他來管理路由

通過注入路由器,我們可以在任何元件內通過 this.$router 訪問路由器,也可以通過 this.$route 訪問當前路由.

官方文件通篇都常使用 router 例項。留意一下 this.$router 和 router 使用起來完全一樣。我們使用 this.$router 的原因是我們並不想在每個獨立需要封裝路由的元件中都匯入路由。

路由的程式設計式導航:

靜態方式下,使用router-link元件來導航,router-link根據“導航地圖”,“渲染”相應router-view。

程式設計式導航,就是用router.push(...)代替rout-link元件,事實上,router-link其實呼叫的就是router.push(...)方法。

巢狀路由

實際生活中的應用介面,通常由多層巢狀的元件組合而成。同樣地,URL 中各段動態路徑也按某種結構對應巢狀的各層元件.

從main.js中,可見,最外層是#app

import Vue from 'vue'
import App from './App'
......

new Vue({
  el: '#app',
  router,
  store,
  render: h => h(App)
})

app.vue如下:

<template>
  <div id="app">
    <!-- <div class="main-app">123</div> -->
    <router-view/>
  </div>
</template>
<script>
export default {
  name: 'App',
  data() {
    return {}
  }
}
</script>


從router中可見到,"/"即為Layout:

//路由
{
  path: '/',
  component: Layout,
  redirect: '/dashboard',
  name: 'Dashboard',
  hidden: true,
  children: [{
    path: 'dashboard',
    component: () => import('@/views/dashboard/index')
  }]
}

Layout.vue結構如下:

<template>
  <div :class="classObj" class="app-wrapper">
    <div v-if="disabled" class="shield" />
    <div v-if="device==='mobile'&&sidebar.opened" class="drawer-bg" @click="handleClickOutside" />
    <head-top/>
    <sidebar class="sidebar-container" />
    <div class="main-container">
      <navbar class="toggle-sidebar" />
      <app-main/>
    </div>
    <foot/>
  </div>
</template>

<script>
import { Navbar, Sidebar, AppMain } from './components'
import HeadTop from '@/components/headTop'
import Foot from '@/components/foot'
import ResizeMixin from './mixin/ResizeHandler'
import { mapState } from 'vuex'
import Bus from '@/utils/Bus'
import { getCodeLabelDictionary } from '@/api/CommonApi'
import { getNowDate } from '@/api/login'

export default {
  name: 'Layout',
  components: {
    Navbar,
    Sidebar,
    AppMain,
    HeadTop,
    Foot
  },
  mixins: [ResizeMixin],
  computed: {
    ...
  },
  watch: {
    ...
  },
  created() {
    ...
  },

  methods: {
    ...
  }
}
</script>
<style lang="scss">
    ...
</style>

Layout.vue當中,可以看出,有左側導航欄的區域了。

 

 

 

 

 

 

我們是動態路由和靜態路由混用的:

import Vue from 'vue'
import Router from 'vue-router'


Vue.use(Router)

/* Layout */
import Layout from '../views/layout/Layout'

//靜態路由部分
export const constantRouterMap = [{
  path: '/login',
  component: () => import(`@/views/login/index`),
  hidden: true
},
{
  path: '/404',
  component: () => import('@/views/404'),
  hidden: true
},
{
  path: '/',
  component: Layout,
  redirect: '/dashboard',
  name: 'Dashboard',
  hidden: true,
  children: [{
    path: 'dashboard',
    component: () => import('@/views/dashboard/index')
  }]
}
]

export default new Router({
  // mode: 'history', //後端支援可開
  scrollBehavior: () => ({
    y: 0
  }),
  routes: constantRouterMap
})

// 非同步掛載的路由
// 動態需要根據許可權載入的路由表
export const asyncRouterMap = [
]

// component: () => import('@/components/permision'),

 

 

 

 

 

參考1:vue-router八個重要知識點應用圖解

參考2:vue-router 基本使用

參考3:vue-router 快速入門

ps:巢狀路由與路由引數的比較,我前端同事給的解釋如下:

巢狀路由的表現形式在url上是這樣的 :   /path/pathtwo/paththree
路由引數在url上表現出是這樣的: /path/pathtwo/paththree/154/887,這種形式需要在路由的path配置的時候寫成 /path/pathtwo/paththree/:appid/:productid
或者以查詢字串形式帶問號的那種:/path/pathtwo/paththree?appid=154&productid=887

如果路由引數以非查詢字串形式表示,確實可能和巢狀路由表現出的地址一樣 。但是兩者在路由router中的path是完全不一樣的 。

如 /path/:paramsone/:paramstwo   ,結果paramsone的值為'pathtwo' ,paramstwo  的值為paththree' ,那麼最終的路由地址是
 /path/pathtwo/paththree,
而如果此時你正好也寫了一個子路由,path為  :/path/pathtwo/paththree

這兩個url看起來一樣 ,但是匹配的path和元件頁面是完全不一樣的 。前者匹配的是/path對應的頁面 ,後面的paramsone,paramstwo  只不過是路由裡面的引數 。
後者匹配的就是/path/pathtwo/paththree對應的頁面 ,且無路由引數 。

參考:vue-router+vuex實現載入動態路由和選單

1、路由 什麼時候 什麼地方從後端請求的

permission.js中有個守護路由router.beforeEach方法,是取得路由的核心程式碼。

ps:Promise vs  permission:

Promise:a declaration or assurance that one will do a particular thing or that a particular thing will happen.es6中,用這個詞表示是非同步函式。

permission:consent; authorization.。

 

改進點:

後端返回的是該使用者可訪問的全部選單 ,並不是全部頁面的選單。
已經與使用者繫結了,所以這裡的許可權過濾並沒有起效 。
而且,後端並沒有根據使用者不同配置不同的角色狀態,只是寫死了每個登陸的使用者都是admin,所以這裡的else裡永遠不會觸發,也就是這裡的許可權過濾還是沒有使用。

這種方式是不是值得商榷呢?

 

2、登入跳轉

驗證成功就直接跳轉首頁,跳轉的過程,就會觸發Navigation Guards,Navigation Guards中,除了驗證使用者是否登入外,如果是首次登入,還會從後端查詢使用者的功能選單,組裝成前端的router.


3、路由和左邊資料夾導航

如何和左邊導航欄關聯

 

 

導航選單

 

 

工具條

 

ps:vue生命週期參考文件:

Vue生命週期中mounted和created的區別

例如我們專案中,要給工具條繫結事件,我們一般在created中,寫相關程式碼。這時候,html還沒有渲染呢,盜一個生命週期的圖如下:

index.html、main.js、app.vue關係:ps:關於Vue中main.js,App.vue,index.html之間關係進行總結

在專案執行中,main.js作為專案的入口檔案,執行中,找到其例項需要掛載的位置,即index.html中,剛開始,index.html的掛載點處的內容會被顯示,但是隨後就被例項中的元件中的模板中的內容所取代,所以我們會看到有那麼一瞬間會顯示出index.html中正文的內容。

 

相關文章