# fox-navigation

导航组件，支持动画过渡

## Install

### NPM

```shell
npm i @fox-js/navigation -S
```

### YARN

```shell
yarn add @fox-js/navigation
```

### PNPM

```shell
pnpm add @fox-js/navigation
```

## 使用说明

### fox-root-navigator

root导航组件，在入口vue文件(App.vue)上使用，支持新增页面的动画效果和拖曳关闭页面。

#### 基础用法

```
<script setup lang="ts">
import { usePageHelper } from '@/utils/custom'
// 获取page helper
const pageHelper = usePageHelper()
// 定义remove page函数
const removePage = () => {
  pageHelper.remove()
}
</script>

<template>
  <fox-root-navigator :remove-page="removePage"></fox-root-navigator>
</template>

<style lang="scss">
</style>

```

#### Props

| 字段             | 说明                                   | 类型    | 默认值    |
|------------------|----------------------------------------|---------|-----------|
| drag-remove       | 是否支持拖曳关闭                               | Boolean  | true   |
| remove-page       | 关闭顶层页面方法                                 | Function   |       |
| router-view-name       | router view名称                | String  | `default`    |
| view-tag       | view tag标签                            | Function/String | `div`     |



## 插槽

| 名称     | 说明             | 
|---------|------------------|
| default | 内容       |



### fox-card-navigator

卡片导航组件，配合多标签页容器使用，具备缓存页面的能力。



#### 基础用法

```
<script setup lang="ts">
const rootName = $ref('_tab_view')
</script>

<template>
  <fox-card-navigator
        :router-view-name="rootName"
        :transition="true"
      ></fox-card-navigator>
</template>

<style lang="scss">
</style>

```

#### Props

| 字段             | 说明                                   | 类型    | 默认值    |
|------------------|----------------------------------------|---------|-----------|
| router-view-name       | router view名称                | String  | `default`    |
| transition       | 是否支持过渡动画                            | Boolean | false   |



## 插槽

| 名称     | 说明             | 
|---------|------------------|
| default | 内容       |


### fox-swiper-navigator

swiper导航组件，配合tab标签使用（例如手机端的主界面），支持拖曳新打开新页面/切换页面

#### 基础用法

```
<script lang="ts" setup>
import { onMounted, ref, computed } from 'vue'
import { usePageHelper } from '@/utils/custom'
import store from '@/store'
import tabs from './data'
const contentPadding = {
  left: 0,
  top: 0,
  right: 0,
  bottom: 0
}
// -------------- 导航设置 ---------------
// content width/height
const contentWidth = ref(0)
const contentHeight = ref(0)
// page ref
const pageRef = ref(null)
// root name
const rootName = ref('_tab_view')
// routes
const routes = computed(() => {
  return tabs.map(tab => {
    return {
      path: tab.route
    }
  })
})
// active route path
const activeRoutePath = computed({
  set: (newVal: string) => {
    // 更新tab bar的index
    index.value = routes.value.findIndex(r => {
      return r.path === newVal
    })
    store.setCurrentRoutePath(newVal, rootName.value)
  },
  get: (): string => {
    return store.getCurrentRoutePath(rootName.value) as string
  }
})
// open page
const openPage = (route: any, index: number) => {
  onTabChange(index)
}

// -------------tab bar 设置 ------------------
//当前tab索引
const index = ref(0)
// 获取page helper
const pageHelper = usePageHelper()
// tab change事件
const onTabChange = (index: any) => {
  const tab = tabs[index]
  // open页面
  pageHelper.open(tab.route)
  // 当前的route path到公共store中
  store.setCurrentRoutePath(tab.route, rootName.value)
}
// content应用
const contentRef = ref(null)
// 加载后处理
onMounted(() => {
  if (pageRef.value) {
    const anyPage: any = pageRef.value
    contentWidth.value = anyPage.getPageContentWidth()
    if (contentWidth.value === 0) {
      const anyContent: any = contentRef.value
      contentWidth.value = anyContent.$el.offsetWidth
    }
    contentHeight.value = anyPage.getPageContentHeight()
  }
  // 当前选中tab index
  let curIndex = index.value
  // 获取之前保存的route path
  let path = store.getCurrentRoutePath(rootName.value)
  if (path) {
    let i = tabs.findIndex(tab => {
      return tab.route === path
    })
    curIndex = i !== -1 ? i : curIndex
    //  更新tab的model
    index.value = curIndex
  }
  // 触发页面跳转
  onTabChange(curIndex)
})
</script>

<template>
  <fox-page :content-padding="contentPadding" ref="pageRef">
    <fox-footer>
      <fox-tabbar v-model="index" @change="onTabChange">
        <template v-for="tab in tabs" :key="tab.title">
          <fox-tabbar-item :title="tab.title" :icon="tab.icon"></fox-tabbar-item>
        </template>
      </fox-tabbar>
    </fox-footer>
    <fox-content ref="contentRef">
      <fox-swiper-navigator
        v-model:activePath="activeRoutePath"
        :router-view-name="rootName"
        :routes="routes"
        :open-page="openPage"
        :transition="true"
        :width="contentWidth"
        :height="contentHeight"
      ></fox-swiper-navigator>
    </fox-content>
  </fox-page>
</template>

<style lang="scss" scoped></style>

```

#### Props

| 字段             | 说明                                   | 类型    | 默认值    |
|------------------|----------------------------------------|---------|-----------|
| open-page  | 打开页面方法 | Function   |  |
| router-view-name  | router view名称  | String  | `default` |
| routes  | 路由列表 | Route[] |    |
| active-path  | 激活路径 | String |    |
| height  | 导航容器高度 | Number |    |
| width  | 导航容器宽度 | Number |    |
| drag  | 是否支持拖曳 | Boolean |    |
| swipe-duration  | 滑动页面动画时间 | Number ||
| scroll-time  | 切换页面动画时间 | Number | |



## 插槽

| 名称     | 说明             | 
|---------|------------------|
| default | 内容       |
