npm package: @ljweb/uniapp-router-next
Description: > 一个类似于vue-router的路由器，用于uniapp（vue3），支持h5和微信小程序和app，其他小程序请自测
Latest version: 1.2.9

# uniapp-router-next

> 一个类似于vue-router的路由器，用于uniapp（vue3），支持h5和微信小程序和app，其他小程序请自测

## 安装

```shell
$ npm install uniapp-router-next
$ npm install unplugin-uni-router -D
```

### 使用  

```typescript
// vite.config.ts
import { defineConfig } from 'vite'
import uni from '@dcloudio/vite-plugin-uni'
import uniRouter from 'unplugin-uni-router/vite'
// https://vitejs.dev/config/
export default defineConfig({
  plugins: [uni(), uniRouter()]
})

// router.ts
import routes from 'uni-router-routes' //由unplugin-uni-router/vite根据pages.json生成
import { createRouter } from 'uniapp-router-next'
const router = createRouter({
  routes: [
    ...routes,
    // 通配符，一般用于匹配不到路径跳转404页面
    {
      path: '*',
      redirect: () => {
        // 可返回{ name: '404' }，{ path: '/pages/404/404' }， '/pages/404/404'
        return { name: '404' }
      }
    }
  ],
  //@ts-ignore
  platform: process.env.UNI_PLATFORM,
  h5: {}
})
export default router

// main.ts
import { createSSRApp } from 'vue'
import router from './router'
import App from './App.vue'
export function createApp() {
  const app = createSSRApp(App)
  app.use(router)
  return {
    app
  }
}

```

### 全局组册组件
有以下两种组册方式，选择一种即可，推荐`easycom`这种方式
- 在`main.ts`或`main.js`中组册 
  ```js
  // main.ts
  import { createSSRApp } from 'vue'
  // 引入组件
  import RouterNavigate from 'uniapp-router-next/components/router-navigate/router-navigate.vue'
  import router from './router'
  import App from './App.vue'
  export function createApp() {
    const app = createSSRApp(App)
    // 组册组件
    app.component('router-navigate', RouterNavigate)
    app.use(router)
    return {
      app
    }
  }
  ```
- 基于`uniapp`的`easycom`，在`pages.json`中添加以下代码
  ```json
    {
       "easycom": {
          "custom": {
              "router-navigate": "uniapp-router-next/components/router-navigate/router-navigate.vue"
          }
      }
    }
  ```


### api跳转

```typescript
import { useRouter } from 'uniapp-router-next'

const router = useRouter()


router.navigateTo({
  path: '/pages/index/index',
  //参数
  query: {
    name: 'name'
  }
})
router.navigateTo...
router.reLaunch...
router.redirectTo...
router.switchTab..
router.navigateBack...
```

### 组件跳转
```html
<template>
 <router-navigate to="/pages/index/index">go</router-navigate>
</template>
```
#### 组件props
```js
// 跳转类型
navType = 'navigate' | 'redirect' | 'reLaunch' | 'switchTab' | 'navigateBack'

// navType = navigateBack时，可传回退页面层数
delta //默认值为1
```
### 路由信息
```typescript
import { useRoute } from 'uniapp-router-next'

const route = useRoute()
console.log(route)
//   fullPath: '/pages/index/index'
//   meta: {}
//   query: {}  上一个页面的参数
//   path: '/pages/index/home'
//   name: ''

```  


### 路由守卫  
用法与[vue-router](https://router.vuejs.org/zh/guide/)类似  
目前只有beforeEach和afterEach，beforeEach支持拦截，在页面跳转前出发，afterEach在页面的onShow生命周期触发  
beforeEach 在返回 false,抛出错误,返回 Promise.reject,调用 next(false)时会停止，返回其它或者调用 next()则执行下一个守卫，next({path: 'xxx'})后终止当前并执行跳转
```typescript
router.beforeEach(async (to, form, next) => {
  console.log(to, form, 'beforeEach')
})

router.afterEach((to, form) => {
  console.log(to, form, 'afterEach')
})

```

### 实验性功能

#### App.vue 模板替换（nvue不支持）

- 开启该功能 （unplugin-uni-router需更新到1.2.0版本以上）
  ```ts
  import { defineConfig } from 'vite'
  import uni from '@dcloudio/vite-plugin-uni'
  import uniRouter from 'unplugin-uni-router/vite'
  // https://vitejs.dev/config/
  export default defineConfig({
    plugins: [uni(),uniRouter({
      replaceAppToPages: true //开启模板替换功能
    })]
  })
  ```
- 在App.vue中写入公共模板
  ```html
  <template>
    <view>header</view>
    <outlet />
    <view>footer</view>
  </template>

  <script setup lang="ts">
  import { onLaunch, onShow, onHide } from "@dcloudio/uni-app";
  onLaunch(() => {
    console.log("App Launch");
  });
  onShow(() => {
    console.log("App Show");
  });
  onHide(() => {
    console.log("App Hide");

  });
  </script>
  <style></style>
  ```

- 最终会替换所有在pages.json中注册的页面
  ```html
  // page.vue
  <template>
    <view>page</view>
  </template>
  ```  
- 替换结果
  ```html
  // page.vue
  <template>
    <view>header</view>
    <view>page</view>
    <view>footer</view>
  </template>
  ```
- 取消某一页面的替换  
  在pages.json中添加skipReplace

  ```json
  {
    "pages": [
      {
        "path": "pages/index/index",
        "name": "index",
        "aliasPath": "/",
        "meta": {
          
        },
        "skipReplace": true
      }]
  }
  ```

#### 注意  
App.vue 模板替换会影响页面的布局，请谨慎使用，而且替换只能替换template中的静态内容，无法替换template中标签绑定的数据