我正在尝试使用 Typescript 而不是 JavaScript 在我的笔记本电脑上启动并运行这个示例。这是一个示例“笔记”应用程序,展示了 Python+VUE3 的功能,包括身份验证。我的 GitHub 存储库位于here。 最后,我取得了不错的进展,但是,目前我陷入了 Register.vue 组件,当注册过程完成并且用户应该被“推送”到仪表板时。 这是“Register.vue”视图的代码:
<template>
<div class="mb-3">
<label for="username" class="form-label">Username:</label>
<input type="text" name="username" v-model="username" class="form-control" />
</div>
<div class="mb-3">
<label for="full_name" class="form-label">Full Name:</label>
<input type="text" name="full_name" v-model="full_name" class="form-control" />
</div>
<div class="mb-3">
<label for="password" class="form-label">Password:</label>
<input type="password" name="password" v-model="password" class="form-control" />
</div>
<button type="submit" class="btn btn-primary" @click="submit">Register</button>
</template>
<script lang="ts">
import { ref, defineComponent } from 'vue'
import { useStore } from '../store/index';
import { useRouter } from '../router/index';
import { UsersActionTypes } from '../store/modules/users/action-types';
export default defineComponent({
name: 'Register',
setup() {
const store = useStore();
const router = useRouter();
const username = ref('');
const full_name = ref('');
const password = ref('');
const submit = () => {
console.log("start submit");
store.dispatch(UsersActionTypes.REGISTER, {
"username": username.value,
"full_name": full_name.value,
"password": password.value
})
.then((res) => {
console.log("res: " + JSON.stringify(res));
router.push('/dashboard');
})
//.catch((reason) => {
// console.log("catch error: " + JSON.stringify(reason));
// })
//.finally(() => {
// console.log("finally error");
// });
}
return {
submit,
username,
full_name,
password
};
}
})
</script>
从控制台的调试日志来看,一切似乎都正确执行(用户操作“注册”调用“登录”,调用“viewme”,提交状态)。我的印象是,注册组件在调用用户操作“注册”后完全停止。
路由器index.ts文件如下所示:
import {
createRouter,
createWebHistory,
RouteRecordRaw,
Router
} from 'vue-router';
import { useStore } from '../store/index';
import Home from '../views/Home.vue';
import Register from '../views/Register.vue';
import Login from '../views/Login.vue';
import Dashboard from '../views/Dashboard.vue';
import Profile from '../views/Profile.vue';
import Note from '../views/Note.vue';
import EditNote from '../views/EditNote.vue';
const store = useStore();
const routes: RouteRecordRaw[] = [
{
path: '/',
name: "Home",
component: Home
},
{
path: '/register',
name: 'Register',
component: Register,
},
{
path: '/login',
name: 'Login',
component: Login,
},
{
path: '/dashboard',
name: 'Dashboard',
component: Dashboard,
meta: { requiresAuth: true },
},
{
path: '/profile',
name: 'Profile',
component: Profile,
meta: { requiresAuth: true },
},
{
path: '/note/:id',
name: 'Note',
component: Note,
meta: { requiresAuth: true }
},
{
path: '/note/:id',
name: 'EditNote',
component: EditNote,
meta: { requiresAuth: true }
}
]
let router: Router;
export function useRouter() {
if (!router) {
router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes,
});
router.beforeEach((to, from, next) => {
if (to.matched.some(record => record.meta.requiresAuth)) {
if (store.getters.isAuthenticated) {
next();
return;
}
next('/login');
} else {
next();
}
});
}
return router;
}
我将更改推送到了我的存储库,我希望完成这个示例的路不会太远。预先感谢您对我的帮助!
使用路由器的正确方法是推送配置对象。 从来没有在文档中注意到
.push('/dashboard')
的能力,而且我个人永远不会这样做,因为这可能对你以后不利。
您错过了命名路线的目的。
对于您已声明的
/dashboard
路径 name: 'Dashboard'
,为此,首选用法是:
router.push({ name: 'Dashboard' })
这同样适用于导航守卫中的
next
:next({ name: 'Login' })
如果您决定更改它,这将使您不必遍历所有代码来使用新路径更新每个按钮、链接和路由器推送。
除此之外,如果仍然无法正常工作,我建议您确保您已在
vue-router
中正确注册new Vue({})
,确保路由器配置确实已加载。
我还建议在实施第 3 方教程中的某些内容之前,通过遵循官方文档来学习基础知识,以避免导致这些神秘错误的正确用法的错误信息。人们代码中的大多数错误都来自此类教程网站。作者的代码不一定 100% 准确和正确。
如果您的页面上有
<form>
标记且带有 <button type="submit">
并且您的页面意外重新加载,则需要在为表单提交事件执行自定义函数时防止原生表单提交发生,正确用法如下:
<template>
<form @submit.prevent="submit">
<button type="submit">Register</button>
</form>
</template>
<script setup>
function submit () {
alert('I am a custom submit action.')
}
</script>
.prevent
将取消本机浏览器提交事件操作,以便触发您的自定义提交功能,而浏览器不会同时意外重新加载页面。
我的应用程序中也有类似的问题。调用
await
的方法上缺少 router.push({ query })
,这创建了一个竞争条件,破坏了我的一些参数。