Vue 3 的组合式 API 具有以下特点:
更好的逻辑组织:传统的 Options API 将所有配置选项放在一个对象中,而组合式 API 可以根据功能或逻辑相关性将代码组织在一起,使代码更清晰、易于理解和维护。
使用 setup 函数:组合式 API 使用
setup()
函数来代替传统的data()
、methods()
等选项。在setup()
函数中,可以创建响应式数据、定义方法,并将它们返回给模板使用。响应式数据:通过使用
ref
和reactive
,可以创建响应式数据。ref
用于包装基本类型数据,而reactive
则用于包装对象和数组。计算属性:可以使用
computed
函数创建计算属性,类似于 Vue 2 中的computed
选项。监听数据变化:通过使用
watch
函数,可以监听数据的变化,并执行相应的操作。watchEffect
则可以监听数据的变化,并在回调函数中执行相应的副作用。生命周期钩子:Vue 3 的组合式 API 也引入了一些新的生命周期钩子函数,如
onMounted
、onUpdated
、onBeforeUnmount
等,用于处理组件在不同阶段的逻辑。自定义逻辑复用:通过将逻辑相关的代码组织在自定义的函数中,可以实现逻辑的复用。这些函数可以由多个组件共享,提高了代码的可重用性。
Vue 3 相对于 Vue 2,有以下变化:
更快的渲染性能:Vue 3 使用了 Virtual DOM 的重写,提高了渲染性能和页面响应速度。
更小的体积:Vue 3 在开发阶段通过 Tree shaking 和按需引入的方式,将库的体积进一步减少。生产环境使用的构建版本比 Vue 2 更小。
组合式 API:Vue 3 引入了组合式 API,提供了更灵活、可组合和易于重用的代码组织方式。组合式 API 基于
setup()
函数进行组件逻辑的编写,使得代码更清晰、易读和维护。更好的 TypeScript 支持:Vue 3 对 TypeScript 的支持更加完善,包括对 Composition API 的类型推断和声明文件的改进。
Teleport 组件:Vue 3 引入了 Teleport 组件,用于将组件的内容传送到指定的目标位置,方便进行 Portal(传送门)式的组件开发。
Fragment:Vue 3 引入了 Fragment(片段)的概念,允许组件可以返回多个根节点而无需包裹在一个无意义的父元素中。
更改的事件修饰符语法:事件修饰符语法在 Vue 3 中有所改变,使用了更具表达力的语法来声明事件修饰符。
移除了一些不常用的特性和 API:Vue 3 移除了 Vue 2 中很少使用的特性和 API,以简化代码库、提高维护性和减少包的体积。
需要注意的是,虽然 Vue 3 在很多方面有所改变,但它仍然保持了与 Vue 2 的相似性,开发者可以相对容易地迁移到 Vue 3。同时,Vue 3 也提供了逐渐迁移的指南,使得现有的 Vue 2 项目可以平稳过渡到 Vue 3。
一、实验名称
实现基于Vue 3组合式API的登录系统。
二、参考资料
《Vue 3官方网站:https://cn.vuejs.org》、《Axios:https://www.axios-http.cn》、《Mock.js:http://mockjs.com 》。
三、实验目的
1. 练习使用组合式API编写Vue组件显示后端数据。
2. 练习使用Axios向后端发送异步请求。
3. 练习使用Mock.js模拟后端数据。
四、实验内容
登录界面:
注意:本实验需要导入的几个包在Web实验练习专栏的实验二有给出!!
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