《Vue 中登录访问的精妙之道》

193 阅读8分钟

《Vue 中登录访问的精妙之道》

在当今数字化的时代,用户登录访问功能是各类应用程序的重要组成部分。它不仅是保障用户数据安全的关键防线,也是提供个性化服务和良好用户体验的起点。而 Vue 作为一款备受青睐的前端框架,为我们实现优雅、高效且安全的登录访问功能提供了强大的支持。 在接下来的篇章中,我们将深入探讨如何利用 Vue 的特性和优势,精心构建一个令人满意的登录访问系统,让用户的登录过程既便捷又可靠,为应用的成功奠定坚实的基础。

由文件出发

image.png

话不多说,上代码

api文件

request.js

1. 导入 axios 库

import axios from "axios"; :从 axios 库中导入 axios 对象,以便后续使用。

2. 创建 axios 实例

export const service = axios.create({... }); :创建了一个名为 serviceaxios 实例,并设置了以下配置:

- `baseURL: 'http://localhost:3001'` :指定了所有请求的基础 URL 。这意味着后续发送的请求将以这个地址为前缀,再加上具体的路径。
- `timeout: 5000` :设置了请求的超时时间为 5000 毫秒。如果在 5 秒内没有收到响应,请求将被视为超时。

3. 响应拦截器

service.interceptors.response.use((response) => {... }) :为 service 实例添加了响应拦截器。

- `console.log("响应成功", response);` :在接收到响应时,打印一条日志表示响应成功,并输出响应对象。
- `if (response.status === 200) { return response.data; } else {}` :检查响应的状态码。如果状态码为 200 ,表示请求成功,直接返回响应的数据部分(`response.data` )。如果状态码不是 200 ,目前代码中没有进一步的处理逻辑,但您可以在这里添加针对不同错误状态码的处理,比如显示错误消息、抛出异常等。

Axios 是一个流行的 JavaScript HTTP 请求库,常用于在前端向服务器发送异步请求并处理响应。

总的来说,这段代码设置了一个 axios 实例,并配置了基础 URL 和超时时间,同时添加了响应拦截器来处理接收到的响应。

index.js

1. 导入服务

import {service} from './request' :从 './request' 模块导入了之前创建的 axios 服务实例 service

2. 定义请求函数

- `export const getPosts = () => { return service.get('/posts') }` :定义了一个名为 `getPosts` 的导出函数,它通过调用 `service` 实例的 `get` 方法向 `/posts` 路径发送请求,并返回请求的结果。
- `export const getPostById = (id) => { return service.get(`/posts/${id}`) }` :定义了 `getPostById` 函数,它接收一个参数 `id` 。通过字符串模板将 `id` 拼接到 `/posts/${id}` 路径中,然后使用 `service``get` 方法发送请求获取特定 `id` 的文章数据,并返回请求结果。
- `export const getRecommendPosts = (id) => { return service.get(`/posts/${id}`) }` :与 `getPostById` 类似,也是接收一个 `id` 参数,通过字符串模板构建请求路径 `/posts/${id}` ,调用 `service``get` 方法发送请求,返回请求结果。从函数名来看,此函数可能用于获取推荐文章的数据。

这些导出的函数将数据获取的逻辑进行了封装,使得在其他模块中可以方便地通过调用这些函数来获取相应的数据,而无需直接处理 axios 的请求配置和发送细节。

router文件

index.js

1. 导入模块

import {createRouter, createMemoryHistory} from 'vue-router' :从 vue-router 库中导入了创建路由实例和内存历史模式的函数。

2. 创建路由实例

const router = createRouter({...}) :使用 createRouter 函数创建了一个路由实例,并配置了以下内容:

- `history: createMemoryHistory()` :选择使用内存历史模式,这种模式通常适用于一些特殊场景,比如在没有浏览器历史操作需求的情况下。
- `routes` :定义了路由规则数组。

    - `{ path: '/', name: 'Home', component: () => import('../views/Home.vue') }` :定义了根路径 `/` 对应的路由,名为 `Home` ,组件通过动态导入的方式加载。
    - `{ path: '/login', name: 'Login', component: () => import('../views/Login.vue') }` :定义了登录页面的路由。
    - `{ path: '/post/:id', name: 'Detail', component: () => import('../views/Detail.vue') }` :定义了动态路径 `/post/:id` 对应的路由,名为 `Detail` ,组件同样动态导入。
    - `{ path: '/cart', name: 'Cart', meta: { requireAuth: true }, component: () => import('../views/Cart.vue') }` :购物车页面的路由,并设置了 `meta` 元信息,表明该路由需要认证。

3. 路由守卫

router.beforeEach((to, from, next) => {...}) :定义了全局前置路由守卫。

- 如果要访问的路由(`to` )的 `meta` 中设置了 `requireAuth: true` (表示需要认证):
    - 如果 `localStorage` 中存在名为 `isLogined` 的项,调用 `next()` 允许继续导航。
    - 如果不存在,将路由重定向到登录页面(`next({ path: 'login' })` )。
- 对于其他不需要认证的路由,直接调用 `next()` 允许继续导航。

最后,将配置好的路由实例导出,以便在其他地方使用。

views文件

Login.vue
<template>
    <div class="container mx-auto p-4">
        <h1 class="text-3xl font-bold mb-8">
            Login
        </h1>
        <form @submit.prevent="handleSubmit">
            <div class="mb-4">
                <label for="username" class="block text-gray-700 text-sm mb-2">
                    Username:
                </label>
                <input required
                        type="text" 
                        id="username" 
                        v-model="username"
                        class="mb-4 shadow apperance-none border rounded w-full px-3 py-2 
                        texte-gray-700 leading-tight focus:outline-none focus:shadow-outline"
                >

                <label for="password" class="block text-gray-700 text-sm mb-2">
                    Password:
                </label>
                <input required
                        type="text" 
                        id="password" 
                        v-model="password"
                        class="mb-4 shadow apperance-none border rounded w-full px-3 py-2 
                        texte-gray-700 leading-tight focus:outline-none focus:shadow-outline"
                >
            </div>
            <button type="submit"
                    class="
                    bg-blue-500 hover:bg-blue-700 text-white font-white font-bold 
                    py-2 px-4 rounded focus:outline-none focus:shadow-line"

                    >
                Login in
            </button>
        </form>        
    </div>
</template>

1. 导入模块

import { ref, onMounted } from 'vue'; :从 Vue 中导入了 refonMounted 函数,用于创建响应式数据和处理组件挂载时的逻辑。

import { useRouter } from 'vue-router'; :从 vue-router 中导入 useRouter 函数,以获取路由实例进行页面导航操作。

2. 创建响应式数据

const username = ref(''); :创建一个名为 username 的响应式数据,初始值为空字符串。

const password = ref(''); :创建一个名为 password 的响应式数据,初始值也为空字符串。

3. 获取路由实例

const router = useRouter(); :获取路由实例,用于后续的页面跳转操作。

4. 定义提交处理函数

const handleSubmit = () => {... }; :定义了一个名为 handleSubmit 的函数,用于处理表单提交逻辑。

- 如果 `username` 的值为 `'admin'``password` 的值为 `'123456'` ,将 `'isLogined'` 标记存储在 `localStorage` 中,并使用 `router.push('/')` 跳转到根路径。
- 否则,弹出一个提示框显示 "用户名或者密码错误!"

5. 组件挂载时的逻辑

onMounted(() => {... }); :在组件挂载时执行以下逻辑。

- 如果 `localStorage` 中存在 `'isLogined'` 标记,弹出提示 "无需重新登录!" ,并在 500 毫秒后使用 `router.push('/')` 跳转到根路径。
Home.vue
<template>
    <div class="flex">
        <div class="container mx-auto p-4">
            <h1 class="text-3xl font-bold mb-4">
                Post List
            </h1>
            <article 
                v-for="post in posts" 
                :key="post.id"
                class="bg-white rounded-lg shadow-md p-4 mb-4"
                >
                <h2 class="text-xl font-semibold mb-2">
                    <router-link :to="{name:'Detail',params:{id : post.id}}">
                        {{ post.title }}
                    </router-link>
                </h2>
                <p class="text-gray-700 ">
                    {{ post.category }}
                </p>
            </article>
        </div>
    </div>
</template>

1. 导入模块

import {getPosts} from '../api/index.js' :从指定的路径导入了 getPosts 函数,可能用于获取文章数据。

import {onMounted, ref} from 'vue' :从 Vue 中导入了 onMounted 函数用于处理组件挂载时的逻辑,以及 ref 函数用于创建响应式数据。

2. 创建响应式数据

const posts = ref([]) :创建了一个名为 posts 的响应式数据,初始值为一个空数组。

3. 组件挂载时的逻辑

onMounted(async () => {...}) :在组件挂载时执行异步操作。

- 调用 `getPosts` 函数获取数据。
- 如果获取到了有效的数据,将其赋值给 `posts.value` ,从而更新响应式数据,可能会触发视图的更新以显示获取到的文章数据。
Detail.uve
<template>
    <div class="container mx-auto p-4">
        <div class="bg-white rounded-lg shadow-md p-8 mt-8">
            <h1 class="text-3xl font-bold mb-4">
                {{ post.title }}
                <div class="text-gray-700 mb-4 mt-4 text-2xl ">
                    <p v-html="post.category"></p>
                </div>
            </h1>
        </div>
    </div>
</template>

1. 导入模块

import { onMounted, ref } from 'vue'; :从 Vue 导入 onMounted 用于处理组件挂载时的逻辑,导入 ref 用于创建响应式数据。

import { useRoute } from 'vue-router'; :从 vue-router 导入 useRoute 以获取当前路由对象。

import { getPostById, getRecommendPosts } from '../api/index' :从指定的模块导入获取特定文章和推荐文章的函数。

2. 使用路由钩子获取当前路由

const route = useRoute(); :获取当前路由对象。

let id = route.params.id; :从路由参数中获取 id 值。

const post = ref({}) :创建一个初始为空对象的响应式数据 post

3. 组件挂载时的逻辑

onMounted(async () => {...}) :在组件挂载时执行异步操作。

- 调用 `getPostById` 函数并传入获取到的 `id` ,获取特定文章的数据。如果获取成功,将数据赋值给 `post.value` 以更新响应式数据。
- 调用 `getRecommendPosts` 函数(可能获取与当前文章相关的推荐文章),但这里没有对获取到的推荐文章数据进行处理。

总的来说,这段代码在组件挂载时,根据当前路由中的 id 获取特定文章的数据,并将其存储在响应式数据 post 中,同时还获取了推荐文章的数据,但后续没有对其进行直接的处理或使用。

Cart.vue
<template>
    <div>
        cart
    </div>
</template>

<script setup>

</script>

<style lang="css" scoped>

</style>

src文件下的APP.vue

<template>
  <nav class="bg-gray-800 text-white p-4">
    <router-link to="/" class="hover:text-gray-300 mr-4">首页</router-link>
    <router-link to="/cart" class="hover:text-gray-300 mr-4">购物车</router-link>
    <router-link to="/login" class="hover:text-gray-300">登录</router-link>
  
  </nav>
  <div class="flex">
    <router-view></router-view>
  </div>
</template>

<script setup>

</script>

<style lang="css" scoped>

</style>

总的来说,这段代码构建了一个包含导航栏和路由视图区域的页面布局。导航栏提供了几个主要页面的链接,路由视图区域会根据当前路由动态展示相应的组件内容。

总结

这个项目主要涉及了 Vue 应用的多个方面,包括路由配置、组件模板、请求处理和登录逻辑等。 在路由方面,创建了不同的路由规则,并设置了路由守卫来控制需要认证的路由访问。 组件模板中,有登录页面、首页等的布局和元素设置,通过 <router-link> 实现页面间的导航。 在请求处理部分,创建了 axios 实例,定义了多个请求函数用于获取不同的数据。 登录逻辑中,使用 ref 管理用户名和密码等数据,通过提交函数判断登录是否成功,并进行相应的处理,包括设置本地存储和页面跳转。 总体来说,项目构建了一个具有一定功能和交互性的 Vue 应用框架,为进一步的功能开发和完善提供了基础。