ユニアプリのルーティングカプセル化

ユニアプリはジャンプページを達成するためのルーティング機能を提供しますが、以下に示すように、プロセスの使用では、我々は、いくつかの便利な場所を見つけました:


どのような問題は、ジャンプページを行います

  1. 悪い管理のページパス
    1. なぜ悪い管理:ページのパスが変更され、または下請け彼は変更に誰も見つからなかったとき
  2. パラメータを渡すのではない非常に友好的な方法
    1. なぜ無愛想:手動でパラメータリストをスプライスする必要性
  3. 単一のパラメータタイプのみサポート文字列
    1. かかわらず、文字列または数値を渡すと、取得したブールは文字列です
  4. 特殊文字が通過するときには、(例えば、2次元コードの情報を渡す)、その引数が切り捨てられるでしょう
    1. その理由は、(=?)そして、他の特殊文字が含まれていません
まず、いくつかの準備作業を行います

    プロジェクトの作成



最初に解決しやすい問題、一元管理されない、集中管理用のファイル(router.js)を作成し、ディレクトリ構造

コードは以下の通りです

export default {
  // 首页页面
  index: '/pages/index/index.vue',
  // 我的页面
  my: '/pages/my/index.vue'
}复制代码

このように使用するとなります

<template>
  <view class="content">
    <image class="logo" src="/static/logo.png"></image>
    <view>
      <text class="title">{{title}}</text>
    </view>
    <button @click="openPage">跳转到我的页面</button>
  </view>
</template>
<script>
  import url from '../../router'
  export default {
    data() {
      return {
        title: 'index'
      }
    },
    onLoad() {    },
    methods: {
      openPage () {
        uni.navigateTo({
          url: url.my
        })
      }
    }
  }
</script>复制代码

特に問題router.jsを導入する必要性を使用する場合は、問題を解決しません

のは、第2及び第3の質問を見てみましょう

例を見てください

本当に悪いトラブルに動作しているパラメータのように比較的多数の下では、パラメータは、一部を分離することはできませんし、それ以上のURLにスプライシングされましたか?

デジタル上でそのパスを見つけるために驚いが文字列になって、パラメータが忠実にできません

第4の問題点が実証されていません

騒ぎ、彼は(そんなに、私は問題がどこにあるか知っておくべきだと思う、ここではこれらの問題を解決することであると述べたプログレッシブ説明します

まず、ファイルを作成し、以下のように(MinRouter.js)ディレクトリ構造があります


第一の課題を解決するために以下のコード

router.jsファイルの導入の必要性を排除

import urlSet from './router';
function openPage (url) {  
    uni.navigateTo({
        url: `${urlSet[url]}`
    })
}
export default openPage复制代码

次の変更main.jsファイルを作成します

import Vue from 'vue'
import App from './App'
// 引入MinRouter文件
import openPage from './MinRouter'
Vue.config.productionTip = false
App.mpType = 'app'
// 添加到全局
global.openPage = openPage
const app = new Vue({
    ...App
})
app.$mount()复制代码

使用

<template>
  <view class="content">
      <image class="logo" src="/static/logo.png"></image>
      <view>
          <text class="title">{{title}}</text>
      </view>
      <button @click="toPage">跳转到我的页面</button>
</view>
</template>
<script> 
 export default {
    data() {      
        return {
            title: 'index'
        }
    },
    onLoad() {    },
    methods: {
      toPage () {
        global.openPage('my')
      }    
 }  
}
</script>复制代码

のは、第2及び第3の問題に対処してみましょう

3番目の質問は、多くの人々が直面している持っている必要があり、関係なく、大量の文字列になるものの結果、数を転送したいと考えていました。

データが文字列になって、だけでなく、元の型を復元できるようにする方法はあります後?

使用JSONは、上記の問題を解決するだけでなく、第二の問題に良い解決策ができ

元のコードを変更しよう

import urlSet from './router';
function openPage (url, query) {
  const queryStr = JSON.stringify(query)
  uni.navigateTo({
    url: `${urlSet[url]}?query=${queryStr}`
  })}
export default openPage复制代码

使用

<template>
  <view class="content">
    <image class="logo" src="/static/logo.png"></image>
    <view>
      <text class="title">{{title}}</text>
    </view>
    <button @click="toPage">跳转到我的页面</button>
  </view></template><script>  
export default {
    data() {
      return {
        title: 'index'
      }
    },
    onLoad() {    },
    methods: {
      toPage () {
        global.openPage('my', {id: 123})
      }
    }
  }
</script>复制代码

のは、第4の問題点を解決してみましょう

(=?)そして、上記URL内の他の特殊文字、そこに特別な意味があるので、我々は、エンコードのJSON文字列を見てする必要があります

import urlSet from './router';
function openPage (url, query) {
  const queryStr = encodeURIComponent(JSON.stringify(query))
  uni.navigateTo({
    url: `${urlSet[url]}?query=${queryStr}`
  })}
export default openPage复制代码

この問題を解決するが、気持ちは、それがVueのプラグインにパッケージ化することができない、非常に良いではないが、同様のVueRouterへ上記のすべて

答えはイエスです

パッケージ成形MinRouter

以下にrouter.jsファイル

import MinRouter from './MinRouter'
// 配置路由
const router = new MinRouter({
  routes: [
    {
      // 页面路径
      path: 'pages/index/index',
      name: 'index'
    },
    {
      path: 'pages/my/index',
      name: 'my'
    }
  ]
 })
export default router复制代码

main.jsは以下にファイル

import Vue from 'vue'
import App from './App'
// 引入MinRouter文件
import MinRouter from './MinRouter'
// 引入router文件
import minRouter from './router'
Vue.config.productionTip = false
// 注册插件
Vue.use(MinRouter)
App.mpType = 'app'
const app = new Vue({
    ...App,
    minRouter
})
app.$mount()复制代码

上記構成はVueRouterようなコードされています

MinRouterファイルで追加し、次のコードを

const toString = Object.prototype.toStringfunction
 isObject (value) {
  return toString.call(value) === '[object Object]'
}
function isString (value) {
  return toString.call(value) === '[object String]
'}
function isDefault (value) {
  return value === void 0
}
function install (Vue) {
  Vue.mixin({
    beforeCreate: function () {
      if (!isDefault(this.$options.minRouter)) {
        Vue._minRouter = this.$options.minRouter
      }    
}  
})  
Object.defineProperty(Vue.prototype, '$minRouter', {
    get: function () {
      return Vue._minRouter._router
    }
  })
}
function MinRouter (options) {
  if (!(this instanceof MinRouter)) {
    throw Error("MinRouter是一个构造函数,应该用`new`关键字调用")
  }
  isDefault(options) && (options = {})
  this.options = options
  this._router = options.routes || []
}
MinRouter.install = install
export default MinRouter复制代码

以下のパラメータのセットopenPage

名前:ジャンプするページを指定します。

クエリ:ジャンプParametersページもたらしました

调用方式:   openPage({name: 跳转的页面, query: {id: 123}})复制代码

openPage次の関数

function openPage (args) {
  let {name, query = {}} = args
  let queryStr = null, path
  queryStr = encodeURIComponent(JSON.stringify(query))
  this.$minRouter.forEach(item => {
    if (item.name === name) {
      path = item.path
    }
  })
  return new Promise((resolve, reject) => {
    uni.navigateTo({
      url: `/${path}?query=${queryStr}`,
      success: resolve,
      fail: reject
    })
  })
}复制代码

this.$minRouter已经在上面的代码代理过来了,不要觉得奇怪,其实就是配置路由中的routes复制代码

のみ上記のみ、この方法で使用することができますルーティングnavigateBack

これは確かに動作しない、あなたは、ルーティングを制御するためのパラメータを追加したい場合があります方法をジャンプしますが、openPage機能を追加することはできませんので、これは、見つけるのは非常に簡単ではありません、内部のルーティングに追加することはできませんか?

のは、ファイルrouter.jsを変更してみましょう

import MinRouter from './MinRouter'
// 配置路由
const router = new MinRouter({
  routes: [
    {
      // 页面路径
      path: 'pages/index/index',
      // type必须是以下的值['navigateTo', 'switchTab', 'reLaunch', 'redirectTo']
      // 跳转方式(默认跳转方式)
      type: 'navigateTo',
      name: 'index'
    },
    {
      path: 'pages/my/index',
      name: 'my'
    }
  ]
 })
export default router复制代码

openPage次の関数

function openPage (args) {
  let name, query = {}, queryStr = null, path, type
  switch (true) {
    case isObject(args):
      ({name, query = {}} = args)
      break
    case isString(args):
      name = args
      break
    default:
      throw new Error('参数必须是对象或者字符串')
  }
  if (isObject(query)) {
    queryStr = encodeURIComponent(JSON.stringify(query))
  } else {
    throw new Error('query数据必须是Object')
  }
  this.$minRouter.forEach(item => {
    if (item.name === name) {
      path = item.path
      type = item.type || 'navigateTo'
    }
  })
  if (!['navigateTo', 'switchTab', 'reLaunch', 'redirectTo'].includes(type)) {
    throw new Error(`name:${name}里面的type必须是以下的值['navigateTo', 'switchTab', 'reLaunch', 'redirectTo']`)
  }
  return new Promise((resolve, reject) => {
    uni[type]({
      url: `/${path}?query=${queryStr}`,
      success: resolve,
      fail: reject
    })
  })
}复制代码

ルーティングパラメータを解決する方法を言わなかったこと言って

以下の機能は、ルーティングパラメータが関連付けられています

function parseURL () {
  const query = this.$root.$mp.query.query
  if (query) {
    return JSON.parse(decodeURIComponent(query))
  } else {
    return {}
  }
}复制代码

以下はMinRouterのための完全なコードです

const toString = Object.prototype.toString
function isObject (value) {
  return toString.call(value) === '[object Object]'
}
function isString (value) {
  return toString.call(value) === '[object String]'
}
function isDefault (value) {
  return value === void 0
}
function openPage (args) {
  let name, query = {}, queryStr = null, path, type, isName = false
  switch (true) {
    case isObject(args):
      ({name, query = {}} = args)
      break
    case isString(args):
      name = args
      break
    default:
      throw new Error('参数必须是对象或者字符串')
  }
  if (isObject(query)) {
    queryStr = encodeURIComponent(JSON.stringify(query))
  } else {
    throw new Error('query数据必须是Object')
  }
  this.$minRouter.forEach(item => {
    if (item.name === name) {
      path = item.path
      type = item.type || 'navigateTo'
      isName = true
    }
  })
  if (!isName) {
    throw new Error(`没有${name}页面`)
  }
  if (!['navigateTo', 'switchTab', 'reLaunch', 'redirectTo'].includes(type)) {
    throw new Error(`name:${name}里面的type必须是以下的值['navigateTo', 'switchTab', 'reLaunch', 'redirectTo']`)
  }
  return new Promise((resolve, reject) => {
    uni[type]({
      url: `/${path}?query=${queryStr}`,
      success: resolve,
      fail: reject
    })
  })
}
function parseURL () {
  const query = this.$root.$mp.query.query
  if (query) {
    return JSON.parse(decodeURIComponent(query))
  } else {
    return {}
}}
function install (Vue) {
  Vue.mixin({
    beforeCreate: function () {
      if (!isDefault(this.$options.minRouter)) {
        Vue._minRouter = this.$options.minRouter
      }
    }
  })
  Object.defineProperty(Vue.prototype, '$minRouter', {
    get: function () {
      return Vue._minRouter._router
    }
  })
  Object.defineProperty(Vue.prototype, '$parseURL', {
    get: function () {
      return Vue._minRouter.parseURL
    }
  })
  Object.defineProperty(Vue.prototype, '$openPage', {
    get: function () {
      return Vue._minRouter.openPage
    }
  })}
function MinRouter (options) {
  if (!(this instanceof MinRouter)) {
    throw Error("MinRouter是一个构造函数,应该用`new`关键字调用")
  }
  isDefault(options) && (options = {})
  this.options = options
  this._router = options.routes || []
}
MinRouter.install = install
MinRouter.prototype.openPage = openPage
MinRouter.prototype.parseURL = parseURL
export default MinRouter复制代码

以下を使用

<template>
  <view class="content">
    <image class="logo" src="/static/logo.png"></image>
    <view>
      <text class="title">{{title}}</text>
    </view>
    <button @click="toPage">跳转到我的页面</button>
  </view>
</template>
<script>
  export default {
    data() {
      return {
        title: 'index'
      }
    },
    onLoad() {
      // 解析路由参数
      console.log(this.$parseURL())
    },
    methods: {
      toPage () {
        // 跳到my的页面  query是传递的参数
        this.$openPage({
          name: 'my',
          query: {id: 123}
        })
      }
    }
  }
</script>复制代码

<template>
  <view class="content">
    <image class="logo" src="/static/logo.png"></image>
    <view>
      <text class="title">{{title}}</text>
    </view>
    <button @click="toPage">跳转到首页页面</button>
  </view>
</template>
<script>
  export default {
    data() {
      return {
        title: 'my'
      }
    },
    onLoad() {
      // 解析路由参数
      console.log(this.$parseURL())
    },
    methods: {
      toPage () {
        // 跳到index的页面
        // 不传参数可以简写成如下
        this.$openPage('index')
      }
    }
  }
</script>复制代码

そして、あなたは同じRouterLinkを使用することはできません

<router-link to="{name: 'my'}"></router-link>
<router-link to="my"></router-link>
<router-link to={name: 'my', query: {id: 123}}></router-link>复制代码

かもしれないが、小さな機能コンポーネントをサポートしていない、すなわち一緒にカプセル化することができないMinRouter

実装ルータリンクを

<template>
  <div @click="openPage">
    <slot></slot>
  </div>
</template>
<script>
export default {
  props: {
    to: {
      type: [Object, String],
      required: true
    }
  },
  methods: {
    openPage () {
      this.$openPage(this.to)
    }
  }
}
</script>复制代码

main.jsファイルを追加します。

import mina from './components/min-a.vue'
Vue.component('min-a', mina)复制代码

使用

<template>
  <view class="content">
    <image class="logo" src="/static/logo.png"></image>
    <view>
      <text class="title">{{title}}</text>
    </view>
    <button @click="toPage">跳转到我的页面</button>
    <min-a to="my">跳转到我的页面min-a标签跳转</min-a>
    <min-a :to="{name: 'my', query: {id: 123}}">跳转到我的页面min-a标签跳转带参数</min-a>
  </view>
</template>复制代码

この目的を達成するために

再びトーク

これは、世界的なされている可能性がbeforeEachのフック関数が、無駄に感じることはありません

行うには、見てgithubの

ユニアプリベースのバッファ


ます。https://juejin.im/post/5d0314a5f265da1ba77ca05bで再現

おすすめ

転載: blog.csdn.net/weixin_33920401/article/details/93178906
おすすめ