实现基于Vue 3组合式API的登录页面实验三

Vue 3 的组合式 API 具有以下特点:

  1. 更好的逻辑组织:传统的 Options API 将所有配置选项放在一个对象中,而组合式 API 可以根据功能或逻辑相关性将代码组织在一起,使代码更清晰、易于理解和维护。

  2. 使用 setup 函数:组合式 API 使用 ?setup()? 函数来代替传统的 ?data()?、?methods()? 等选项。在 ?setup()? 函数中,可以创建响应式数据、定义方法,并将它们返回给模板使用。

  3. 响应式数据:通过使用 ?ref? 和 ?reactive?,可以创建响应式数据。?ref? 用于包装基本类型数据,而 ?reactive? 则用于包装对象和数组。

  4. 计算属性:可以使用 ?computed? 函数创建计算属性,类似于 Vue 2 中的 ?computed? 选项。

  5. 监听数据变化:通过使用 ?watch? 函数,可以监听数据的变化,并执行相应的操作。?watchEffect? 则可以监听数据的变化,并在回调函数中执行相应的副作用。

  6. 生命周期钩子:Vue 3 的组合式 API 也引入了一些新的生命周期钩子函数,如 ?onMounted?、?onUpdated?、?onBeforeUnmount? 等,用于处理组件在不同阶段的逻辑。

  7. 自定义逻辑复用:通过将逻辑相关的代码组织在自定义的函数中,可以实现逻辑的复用。这些函数可以由多个组件共享,提高了代码的可重用性。

Vue 3 相对于 Vue 2,有以下变化:

  1. 更快的渲染性能:Vue 3 使用了 Virtual DOM 的重写,提高了渲染性能和页面响应速度。

  2. 更小的体积:Vue 3 在开发阶段通过 Tree shaking 和按需引入的方式,将库的体积进一步减少。生产环境使用的构建版本比 Vue 2 更小。

  3. 组合式 API:Vue 3 引入了组合式 API,提供了更灵活、可组合和易于重用的代码组织方式。组合式 API 基于 ?setup()? 函数进行组件逻辑的编写,使得代码更清晰、易读和维护。

  4. 更好的 TypeScript 支持:Vue 3 对 TypeScript 的支持更加完善,包括对 Composition API 的类型推断和声明文件的改进。

  5. Teleport 组件:Vue 3 引入了 Teleport 组件,用于将组件的内容传送到指定的目标位置,方便进行 Portal(传送门)式的组件开发。

  6. Fragment:Vue 3 引入了 Fragment(片段)的概念,允许组件可以返回多个根节点而无需包裹在一个无意义的父元素中。

  7. 更改的事件修饰符语法:事件修饰符语法在 Vue 3 中有所改变,使用了更具表达力的语法来声明事件修饰符。

  8. 移除了一些不常用的特性和 API:Vue 3 移除了 Vue 2 中很少使用的特性和 API,以简化代码库、提高维护性和减少包的体积。

需要注意的是,虽然 Vue 3 在很多方面有所改变,但它仍然保持了与 Vue 2 的相似性,开发者可以相对容易地迁移到 Vue 3。同时,Vue 3 也提供了逐渐迁移的指南,使得现有的 Vue 2 项目可以平稳过渡到 Vue 3。

一、程序代码

登录界面:

1. 用VS Code或WebStorm(后面的步骤以VS Code为例)打开实验二(专栏有)创建的myweb项目文件夹。

2. 在VS Code中鼠标右键单击项目的components目录,在弹出的菜单中选择“新建文件”,在输入框中输入新建文件的文件名为UserLogin.vue。

3. 在打开的UserLogin.vue文件中输入构成Vue组件的三个元素,代码如下:

<template>

</template>

<script setup lang="ts">

</script>

<style scoped>

</style>

template部分是界面的展示代码,可以写HTML标记和Vue的组件标记;script部分是业务实现代码,可以使用JavaScript或TypeScript调用Vue的API来实现业务逻辑;style界面布局代码,可以通过CSS等样式定义语言来定义界面的样式。

4.把实验一webdemo项目中login.html文件中body元素内div元素的内容复制myweb项目Login.vue文件的template元素内,把webdemo项目中login.css文件中.center和div的样式定义复制到szweb项目UserLogin.vue文件的style元素内。复制完成以后,UserLogin.vue文件的内容如下所示:

<script setup lang="ts">

</script>

<template>

    <div class="center">

        <form action="/webdemo/login" method="post">

            <p style="margin-bottom: 50px">用户登录</p>

            <p>

                <label for="username">请输入账号:</label>

                <input id="username" name="username" type="text" />

            </p>

            <p>

                <label for="password">请输入密码:</label>

                <input id="password" name="password" type="text" />

            </p>

            <input type="submit" value="提交" onclick="valid()" />

        </form>

    </div>

</template>

<style scoped>

.center {

    display: flex;

    justify-content: center;

    align-items: center;

    width: 600px;

    height: 300px;

    background-color: #f0f0f0;    

}

div {box-shadow: 0px 0px 10px #888888;}

</style>

5. 在VS Code中打开App.vue文件,修改App.vue文件的内容如下列代码所示:

<script setup lang="ts">

import UserLogin from './components/UserLogin.vue'

</script>

<template>

  <user-login />

</template>

6.按下Ctrl+Shift+`组合键打开VS Code的终端窗口,在窗口中输入:

pnpm dev

运行项目以后,按住Ctrl键点击http://localhost:5174/链接在浏览器中会看到登录页面。

7. 修改vite.config.ts配置文件,设置mock模拟数据的路径和服务器端口号,修改后vite.config.ts文件的内容如下列代码所示:

import { fileURLToPath, URL } from 'node:url'

import { defineConfig } from 'vite'

import vue from '@vitejs/plugin-vue'

import { viteMockServe } from "vite-plugin-mock";

// https://vitejs.dev/config/

export default defineConfig({

  plugins: [vue(), viteMockServe({ mockPath: './mock' })],

  resolve: {

    alias: {

      '@': fileURLToPath(new URL('./src', import.meta.url))

    }

  },

  server: {

    port: 8080, //启动端口  

  },

})

8. 在myweb项目目录下新建mock目录,用来存放模拟后端数据的文件。

9. 在mock目录下新建index.ts文件,在该文件中实现后端数据的模拟,代码如下:

import type { MockMethod } from 'vite-plugin-mock'

const userData = [

    {

        username: 'admin',

        password: '12345'

    },

    {

        username: 'test',

        password: 'test'

    }

]

export default [

    {

        url: '/api/login',

        method: 'post',

        response: (data:any) => {

            const info = data.body

            const result= userData.some(item=>{

                return item.username===info.username&&item.password===info.password

            })

            const msg=result?`登录成功,欢迎${info.username}!`:'登录失败,用户名或密码不正确!'

            return {msg};

        },

    },

] as MockMethod[];

10. 在src目录下新建utils目录,在该目录下新建request.ts文件,在该文件中创建利用axios向后端发送异步请求的service并导出,如下列代码所示:

import axios from 'axios'

const baseURL = '/'

const service = axios.create({

    baseURL,

    timeout: 5000, // 请求的最长响应时间

});

export default service

11. 在src下新建api目录,在该目录下新建user.ts文件,在该文件中使用service创建向后端发送访问用户数据请求的API,发送的请求会被Mock拦截从而返回模拟数据,如下列代码所示:

import service from "@/utils/request";

export interface User{

    username:string,

    password:string

}

export function login(data:User) {

    return service({

        url: "/api/login",

        method: "post",

        data: data,

    });

}

12. 修改UserLogin.vue文件的script和template元素,实现基于Vue 3的登录页面,修改后代码如下所示:

<script lang="ts" setup>
import {ref} from 'vue';
import {login} from '@/api/user'
const username = ref('')
const password = ref('')
const result = ref('')
const handleLogin = async () => {
  if (username.value === '' || password.value === '') {
    alert('用户名或密码不能为空!')
  } else {
    try {
      const res = await login({username: username.value, password: password.value})
      result.value = res.data.msg
    }
    catch (e) {
      alert(e)
    }
  }
}
</script>
<template>
  <div class="center">
    <form method="post">
      <p style="margin-bottom: 50px">用户登录</p>
      <p>
        <label for="username">请输入账号:</label>
        <input id="username" v-model="username" type="text"/>
      </p>
      <p>
        <label for="password">请输入密码:</label>
        <input id="password" v-model="password" type="password"/>
      </p>
      <button @click.prevent="handleLogin">提交</button>
      <h2>{{result}}</h2>
    </form>
  </div>
</template>
<style scoped>
.center {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 600px;
  height: 300px;
  background-color: #f0f0f0;
}
div {
  box-shadow: 0px 0px 10px #888888;
}
</style>

13. 运行项目,测试登录页面。

运行程序:pnpm dev