vue3(十三)-基础入门之路由配置与重定向

一、一级路由与重定向

1、创建 App.vue

在父组件中导入子组件 Navbar

<template><div><navbar></navbar></div>
</template><style lang="scss"></style><script>
import navbar from '@/components/Navbar'export default {components: {navbar}
}
</script>

2、创建 Navbar.vue 组件

App.vue 导入了 Navbar 组件,所以需要创建该组件;使用 router-link 作为跳转标签;而 router-view 看作一个插槽,点击相应的跳转标签,就根据路径到 myrouter.js 找与跳转标签中的路径一致的 path,根据 myrouter.js 文件中路径与组件的映射关系,显示相应的组件

<template><div><router-link to="/film" active-class="mycolor">电影</router-link><router-link to="/video" active-class="mycolor">视频</router-link><router-link to="/center" active-class="mycolor">我的</router-link><router-view></router-view></div>
</template><!-- 设置点击后的文字颜色 -->
<style lang="scss" scoped>
.mycolor {color: red;
}
</style>

3、配置 main.js 文件

在这导入路由的的配置文件 myrouter.js,并显式使用 use(router) 来绑定路由

import { createApp } from 'vue'
import App from './App.vue'
import router from '@/myrouter'createApp(App).use(router).mount('#app')

4、配置路由

创建 myrouter.js 文件,配置路径与组件的映射关系

import { createRouter, createWebHistory } from 'vue-router'
import Film from './views/Film.vue'
import Center from '@/views/Center.vue'
import Video from '@/views/Video.vue'const routes = [{path: '/film',component: Film},{path: '/center/',component: Center},{path: '/video',component: Video},{// path: '/:catchAll(.*)*',将匹配所有内容并将其放在 `$route.params.pathMatch` 下path: '/:pathMatch(.*)*',// 将匹配以 `/user-` 开头的所有内容,并将其放在 `$route.params.afterUser` 下// { path: '/user-:afterUser(.*)', component: UserGeneric },//重定向,当没有匹配路径时重定向到 /filmredirect: '/film'}
]const myrouter = createRouter({history: createWebHistory(process.env.BASE_URL),routes
})export default myrouter

5、创建子组件

5.1、Film.vue

<template><div class="film"><h1>This is an film page</h1></div>
</template>

5.2、Video.vue

<template><div class="video"><h1>This is an video page</h1></div>
</template>

5.2、Center.vue

<template><div class="center"><h1>This is an center page</h1></div>
</template>

6、页面展示

当分别点击 电影 视频 我的 三个标签后,分别展示 Film.vue Video.vue Center.vue 3个组件内容

在这里插入图片描述

A:以下为通过监听浏览器 hashchange 事件(监听浏览器地址栏路径的切换)实现的简单路由


<script setup>
import { ref, computed } from 'vue'
import Film from './views/Film'
import Cneter from './views/Center'
import Video from './views/Video'const routes = {'/': Film,'/center': Cneter
}const currentPath = ref(window.location.hash)window.addEventListener('hashchange', () => {currentPath.value = window.location.hash
})const currentView = computed(() => {return routes[currentPath.value.slice(1) || '/'] || Video
})
</script><template><div><a href="#/">Film</a><a href="#/center">Center</a><a href="#/non-exist">Video</a><component :is="currentView" /></div>
</template>

B:main.js 文件

import { createApp } from 'vue'
import App from './App.vue'createApp(App).mount('#app')

二、二级路由与重定向

上述第一种一级路由写法中, App.vue 、Navbar.vue 、main.js 、Video.vue、Center.vue 不作修改

1、Film.vue

增加 轮播、正在热映、即将上映 三个组件

<template><div class="film"><filmCarousel></filmCarousel><router-link to="/film/nowPlaying" active-class="mycolor">正在热映</router-link><router-link to="/film/comingSoon" active-class="mycolor">即将上映</router-link><router-view></router-view></div>
</template><script>
import filmCarousel from '@/components/film/FilmCarousel.vue'
export default {components: {filmCarousel}
}
</script>
<style lang="scss" scoped>
.mycolor {color: blue;
}
</style>

新增

轮播组件:FilmCarousel.vue
正在热映:FilmNowPlaying.vue
即将上映:FilmCommingsoon.vue

2、myrouter.js

增加 /film 路径下的二级路由与重定向

import { createRouter, createWebHistory } from 'vue-router'
import Film from './views/Film.vue'
import Center from '@/views/Center.vue'
import Video from '@/views/Video.vue'
import FilmNowPlaying from '@/components/film/FilmNowPlaying.vue'
import FilmCommingsoon from '@/components/film/FilmCommingsoon.vue'const routes = [{path: '/film',component: Film,children: [{ path: 'nowPlaying', component: FilmNowPlaying },{ path: 'comingSoon', component: FilmCommingsoon },// 重定向:当 /film 路径下没有匹配的路径时重定向到 /film/nowPlaying{ path: '', redirect: '/film/nowPlaying' }]},{path: '/center/',component: Center},{path: '/video',component: Video},{// path: '/:catchAll(.*)',重定向,当没有匹配路径时重定向到 /filmpath: '/:pathMatch(.*)',redirect: '/film'}
]const myrouter = createRouter({history: createWebHistory(process.env.BASE_URL),routes
})export default myrouter

3、新增的三个子组件

A、FilmCarousel.vue

<!-- 电影-轮播 -->
<template><div class="swiper-container"><div class="swiper-wrapper"><div class="swiper-slide" v-for="(item,index) in dataList" :key="index">{{ item }}</div></div></div>
</template><script>
import Swiper from 'swiper'
import 'swiper/swiper-bundle.css'
export default {data() {return { dataList: [] }},mounted() {this.dataList = ['轮播1', '轮播2', '轮播4', '轮播4']},updated() {const mySwiper = new Swiper('.swiper-container', {loop: true,autoplay: { delay: 1000, disableOnInteraction: false },scrollbar: false,slidesPerView: 1,slidesPerGroup: 1})}
}
</script><style scoped>
.swiper-container {width: 100%; /* 根据需要进行调整 */overflow: hidden;
}
</style>

B、FilmNowPlaying.vue

<!-- 电影-正在热映 -->
<template><div><div v-for="(item,index) in dataList" :key="index">{{ item }} </div></div>
</template>
<script>
export default {data() {return { dataList: ['热映1', '热映2', '热映3', '热映4'] }}
}
</script>

C、FilmCommingsoon.vue

<!-- 电影-即将上映 -->
<template><div><div v-for="(item,index) in dataList" :key="index">{{ item }}</div></div>
</template>
<script>
export default {data() {return { dataList: ['即将上映1', '即将上映2', '即将上映3', '即将上映4'] }}
}
</script>

4、页面展示

在这里插入图片描述

三、动态路由

这里一共整理了 5 种传参方式,分别为

1、路径字符串/ 拼接参数
2、路径字符串?拼接参数
3、path + query
4、name + query
5、name + params

1、在 FilmNowPlaying.vue 中增加 查看详情 按钮

<!-- 电影-正在热映 -->
<template><div><div v-for="(item,index) in dataList" :key="index">{{ item }} <button @click="checkDetail(index)"> 查看详情</button></div></div>
</template>
<script>
export default {data() {return { dataList: ['热映1', '热映2', '热映3', '热映4'] }},methods: {checkDetail(index) {// 1、路径字符串/ 拼接参数// this.$router.push('/film/detail/' + index)// 2、路径字符串?拼接参数this.$router.push('/film/detail?index=' + index)// 3、path + query// this.$router.push({//   path: 'detail',//   query: {//     index: index//   }// })// 4、name + query// this.$router.push({//   name: 'detail',//   query: {//     index: index//   }// })// 5、name + params// this.$router.push({//   name: 'detail',//   params: {//     index: index//   }// })}}
}
</script>

2、新增 FilmDetail.vue 组件

<!-- 详情页面 -->
<template><div>详情页面</div>
</template><script>
import { useRouter } from 'vue-router'
export default {mounted() {// 1、路径字符串/ 拼接参数// console.log(this.$route.params.index)// 2、路径字符串?拼接参数console.log(this.$route.query.index)// 3、path + query// console.log(this.$route.query.index)// 4、name + query// console.log(this.$route.query.index)// 5、name + params// console.log(this.$route.params.index)}
}
</script>

3、myrouter.js

import { createRouter, createWebHistory } from 'vue-router'
import Film from './views/Film.vue'
import Center from '@/views/Center.vue'
import Video from '@/views/Video.vue'
import FilmNowPlaying from '@/components/film/FilmNowPlaying.vue'
import FilmCommingsoon from '@/components/film/FilmCommingsoon.vue'
import FilmDetail from '@/components/film/FilmDetail.vue'
const routes = [{path: '/film',component: Film,children: [{ path: 'nowPlaying', component: FilmNowPlaying },{ path: 'comingSoon', component: FilmCommingsoon },// 重定向:当 /film 路径下没有匹配的路径时重定向到 /film/nowPlaying{ path: '', redirect: '/film/nowPlaying' },// 1、路径字符串/ 拼接参数// { path: 'detail/:index', component: FilmDetail },// 2、路径字符串?拼接参数{ path: 'detail', component: FilmDetail }// 3、path + query// { path: 'detail', component: FilmDetail },// 4、name + query// { path: 'detail', name: 'detail', component: FilmDetail },// 5、name + params// { path: 'detail/:index', name: 'detail', component: FilmDetail },]},{path: '/center/',component: Center},{path: '/video',component: Video},{// path: '/:catchAll(.*)', 重定向,当没有匹配路径时重定向到 /filmpath: '/:pathMatch(.*)',redirect: '/film'}
]const myrouter = createRouter({history: createWebHistory(process.env.BASE_URL),routes
})export default myrouter

4、页面展示

在这里插入图片描述

四、路由语法介绍

1、动态路由匹配

1.1 、路径参数 用冒号 : 表示,当一个路由被匹配时,它的 params 的值将在每个组件中以 this.$route.params
的形式暴露出来。因此跨域通过 this. $route.params.index 获取参数

1.2、在同一个路由中设置有多个 路径参数,它们会映射到 $route.params 上的相应字段。例如:

匹配模式匹配路径$route.params
/users/:username/users/eduardo{ username: 'eduardo' }
/users/:username/posts/:postId/users/eduardo/posts/123{ username: 'eduardo', postId: '123' }

2、路由匹配语法

1、在参数中自定义正则

const routes = [// /:orderId -> 仅匹配数字{ path: '/:orderId(\\d+)' },// /:productName -> 匹配其他任何内容{ path: '/:productName' },
]

2、可重复的参数

2.1、匹配规则

const routes = [// /:chapters ->  匹配 /one, /one/two, /one/two/three, 等{ path: '/:chapters+' },// /:chapters -> 匹配 /, /one, /one/two, /one/two/three, 等{ path: '/:chapters*' },// 仅匹配数字// 匹配 /1, /1/2, 等{ path: '/:chapters(\\d+)+' },// 匹配 /, /1, /1/2, 等{ path: '/:chapters(\\d+)*' },
]

2.2、传参

// 给定 { path: '/:chapters*', name: 'chapters' },
router.resolve({ name: 'chapters', params: { chapters: [] } }).href
// 产生 /
router.resolve({ name: 'chapters', params: { chapters: ['a', 'b'] } }).href
// 产生 /a/b// 给定 { path: '/:chapters+', name: 'chapters' },
router.resolve({ name: 'chapters', params: { chapters: [] } }).href
// 抛出错误,因为 `chapters` 为空

3.可选参数

也可以通过使用 ? 修饰符(0 个或 1 个)将一个参数标记为可选:

const routes = [// 匹配 /users 和 /users/posva{ path: '/users/:userId?' },// 匹配 /users 和 /users/42{ path: '/users/:userId(\\d+)?' },
]

3、编程式导航

3.1、push()

当点击 时,内部会调用这个方法,所以点击 相当于调用 router.push(…) :

声明式编程式
<router-link :to="...">router.push(...)

该方法的参数可以是一个字符串路径,或者一个描述地址的对象。例如:

// 字符串路径
router.push('/users/eduardo')// 带有路径的对象
router.push({ path: '/users/eduardo' })// 命名的路由,并加上参数,让路由建立 url
router.push({ name: 'user', params: { username: 'eduardo' } })// 带查询参数,结果是 /register?plan=private
router.push({ path: '/register', query: { plan: 'private' } })// 带 hash,结果是 /about#team
router.push({ path: '/about', hash: '#team' })

注意:如果提供了 path,params 会被忽略,上述例子中的 query 并不属于这种情况;params 不能与 path 一起使用
当指定 params 时,可提供 string 或 number 参数(或者对于可重复的参数可提供一个数组)。任何其他类型(如对象、布尔等)都将被自动字符串化。对于可选参数,你可以提供一个空字符串(“”)或 null 来移除它。

3.2、替换当前位置

它的作用类似于 router.push,唯一不同的是,它在导航时不会向 history 添加新记录,正如它的名字所暗示的那样——它取代了当前的条目。

声明式编程式
<router-link :to="..." replace>router.replace(...)

也可以直接在传递给 router.push 的 to 参数中增加一个属性 replace: true :

router.push({ path: '/home', replace: true })
// 相当于
router.replace({ path: '/home' })

3.3、横跨历史

该方法采用一个整数作为参数,表示在历史堆栈中前进或后退多少步,类似于 window.history.go(n)。

// 向前移动一条记录,与 router.forward() 相同
router.go(1)// 返回一条记录,与 router.back() 相同
router.go(-1)// 前进 3 条记录
router.go(3)// 如果没有那么多记录,静默失败
router.go(-100)
router.go(100)

4、命名视图

有时候想同时 (同级) 展示多个视图,而不是嵌套展示;需要在 < router-view > 标签中 命名 name 属性; 如果 router-view 没有设置名字,那么默认为 default。

App.vue

<template><h1>Named Views</h1><ul><li><router-link to="/">First page</router-link></li><li><router-link to="/other">Second page</router-link></li></ul><!-- 没有name属性,默认default --><router-view class="view one"></router-view><!-- name="a",对应 router.js 中的components,匹配components中的key,从而具体组件 --><router-view class="view two" name="a"></router-view><router-view class="view three" name="b"></router-view>
</template><script>
export default {name: "App",
};
</script>

router.js

import { createRouter, createWebHistory } from 'vue-router'
import First from './views/First.vue'
import Second from './views/Second.vue'
import Third from './views/Third.vue'export const router = createRouter({history: createWebHistory(),routes: [{path: '/',components: {default: First,a: Second,b: Third,},},{path: '/other',components: {default: Third,a: Second,b: First,},},],
})

5、重定向和别名

5.1、重定向

  • 重定向也是通过 routes 配置来完成,下面例子是从 /home 重定向到 /:
const routes = [{ path: '/home', redirect: '/' }]
  • 重定向的目标也可以是一个命名的路由:
const routes = [{ path: '/home', redirect: { name: 'homepage' } }]
  • 甚至是一个方法,动态返回重定向目标:
const routes = [{// /search/screens -> /search?q=screenspath: '/search/:searchText',redirect: to => {// 方法接收目标路由作为参数// return 重定向的字符串路径/路径对象return { path: '/search', query: { q: to.params.searchText } }},},{path: '/search',// ...},
]
  • 也可以重定向到相对位置:
const routes = [{// 将总是把/users/123/posts重定向到/users/123/profile。path: '/users/:id/posts',redirect: to => {// 该函数接收目标路由作为参数// 相对位置不以`/`开头// 或 { path: 'profile'}return 'profile'},},
]

5.2、别名

/ 别名为 /home,意味着当用户访问 /home 时,URL 仍然是 /home,但会被匹配为用户正在访问 /

const routes = [{ path: '/', component: Homepage, alias: '/home' }]

通过别名,可以自由地将 UI 结构映射到一个任意的 URL,而不受配置的嵌套结构的限制。使别名以 / 开头,以使嵌套路径中的路径成为绝对路径。甚至可以将两者结合起来,用一个数组提供多个别名:

const routes = [{path: '/users',component: UsersLayout,children: [// 为这 3 个 URL 呈现 UserList// - /users// - /users/list// - /people//   别名:/people 将可以代表 /users //   别名:list 作为子节点的别名,最后结构为:/users/list{ path: '', component: UserList, alias: ['/people', 'list'] },],},
]

如果路由有参数,请确保在任何绝对别名中包含它们:

const routes = [{path: '/users/:id',component: UsersByIdLayout,children: [// 为这 3 个 URL 呈现 UserDetails// - /users/24// - /users/24/profile// - /24{ path: 'profile', component: UserDetails, alias: ['/:id', ''] },],},
]

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/592431.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

arm64 UAO/PAN 特性对用户空间边界读写的影响(copy_from/to_user)

文章目录 1 UAO/PAN 特性由来2 硬件PAN的支持3 UAO 的支持 1 UAO/PAN 特性由来 linux 内核空间与用户空间通过 copy_from/to_user 进行数据拷贝交换&#xff0c;而不是通过简单的 memcpy/strcpy 进行拷贝复制&#xff0c;原因是安全问题&#xff08;这里不详细展开&#xff09…

初始化数组方法大全

初始化数组方法大全 大家好&#xff0c;我是免费搭建查券返利机器人赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;今天&#xff0c;让我们一同深入研究在编程中常用的操作之一——数组的初始化。数组是许多编程语…

pytest --collectonly 收集测试案例

pytest --collectonly 是一条命令行指令&#xff0c;用于在运行 pytest 测试时仅收集测试项而不执行它们。它会显示出所有可用的测试项列表&#xff0c;包括测试模块、测试类和测试函数&#xff0c;但不会执行任何实际的测试代码。 这个命令对于查看项目中的测试结构和确保所有…

C++的基础语句

C前奏 1.变量的定义2.键入和输出3.运算符4.sizeof()函数5.判断6.goto语句7.总结 这个专题&#xff0c;我会用简单的语言介绍C的语法&#xff0c;并会适当的对比实现相同或相似功能的C与python代码写法上的不同。 1.变量的定义 对于python来说&#xff0c;我们可以跳过定义直接…

定岗定编设计:企业职能部门定岗定编设计项目成功案例

一、客户背景及现状分析 某大型车辆公司隶属于某央企集团&#xff0c;建于20世纪60年代&#xff0c;是中国高速、重载、专用铁路车辆生产经营的优势企业&#xff0c;轨道车辆制动机研发制造的主导企业&#xff0c;是隶属于国内最大的轨道交通设备制造上市企业的骨干二级公司。公…

AI绘图软件,科技之旅绘画

科技与艺术的碰撞总能产生令人惊叹的火花&#xff0c;现在小编要给大家介绍一款引领未来艺术潮流的AI绘图软件——首助编辑高手。这是一款将人工智能与创意绘画完美结合的软件&#xff0c;它将为你打开一扇全新的创意之门。 所需工具&#xff1a; 一个【首助编辑高手】软件 …

Qt第一个UI程序设计

在第一个Qt程序的基础上我对ui界面进行设计&#xff0c;点击设计按钮 然后 拖动Label按钮输入想要输入的语句。 运行结果如下图。

通过用户输入数字,并计算二次方程

通过用户输入数字&#xff0c;并计算二次方程 以下实例为通过用户输入数字&#xff0c;并计算二次方程&#xff1a; 实例(Python 3.0) # Filename : test.py # author by : www.dida100.com# 二次方程式 ax**2 bx c 0 # a、b、c 用户提供&#xff0c;为实数&#xff0c;a…

案例1—综合项目组网(2)

交换机连接服务器&#xff1a; 服务器虚拟化&#xff1a; 1. 为什么要用虚拟化技术 2. 虚拟化和NFV的区别 3. 将8台服务器虚拟化为一个资源池的大致步骤 4. 服务器规划情况&#xff1a;管理网和业务网 交换机连接服务器&#xff1a; 1&#xff09;将交换机和服务器相连&am…

算法巡练day03Leetcode203移除链表元素707设计链表206反转链表

今日学习的文章视频链接 https://www.bilibili.com/video/BV1nB4y1i7eL/?vd_source8272bd48fee17396a4a1746c256ab0ae https://programmercarl.com/0707.%E8%AE%BE%E8%AE%A1%E9%93%BE%E8%A1%A8.html#%E7%AE%97%E6%B3%95%E5%85%AC%E5%BC%80%E8%AF%BE 链表理论基础 见我的博…

计算机组成原理 主存和CPU连接与主存提速方案

文章目录 主存与CPU的连接译码器线选法译码片选法总结 位拓展字拓展字位同时拓展 主存提速方案存储周期双端口RAM多模块存储器单体多字存储器多模块多体并行存储器存储器高位交叉编址低位交叉编址 主存与CPU的连接 #mermaid-svg-3wv6WzRP2BvKEHQZ {font-family:"trebuchet…

【线上问题】两台服务器的时间不一致导致jwt解析错误

目录 一、问题描述二、解决方法 一、问题描述 1.线上生产问题&#xff0c;本地和测试环境均无问题 2.本地和测试由于网关和登录服务均在同一台机器 3.线上的登录服务和网关部署不在一起&#xff0c;登录服务的时间正常&#xff0c;网关服务的服务器时间比实际快5秒 4.登录服务j…

负缓存 (在 DNS 中较为常见)

摘要 负缓存&#xff0c;也被称为负值缓存或负面缓存&#xff0c;指的是在域名系统&#xff08;DNS&#xff09;中记录和重用之前失败查询结果的机制。当DNS服务器无法解析一个域名时&#xff0c;它会返回一个特定错误码&#xff08;例如NXDOMAIN&#xff09;&#xff0c;指示…

ChatGPT付费创作系统V2.6.2独立版 +WEB端+ H5端 + 小程序端

详情介绍 安装测试环境:Nginx 1.20+PHP7.4+MySQL 5.7 演示网址已升级至2.6.2最新版,仅供研究测试 WEB端:https://chat.ttbobo.cn 体验后台:https://chat.ttbobo.cn/admin 账号:admin 密码:123456 ChatGPT付费创作系统V2.6.2独立版 +WEB端+ H5端 + 小程序端 - 百创…

鸿蒙原生应用再添新丁!中国移动 入局鸿蒙

鸿蒙原生应用再添新丁&#xff01;中国移动 入局鸿蒙 来自 HarmonyOS 微博1月2日消息&#xff0c;#中国移动APP启动鸿蒙原生应用开发#&#xff0c;拥有超3亿用户的中国移动APP宣布&#xff0c;正式基于HarmonyOS NEXT启动#鸿蒙原生应用#及元服务开发。#HarmonyOS#系统的分布式…

【Linux】进程控制深度了解

> 作者简介&#xff1a;დ旧言~&#xff0c;目前大二&#xff0c;现在学习Java&#xff0c;c&#xff0c;c&#xff0c;Python等 > 座右铭&#xff1a;松树千年终是朽&#xff0c;槿花一日自为荣。 > 目标&#xff1a;熟练掌握Linux下的进程控制 > 毒鸡汤&#xff…

【Leetcode】466. 统计重复个数

文章目录 题目思路代码 题目 466. 统计重复个数 思路 题目要求找出一个最大整数 m&#xff0c;使得经过 n2 个字符串 s2 组成的字符串能够被经过 n1 个字符串 s1 组成的字符串完全包含的次数。使用动态规划来记录每个位置匹配的情况&#xff0c;并通过循环节的分析来计算最…

JavaBean

学习目的与要求 熟练掌握<jsp:useBean>、<jsp:setProperty>、<jsp:getProperty>等JSP的操作指令。 本章主要内容 编写JavaBean在JSP中使用JavaBean 一个JSP页面通过使用HTML标记为用户显示数据&#xff08;静态部分&#xff09;&#xff0c;页面中变量的…

利用码云(Gitee)与IDEA轻松管理远程代码库的完整指南

目录 前言1 码云简介2 码云上创建远程库3 IDEA集成码云的步骤3.1 安装Gitee插件并建立连接3.2 项目分享到码云3.3 拉取代码 4 码云复制Github4.1 迁移github项目到码云4.2 代码同步 结语 前言 在软件开发领域&#xff0c;代码托管平台是开发者不可或缺的利器。Github作为全球最…

Qt实现文本编辑器(二)

上一章节讲述了如何制作文本编辑页面&#xff0c;以及应该有哪些功能需要实现&#xff0c;只是做了展示效果&#xff0c;实际的点击事件并没有处理。今天来具体讲解下是如何实现菜单栏以及工具栏上对应的需求吧~ 功能实现 功能&#xff1a; 1、动作消息触发 2、具体功能&am…