遇到的问题
一
export default defineComponent ({
name: 'Login',
Component name “Login” should always be multi-word
解决
修改 name: ‘LoginPage’, 即可
二
TS报红解决方案——找不到模块“./XXX.vue”或其相应的类型声明
typescript 只能理解 .ts 文件,无法理解 .vue文件
因此需要给.vue文件加上类型说明文件
解决
修改:根目录下创建一个后缀为env.d.ts 的文件,并写入以下内容:
declare module '*.vue' {
import type { DefineComponent } from 'vue'
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types
const component: DefineComponent<{}, {}, any>
export default component
}
实现功能说明
两个页面,第一个页面称为Login,里面包含两个子路由,一个是正常登录LoginInput一个是注册RegisterInput,两个子路由页面均有一个按钮,点击将输入的参数传到下一个界面
嵌套子路由使用
通过切换上图中的登录和注册tab实现子路由切换,默认展示登录子路由
构建父页面
使用router-link完成切换,使用router-view展示子路由页面
<template>
<div class="login">
<div class="tab">
<router-link :to="{ name: 'loginInput' }">登录</router-link> |
<router-link :to="{ name: 'registerInput' }">注册</router-link>
</div>
<div class="tab">
<van-icon name="checked" size="40"/>
</div>
<router-view></router-view>
</div>
</template>
创建两个子页面
登录页
<template>
<div class="login">
<div class="container">
<div class="line">
<p>账号:</p>
<input type="text" v-model="userInput" placeholder="请输入用户名" />
</div>
<div class="line">
<p>密码:</p>
<input type="password" v-model="pwdInput" placeholder="请输入密码" />
</div>
<div class="btn-container">
<button @click="loginAction">登录</button>
</div>
<div class="param-info">
传递的参数:{{ JSON.stringify({ user: userInput, password: pwdInput }) }}
</div>
</div>
</div>
</template>
注册页面
<template>
<div class="register">
<div class="container">
<div class="line">
<p>用户名:</p>
<input type="text" v-model="userInput" placeholder="请输入用户名" />
</div>
<div class="line">
<p>手机号:</p>
<input type="number" v-model="phoneInput" placeholder="请输入手机号" />
</div>
<div class="line">
<p>密码:</p>
<input type="password" v-model="pwdInput" placeholder="请输入密码" />
</div>
<div class="btn-container">
<button @click="registerAction">注册</button>
</div>
<div class="param-info">
传递的参数:{{ JSON.stringify({ user: userInput, mobile: phoneInput, password: pwdInput }) }}
</div>
</div>
</div>
</template>
配置嵌套路由
默认展示某个子路由和默认重定向某个页面做法一致,只需设置该路由的path为:‘/’,name仍需保留具体名字,用来做点击切换路由
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: [
{
path: '/',
name: 'login',
component: Login,
children: [
{
path: '/',
name: 'loginInput',
component: () => import('../components/LoginComponent.vue')
},
{
path: '/register/input',
name: 'registerInput',
component: () => import('../components/RegisterComponent.vue')
}
]
}
]
})
现在点击登录和注册就可以自由切换两个子组件了。
页面跳转传参
除了上面的router-link,常用的跳转就是点击直接push了。
组合式API使用路由
import { useRouter } from 'vue-router'
const router = useRouter()
方式一 params
router-vue@[4.1.4] 之后,直接通过push {params:}的方式已经不能成功传递参数了,所以需要修改路由。
修改:
router 下 index.ts,新增首页路由如下,注意这里需要在path后面带上参数,格式如下,它也能避免页面刷新后,通过路由传递的参数丢失。
{
path: '/home/:user:password:phone',
name: 'home',
component: () => import('../views/Home.vue')
}
跳转事件
export default defineComponent ({
name: 'RegisterInput',
setup() {
const userInput = ref('')
const pwdInput = ref('')
const phoneInput = ref('')
const router = useRouter()
const registerAction = () => {
const info = {
user: userInput.value,
password: pwdInput.value,
phone: phoneInput.value
}
router.push({
name: 'home',
params: info
})
}
return {
userInput,
pwdInput,
registerAction,
phoneInput
}
}
})
但这样的缺点是它也会和get请求一般,将参数暴露在路由上面,效果如下
方式二 query
router 下 index.ts,新增首页路由如下
{
path: '/home',
name: 'home',
component: () => import('../views/Home.vue')
}
跳转事件
const userInput = ref('')
const pwdInput = ref('')
const router = useRouter()
const loginAction = () => {
const info = {
user: userInput.value,
password: pwdInput.value
}
router.push({
name: 'home',
query: info
})
}
效果如下
返回上一界面
/// 方式一
const vueRouter = useRouter()
const backToLastPage = () => {
vueRouter.back()
}
/// 方式二
const backToLastPage = () => {
window.history.back()
}
地址错误时自动跳转指定页面
{ path: '/:pathMatch(.*)*', name: 'NotFound', component: () => import('../views/NotFound.vue')},
NotFound.vue
<template>
<div>NOT FOUND</div>
</template>
效果如下