nuxt 過濾 query 引數

silenceCoder發表於2018-09-28

今天發現了一個線上問題,我們的APP跳轉內嵌H5時會預設query帶一些引數,比如city之類的,但是有時運營人員配置頁面連結地址時在不太瞭解的情況下,會手動加上city這些引數,恰巧你請求介面的時候需要這個引數,使用this.$route.query.city獲取,form提交就會成為下圖,會報400引數不規範,

nuxt 過濾 query 引數

這樣重複query傳引數顯然是不規範的,這樣使用this.$route.query.city獲取回來是一個陣列

解決該問題需要兩點:

  1. 根源上配置的時候不要重複配置
  2. 前端對URLquery傳參進行過濾

那麼過濾引數怎樣才能一勞永逸呢,避免每次取引數時判斷是不是陣列這中重複的程式碼。我們使用nuxt 這中服務端渲染的框架,開始想當然的想到在middleware中過濾,每次請求過來後執行middleware,過濾引數

先寫個filterQuery的測試middleware 測試覆蓋原來city,跑起來看看效果吧

nuxt 過濾 query 引數

控制檯列印結果沒啥問題

nuxt 過濾 query 引數

在頁面裡取一下試試,但結果不盡人意,this.$route.query.city 依然是陣列多個值

nuxt 過濾 query 引數
nuxt 過濾 query 引數

看到這裡,才發現自己太想當然了,nuxt是一套vue ssr的架構,服務端渲染的專案,**每當一個新路由過來時,都會建立一個新的vue 例項,包括router, store,**這樣是為了避免交叉請求狀態的汙染,頁面中vue生命週期裡this.$routevue例項上的;改動middlewareroute只在服務端比如asyncDatafetch時獲取生效

測試一下 頁面中asyncData獲取一下引數

nuxt 過濾 query 引數

果然這裡變了

nuxt 過濾 query 引數

那現在就是對routerquery做處理,其實vue-router為我們提供這樣的函式 parseQuery/stringQuery(提供自定義查詢字串的解析/反解析函式。覆蓋預設行為)

nuxt是對vue進行了封裝,路由生成都是自動通過掃頁面路徑自動生成的,那我們去nuxt的原始碼裡探個究竟,生成的核心是一個模板檔案,lib/app/router.js檔案,建立新router例項的工廠函式也在這個檔案裡

export function createRouter () {
  return new Router({
    mode: '<%= router.mode %>',
    base: '<%= router.base %>',
    linkActiveClass: '<%= router.linkActiveClass %>',
    linkExactActiveClass: '<%= router.linkExactActiveClass %>',
    scrollBehavior,
    routes: [
<%= _routes %>
    ],
    <% if (router.parseQuery) { %>parseQuery: <%= serialize(router.parseQuery).replace('parseQuery(', 'function(') %>,<% } %>
    <% if (router.stringifyQuery) { %>stringifyQuery: <%= serialize(router.stringifyQuery).replace('stringifyQuery(', 'function(') %>,<% } %>
    fallback: <%= router.fallback %>
  })
} 
複製程式碼

在這裡找到了需要的parseQuery 函式,這裡的router.parseQuery是在 lib/common/options.js中配置的

router: {
    mode: 'history',
    base: '/',
    routes: [],
    middleware: [],
    linkActiveClass: 'nuxt-link-active',
    linkExactActiveClass: 'nuxt-link-exact-active',
    extendRoutes: null,
    scrollBehavior: null,
    parseQuery: false,
    stringifyQuery: false,
    fallback: false
  },
複製程式碼

無論本地啟動還是nuxt build的時候這個options.js都會與根目錄下的nuxt.config.js配置項進行合併,所以也就一目瞭然了,加到nuxt.config.jsrouter下就好了,明確了就開幹試試吧

nuxt.config.js加了如下程式碼

parseQuery: function (querystring) {
      let d = function (str) {
        try {
          return str && window.decodeURIComponent(str)
        } catch (e) {
          return str
        }
      }
      if (d(querystring).includes('?')) querystring = d(querystring).replace(/\?/g, '&')
      querystring = querystring.split('&')
      let params = {}
      let pair
      
      // march and parse
      for (let i = querystring.length - 1; i >= 0; i--) {
        pair = querystring[i].split('=')
        params[d(pair[0])] = d(pair[1])
      }
      return params
    }
複製程式碼

不僅對重複的key過濾,也對url混入多個?做了合併過濾 結果就是 this.$router.query.city 進行了過濾,這裡預設取第一個值

nuxt 過濾 query 引數

~本文完,有任何表述不清或者表達錯誤的,請大家指正~

相關文章