亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

基于 Vue 的后臺(tái)管理系統(tǒng)前端實(shí)踐

scwang90 / 1005人閱讀

摘要:輸入框內(nèi)容過濾產(chǎn)品有一個(gè)需求是,在搜索用戶信息時(shí),只能通過郵箱搜索,并且只能輸入字母數(shù)字以及。我選擇了輸入框的值這里的坑就是需要在中更新值,因?yàn)樵剡@時(shí)才刷新。是否有一定要用的必要類似的管理系統(tǒng)涉及到不同頁(yè)面之間的交互都很少。

初始化項(xiàng)目

使用 Vue-cli3 初始化項(xiàng)目1

安裝 Element UI
安裝 Vue-i18n,做相關(guān)配置2,3

原則上需要對(duì) Element 也做 I18n 的處理,但是我覺得 Element 中已經(jīng)有很完善的多語(yǔ)言翻譯,而 Element 自身尚不支持 Vue-i18n 7+ 版本,要特殊處理,所以就算了,這里直接使用了 Element 自帶的方法。
項(xiàng)目結(jié)構(gòu)
.
|-- babel.config.js
|-- package.json
|-- public
|   `-- index.html
|-- src
|   |-- App.vue
|   |-- assets 
|   |   |-- override-element-ui.less      // 覆蓋 Element 默認(rèn)樣式
|   |   `-- image                         // 圖片文件目錄
|   |-- components  // 所有非 `` 中顯示的頁(yè)面的 Vue 組件
|   |   |-- mainMenu.vue    // 左側(cè)導(dǎo)航
|   |   |-- pureTitle.vue   // 通用的 Title 組件,項(xiàng)目中有多個(gè)頁(yè)面會(huì)用到
|   |   |-- search.vue      // 通用的 Search 頭部組件,同樣會(huì)用到
|   |   `-- userCenter.vue  // 字面意思用戶中心,目前只需要顯示用戶名,handle 用戶退出操作??深A(yù)見:下拉菜單操作、頭像顯示等...
|   |-- main.js     // Vue-cli 生成的項(xiàng)目基本文件
|   |-- router.js   // Vue-cli 生成,路由
|   |-- store   // Vuex相關(guān)
|   |   |-- index.js
|   |   |-- mutationTypes.js
|   |   `-- module  // 這里按照路由劃分了 module,不一定對(duì)
|   |   |   |-- someModule.js
|   |   |   `-- elseModule.js
|   |-- utils
|   |   |-- i18n  // 國(guó)際化支持
|   |   |   |-- index.js
|   |   |   `-- lang  // 語(yǔ)言字符串文件
|   |   |       |-- en.json
|   |   |       `-- zh.json
|   |   |-- request  // 處理所有 ajax 請(qǐng)求
|   |   |   |-- index.js    // 基于 axios,封裝了需要用到的方法,例如 token 的處理
|   |   |   |-- someComponentName.js  // 基于組件分割的請(qǐng)求,在 Vuex action 中調(diào)用獨(dú)立方法
|   |   |   `-- elseComponentName.js
|   |   |-- timeHelper.js  // 時(shí)間戳轉(zhuǎn)換幫助函數(shù)
|   |   `-- userHelper.js  // 保存用戶信息幫助函數(shù)
|   `-- views  // ` 下內(nèi)容顯示組件`
|       |-- Home.vue
|       |-- Login.vue
|       |-- MainPage.vue
|       |-- Manage.vue
|       `-- Verify.vue
|-- .env.development // 環(huán)境變量 process.env
|-- .env.production  // 生產(chǎn)環(huán)境下的環(huán)境變量
`-- vue.config.js    // 更改 Vue-cli 默認(rèn)配置
Element 按需加載

先看一張項(xiàng)目初始狀態(tài)下,全局引入 Element & 按需引入打包大小的對(duì)比:

How

參考:按需引入

需要注意的地方是:

不用新建 .babelrc 文件,只需要更改 babel.config.js

使用 Vue-cli 初始化項(xiàng)目后, presets 中為 ["@vue/app"],不需要更改為 element 官網(wǎng)中的 es2015 。原因是 babel 的目前版本已經(jīng)不推薦按照 JavaScript 版本來區(qū)分編譯目標(biāo)。(// todo:添加相關(guān)鏈接)

可用的 babel.config.js 文件如下:

module.exports = {
  presets: [
    ["@vue/app"],
  ],
  plugins: [
    [
      "component",
      {
        "libraryName": "element-ui",
        "styleLibraryName": "theme-chalk"
      }
    ]
  ]
}
覆蓋默認(rèn)樣式

正常情況下,可以通過直接修改對(duì)應(yīng) class 的內(nèi)容修改。但含有 foo__bar 類似格式的樣式不會(huì)應(yīng)用 scoped(因?yàn)椴皇峭粋€(gè) Vue 實(shí)例),因此修改不會(huì)生效。

可以通過在 *.vue 中不使用 scope 來解決這個(gè)問題,Element 在 Issue 中也吐槽過。雖然我不認(rèn)為 scope 不是一個(gè)好的解決方案。

因此,我選擇了在 main.js 中引入外部樣式表,例如override-element-ui.less,在外部樣式表中修改 foo__bar 類名的樣式。

路由設(shè)計(jì)

route.js 主要設(shè)計(jì)如下:

  routes: [
    {
      path: "/login",
      name: "login",
      component: Login
    },
    {
      path: "/",
      name: "home",
      component: Home,
      children: [
        {
          path: "/index",
          component: mainPage
        },
        {
          path: "/manage",
          component: manage,
          children: [
            {
              path: "user/:uumsid&:userid",
              component: userDetail
            },
            {
              path: "enterprise/:id",
              component: insDetail
            },
            {
              path: "/",
              component: manageList
            },
          ]
        },
        {
          path: "/verify",
          component: Verify,
        },
        {
          path: "/verify/:id",
          component: VerifyDetail
        },
        {
          path: "*",
          redirect: "/index"
        },
      ]
    },
  ]

555...不太想貼代碼,感覺太亂、太長(zhǎng)。

但不貼又說不清楚。

簡(jiǎn)單來說,項(xiàng)目只分為兩個(gè)部分。登陸頁(yè)和功能頁(yè)。

根路由綁定到了登陸后的首頁(yè)。

首頁(yè)包含頭部標(biāo)題、左側(cè)菜單還有顯示內(nèi)容的 。

因此,如果用戶僅輸入 location.host 訪問網(wǎng)站,會(huì)被帶到 ${host}/index 頁(yè)面。另外,訪問任意未被匹配的 path,都會(huì)重定向到 index 頁(yè)面。

這個(gè)時(shí)候會(huì)出現(xiàn)兩個(gè)分支:

判斷本地是否存在用戶信息是否存在 ? 進(jìn)行正常操作 :重定向到登錄頁(yè)

如何保存用戶信息和登陸狀態(tài)

整個(gè)系統(tǒng)只需要分成需要登錄和不需登陸兩個(gè)部分。

當(dāng)前所開發(fā)的系統(tǒng)除登錄頁(yè)外,都需要登錄后訪問。

這個(gè)部分和路由設(shè)計(jì)強(qiáng)相關(guān)。何時(shí)判斷用戶是否登錄在上一部分已經(jīng)解釋過。

使用 localstorage 來持久化保存用戶信息,處理用戶刷新頁(yè)面以及一段時(shí)間內(nèi)關(guān)閉瀏覽器后不用重新登錄的需求。(一段時(shí)間為30min)

Home.vue 的 created() 鉤子中做如下操作:

    created() {
      let userInfo = getUserFromLocal("userinfo")
      let verifiedUserInfo = (info) => {
        let now = new Date().getTime()
        const PASS_TIME = 1000 * 60 * 30 // 30min
        if (!info) return false
        if (now - info.time < PASS_TIME) return true
        return false
      }
      if (!!verifiedUserInfo(userInfo)) {
        this.onRefresh(userInfo)
      } else {
        this.$router.push({path: "/login"})
      }
    }

其中,getUserFromLocal 是在 userHelper.js 中寫的從 localstorage 中獲取數(shù)據(jù)的方法。通過判斷用戶信息是否存在以及是否過期來決定是跳轉(zhuǎn)到登錄頁(yè)還是直接使用當(dāng)前已有的用戶信息。

// 我不覺得這是一個(gè)很完美的方案,但根據(jù)我搜索的資料來看,確實(shí)沒有詳細(xì)說過這方面內(nèi)容的文章。所以,期待能看到更好的方案。

如何優(yōu)雅的觸發(fā)表單驗(yàn)證

Element 的表單驗(yàn)證方法

但沒有給出 async-validator 支持的表單驗(yàn)證觸發(fā)方式。

經(jīng)過查找,支持的觸發(fā)方式有: submit, blur, input

我選擇的方案是在規(guī)則中使用 submit 時(shí)驗(yàn)證(指表單提交時(shí)觸發(fā),因此實(shí)際情況中永遠(yuǎn)不會(huì)觸發(fā),但能滿足需求,即手動(dòng)觸發(fā)驗(yàn)證。)

同時(shí),在點(diǎn)擊登錄或者發(fā)送請(qǐng)求按鈕時(shí),調(diào)用 this.$refs.[formEl].validate((boolean) => { // callback})

清除表單驗(yàn)證結(jié)果: ...

當(dāng)表單項(xiàng)很多時(shí),也可以在

...中調(diào)用clearValidate(prop), prop 指表單項(xiàng)的 name 值。

輸入框內(nèi)容過濾

產(chǎn)品有一個(gè)需求是,在搜索用戶信息時(shí),只能通過郵箱搜索,并且只能輸入字母、數(shù)字以及@。因此,我們需要對(duì)用戶輸入數(shù)據(jù)時(shí)即時(shí)進(jìn)行過濾。(別問我為什么不在用戶輸入完成后提示錯(cuò)誤,這是需求。

我選擇了 watch 輸入框 value 的值:

value(val) {
  this.$nextTick(() => {
    this.value = this.reg ? val.replace(this.reg, "") : val
  })
}

這里的坑就是需要在 $nextTick() 中更新 value 值,因?yàn)?DOM 元素這時(shí)才刷新。

這個(gè)需求有許多 blog 都給出過不同的解決方案,可以多看看選擇一下。

獲取數(shù)據(jù)時(shí)的細(xì)節(jié)問題 ajax 的封裝

基于 axios

./utils/request/index.js:

import axios from "axios"

// BASE_HOST 通過 .env.[development|production] 配置。注意:每個(gè)變量都要用 VUE_APP作為前綴,否則不能識(shí)別
const BASE_HOST = process.env.VUE_APP_API_BASE
const TIME_OUT = 1000 * 10

/**
 *
 * @param URL {string}
 * @param params {Object}
 */
export function POST(URL, params) {
  if (!URL.includes(BASE_HOST)) URL = BASE_HOST + URL
  return axios({
    method: "post",
    url: URL,
    data: params,
    timeout: TIME_OUT
  })
}

export function GET(URL, data) {
  // like POST
}

/**
 * @param URL {string}
 * @param token {string}
 * @param params {Object}
 */
export function GET_WITH_TOKEN(URL, token, params) {
  if (!URL.includes(BASE_HOST)) URL = BASE_HOST + URL
  return GET(URL, {
    params,
    headers: {
      token: token
    },
    timeout: TIME_OUT
  })
}

封裝了基本的 GET,POST等方法,沒想到什么特別的作用,也沒有想到不好的地方,留著為了以防萬(wàn)一。(事實(shí)上,也用上了。比如超時(shí)處理。但是,超時(shí)處理在下一層也能做。但這樣的話登陸就需要多帶帶設(shè)置超時(shí)了。)

GET_WITH_TOKEN(以及 POST_WITH_TOKEN 等) 用于需要登錄鑒權(quán)的接口

顯示 Loading 狀態(tài)

在等待api返回?cái)?shù)據(jù)時(shí)可以用loading告訴用戶頁(yè)面正在加載。Element 提供的 Loading組件

一般切換路由后,會(huì)在組件的 created() 方法中發(fā)送請(qǐng)求。這種情況下應(yīng)該在 nextTick()(或者mounted()中) 中調(diào)用 loading ,避免頁(yè)面切換時(shí)找不到 DOM,出現(xiàn)全屏 loading 或頁(yè)面閃爍。

尚不明確(梗

I18n 的方案不夠完善,現(xiàn)在做到了語(yǔ)言文件的熱切換,但是對(duì)業(yè)務(wù)來講似乎沒有什么必要。沒有做語(yǔ)言字符串的按需加載(事實(shí)上是做了但沒有實(shí)現(xiàn)),但這個(gè)似乎比熱切更重要一點(diǎn)。

按照 Vue-router 實(shí)現(xiàn)了懶加載及文件命名,但瀏覽器似乎仍然會(huì)下載所有 JS 文件,在 JS Tab 中可以看到只下載了當(dāng)前頁(yè)用到的文件。

Vuex 是否有一定要用的必要?類似的管理系統(tǒng)涉及到不同頁(yè)面之間的交互都很少。在該系統(tǒng)中完全沒有,雖然有不同組件的交互,但都能較簡(jiǎn)單的把狀態(tài)提升到其父組件。因此,Vuex 唯一必須要用的理由就是保存用戶狀態(tài)。因?yàn)榈顷懞蟮慕涌诙夹枰?token 校驗(yàn),保存在 Vuex 中可以非常方便的使用。

參考資料

Vue CLI 3

Vue I18n

如何讓一個(gè)vue項(xiàng)目支持多語(yǔ)言(vue-i18n)

同步在博客:https://blog.life1st.me/artic...

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/98131.html

相關(guān)文章

  • 一些基于React、Vue、Node.js、MongoDB技術(shù)棧實(shí)踐項(xiàng)目

    摘要:利用中間件實(shí)現(xiàn)異步請(qǐng)求,實(shí)現(xiàn)兩個(gè)用戶角色實(shí)時(shí)通信。目前還未深入了解的一些概念。往后會(huì)寫更多的前后臺(tái)聯(lián)通的項(xiàng)目。刪除分組會(huì)連同組內(nèi)的所有圖片一起刪除。算是對(duì)自己上次用寫后臺(tái)的一個(gè)強(qiáng)化,項(xiàng)目文章在這里。后來一直沒動(dòng),前些日子才把后續(xù)的完善。 歡迎訪問我的個(gè)人網(wǎng)站:http://www.neroht.com/? 剛學(xué)vue和react時(shí),利用業(yè)余時(shí)間寫的關(guān)于這兩個(gè)框架的訓(xùn)練,都相對(duì)簡(jiǎn)單,有的...

    tangr206 評(píng)論0 收藏0
  • vue for contacts項(xiàng)目總結(jié)

    摘要:用來主要前臺(tái)的請(qǐng)求,并處理返回相關(guān)的數(shù)據(jù),做后臺(tái)服務(wù)。總結(jié)做完這個(gè)項(xiàng)目,其中的過程還是挺艱辛的,畢竟都是邊學(xué)邊做,不過最后能完成還是挺開心的,終于有了一個(gè)從到的項(xiàng)目過程。雖然只是一個(gè)小小的練手項(xiàng)目,不過對(duì)于目前的我,感覺還是不錯(cuò)的。 showImg(https://oc1gyfe6q.qnssl.com/17-3-30/43434844-file_1490879850754_14751...

    tulayang 評(píng)論0 收藏0
  • vue for contacts項(xiàng)目總結(jié)

    摘要:用來主要前臺(tái)的請(qǐng)求,并處理返回相關(guān)的數(shù)據(jù),做后臺(tái)服務(wù)??偨Y(jié)做完這個(gè)項(xiàng)目,其中的過程還是挺艱辛的,畢竟都是邊學(xué)邊做,不過最后能完成還是挺開心的,終于有了一個(gè)從到的項(xiàng)目過程。雖然只是一個(gè)小小的練手項(xiàng)目,不過對(duì)于目前的我,感覺還是不錯(cuò)的。 showImg(https://oc1gyfe6q.qnssl.com/17-3-30/43434844-file_1490879850754_14751...

    ralap 評(píng)論0 收藏0
  • vue for contacts項(xiàng)目總結(jié)

    摘要:用來主要前臺(tái)的請(qǐng)求,并處理返回相關(guān)的數(shù)據(jù),做后臺(tái)服務(wù)??偨Y(jié)做完這個(gè)項(xiàng)目,其中的過程還是挺艱辛的,畢竟都是邊學(xué)邊做,不過最后能完成還是挺開心的,終于有了一個(gè)從到的項(xiàng)目過程。雖然只是一個(gè)小小的練手項(xiàng)目,不過對(duì)于目前的我,感覺還是不錯(cuò)的。 showImg(https://oc1gyfe6q.qnssl.com/17-3-30/43434844-file_1490879850754_14751...

    ARGUS 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

scwang90

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<