uniapp如何编写含有后端的登录注册页面
作者:极客李华
uniapp-含有后端的登录注册页面编写
创建数据库
数据库结构
表名:user
列名 | 数据类型 | 描述 |
---|---|---|
id | int | 自增ID |
username | varchar | 用户名 |
password | varchar | 密码 |
nickname | varchar | 昵称 |
这个方案只保留了id、username、password和nickname四个字段,以最简单的方式存储用户基本信息。需要注意的是,密码应该进行安全处理(如加密),避免泄露敏感信息。如果后续有新增信息需求,则可以随时更改表结构,添加相应的列即可。
数据库代码
-- 创建 usertable 数据库 CREATE DATABASE IF NOT EXISTS usertable; -- 切换至 usertable 数据库 USE usertable; -- 创建 user 表 CREATE TABLE IF NOT EXISTS user ( id INT(11) NOT NULL AUTO_INCREMENT, username VARCHAR(100) NOT NULL UNIQUE, password VARCHAR(100) NOT NULL, nickname VARCHAR(100) NOT NULL, PRIMARY KEY (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -- 添加一些测试数据 INSERT INTO user (username, password, nickname) VALUES ('user1', 'password1', '张三'); INSERT INTO user (username, password, nickname) VALUES ('user2', 'password2', '李四'); INSERT INTO user (username, password, nickname) VALUES ('user3', 'password3', '王五');
这段SQL代码用于创建一个名为user
的表格,并且添加了一些简单的测试数据。其中,id
列使用了自增主键约束,保证数据的唯一性。
username
列使用了unique
约束,确保用户名的唯一性。请注意,utf8mb4
是一种更高效和更通用的字符编码,支持更广泛的Unicode字符集,所以它比utf-8更推荐使用。
后端编写
创建项目(准备工作)
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.7.11</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.example</groupId> <artifactId>userTable</artifactId> <version>0.0.1-SNAPSHOT</version> <name>userTable</name> <description>userTable</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>2.7.6</version> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-jpa</artifactId> <version>2.5.6</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>5.6.3.Final</version> </dependency> <dependency> <groupId>javax.persistence</groupId> <artifactId>javax.persistence-api</artifactId> <version>2.2</version> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.3.0</version> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.3.0</version> </dependency> <dependency> <groupId>com.mysql</groupId> <artifactId>mysql-connector-j</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.4.2</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>1.8.0</version> </dependency> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-api</artifactId> <version>0.11.2</version> </dependency> <!-- 如果要使用 jjwt 的实现,还需要添加以下依赖 --> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-impl</artifactId> <version>0.11.2</version> <scope>runtime</scope> </dependency> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-jackson</artifactId> <version>0.11.2</version> <scope>runtime</scope> </dependency> <!-- Hibernate Validator --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>1.8.0</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <excludes> <exclude> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </exclude> </excludes> </configuration> </plugin> </plugins> </build> </project>
application.properties
# ????? spring.datasource.url=jdbc:mysql://localhost:3306/usertable?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai spring.datasource.username=root spring.datasource.password=123456 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver # ??????? server.port=8081 # MyBatis-Plus ?? mybatis-plus.mapper-locations=classpath:/mapper/*.xml mybatis-plus.type-aliases-package=com.example.demo.entity mybatis-plus.global-config.db-config.id-type=auto mybatis-plus.configuration.map-underscore-to-camel-case=true mybatis-plus.configuration.use-generated-keys=true mybatis-plus.configuration.map-enum-as-ordinal=false mybatis-plus.configuration.enum-handler=com.baomidou.mybatisplus.extension.handlers.MybatisEnumTypeHandler
Bean
User
import com.baomidou.mybatisplus.annotation.TableName; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @Data @AllArgsConstructor @NoArgsConstructor @TableName("user") // 声明对应的数据库表名(user) public class User { private Long id; private String username; private String password; private String nickname; }
Result
import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; @Data @Builder @AllArgsConstructor @NoArgsConstructor public class Result { private Integer code; // 状态码 private String message; // 状态信息 private Object data; // 数据 }
config
CorsConfig
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; @Configuration public class CorsConfig { @Bean public WebMvcConfigurer corsConfigurer() { return new WebMvcConfigurerAdapter() { @Override public void addCorsMappings(CorsRegistry registry) { // 允许来自本地的8080端口发起的跨域请求 registry.addMapping("/api/**") .allowedOrigins("*") .allowedMethods("GET", "POST", "PUT", "DELETE") .allowCredentials(true).maxAge(3600); } }; } }
Mapper
UserMapper
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.example.usertable.Bean.User; import org.apache.ibatis.annotations.Mapper; @Mapper public interface UserMapper extends BaseMapper<User> { }
Service
UserService
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.IService; import com.example.usertable.Bean.User; public interface UserService extends IService<User> { /** * 分页查询用户列表 */ IPage<User> selectPage(Page<User> page); /** * 用户注册 */ boolean register(User user); /** * 用户登录 */ User login(String username, String password); }
ServiceImpl
UserServiceImpl
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.example.usertable.Bean.User; import com.example.usertable.Mapper.UserMapper; import com.example.usertable.Service.UserService; import lombok.AllArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; @Service @AllArgsConstructor public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService { @Override public IPage<User> selectPage(Page<User> page) { return baseMapper.selectPage(page, null); } /** * 注册新用户(需先检查用户名是否已被使用) */ @Override public boolean register(User user) { String username = user.getUsername(); // 根据用户名查询用户 User u = this.getOne(new QueryWrapper<User>().eq("username", username)); if (u != null) { // 用户名已存在 return false; } else { // 将用户保存到数据库 return this.save(user); } } /** * 用户登录(根据用户名和密码查询用户) */ @Override public User login(String username, String password) { if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) { // 用户名和密码不能为空 return null; } return this.getOne(new QueryWrapper<User>() .eq("username", username) .eq("password", password)); } }
Controller
UserController
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.example.usertable.Bean.Result; import com.example.usertable.Bean.User; import com.example.usertable.Service.UserService; import lombok.AllArgsConstructor; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @AllArgsConstructor @RestController @RequestMapping("/users") public class UserController { private final UserService userService; /** * 获取用户列表(分页) */ @GetMapping("/") public Result list(@RequestParam(defaultValue = "1") Integer pageNum, @RequestParam(defaultValue = "10") Integer pageSize) { // 构建分页对象 Page<User> page = new Page<>(pageNum, pageSize); // 分页查询用户数据 IPage<User> userPage = userService.page(page, null); return Result.builder() .code(200) .message("获取成功") .data(userPage) .build(); } /** * 根据 ID 获取用户信息 */ @GetMapping("/{id}") public Result detail(@PathVariable Long id) { // 查询用户信息 User user = userService.getById(id); if (user != null) { return Result.builder() .code(200) .message("获取成功") .data(user) .build(); } else { return Result.builder() .code(404) .message("用户不存在") .build(); } } /** * 注册 */ @PostMapping("/register") public Result register(@RequestBody @Validated User user) { boolean success = userService.register(user); if (success) { return Result.builder() .code(200) .message("注册成功") .data(user) .build(); } else { return Result.builder() .code(500) .message("用户名已存在") .build(); } } /** * 登录 */ @PostMapping("/login") public Result login(@RequestBody User user) { String username = user.getUsername(); String password = user.getPassword(); // 查询用户 User loginUser = userService.login(username, password); if (loginUser != null) { return Result.builder() .code(200) .message("登录成功") .data(loginUser) .build(); } else { return Result.builder() .code(401) .message("用户名或密码错误") .build(); } } /** * 新增用户 */ @PostMapping("/") public Result add(@RequestBody @Validated User user) { boolean success = userService.save(user); if (success) { return Result.builder() .code(200) .message("新增成功") .data(user) .build(); } else { return Result.builder() .code(500) .message("新增失败") .data(user) .build(); } } /** * 更新用户信息 */ @PutMapping("/{id}") public Result update(@PathVariable Long id, @RequestBody @Validated User user) { user.setId(id); boolean success = userService.updateById(user); if (success) { return Result.builder() .code(200) .message("更新成功") .data(user) .build(); } else { return Result.builder() .code(500) .message("更新失败") .data(user) .build(); } } /** * 删除用户 */ @DeleteMapping("/{id}") public Result delete(@PathVariable Long id) { boolean success = userService.removeById(id); if (success) { return Result.builder() .code(200) .message("删除成功") .build(); } else { return Result.builder() .code(500) .message("删除失败") .build(); } } }
Postman测试
测试所有的接口
以下是基于8081端口号的 Postman 测试:
1. 获取用户列表(分页)
请求地址:http://localhost:8081/users/
请求方法:GET
请求参数:
参数名称 | 参数类型 | 是否必须 | 默认值 | 参数说明 |
---|---|---|---|---|
pageNum | Integer | 否 | 1 | 当前页码 |
pageSize | Integer | 否 | 10 | 每页记录数 |
成功响应:
{ "code": 200, "message": "获取成功", "data": { "records": [ { "id": 1, "username": "user1", "password": "password1", "nickname": "张三" }, { "id": 2, "username": "user2", "password": "password2", "nickname": "李四" }, { "id": 3, "username": "user3", "password": "password3", "nickname": "王五" } ], "total": 0, "size": 10, "current": 1, "orders": [], "optimizeCountSql": true, "hitCount": false, "countId": null, "maxLimit": null, "searchCount": true, "pages": 0 } }
2. 根据 ID 获取用户信息
请求地址:http://localhost:8081/users/{id}
请求方法:GET
请求路径参数:
参数名称 | 参数类型 | 是否必须 | 示例值 | 参数说明 |
---|---|---|---|---|
id | Long | 是 | 1 | 用户 ID |
成功响应:
{ "code": 200, "message": "获取成功", "data": { "id": 1, "username": "user1", "password": "password1", "nickname": "张三" } }
3. 注册
请求地址:http://localhost:8081/users/register
请求方法:POST
请求参数:
参数名称 | 参数类型 | 是否必须 | 示例值 | 参数说明 |
---|---|---|---|---|
username | String | 是 | user-11 | 用户名 |
password | String | 是 | pass-11 | 密码 |
nickname | String | 否 | lihua | 昵名 |
请求示例:
{ "username": "user-11", "password": "pass-11", "nickname":"lihua" }
成功响应:
{ "code": 200, "message": "注册成功", "data": { "id": 4, "username": "user-11", "password": "pass-11", "nickname": "lihua" } }
失败响应:
{ "code": 500, "message": "用户名已存在" }
4. 登录
请求地址:http://localhost:8081/users/login
请求方法:POST
请求参数:
参数名称 | 参数类型 | 是否必须 | 示例值 | 参数说明 |
---|---|---|---|---|
username | String | 是 | user-1 | 用户名 |
password | String | 是 | pass-1 | 密码 |
请求示例:
{ "username": "user2", "password": "password2" }
成功响应:
{ "code": 200, "message": "登录成功", "data": { "password": "password2", "nickname": "李四", "id": 2, "username": "user2" } }
失败响应:
{ "code": 401, "message": "用户名或密码错误", "data": null }
5. 新增用户
请求地址:http://localhost:8081/users/
请求方法:POST
请求参数:
参数名称 | 参数类型 | 是否必须 | 示例值 | 参数说明 |
---|---|---|---|---|
username | String | 是 | user-12 | 用户名 |
password | String | 是 | pass-12 | 密码 |
nickname | String | 否 | 小李 | 昵名 |
请求示例:
{ "username": "user-12", "password": "pass-12", "nickname": "小李" }
成功响应:
{ "code": 200, "message": "新增成功", "data": { "id": 5, "username": "user-12", "password": "pass-12", "nickname": "小李" } }
失败响应:
{ "code": 500, "message": "新增失败" }
6. 更新用户信息
请求地址:http://localhost:8081/users/{id}
请求方法:PUT
请求路径参数:
参数名称 | 参数类型 | 是否必须 | 示例值 | 参数说明 |
---|---|---|---|---|
username | String | 否 | user-12-update | 用户名 |
password | String | 否 | pass-12-update | 密码 |
String | 否 | user-12-update@example.com | 邮箱 | |
phone | String | 否 | 12345678901 | 手机号 |
请求示例:
{ "username": "user-13", "password": "pass-13", "nickname": "小李" }
成功响应:
{ "code": 200, "message": "更新成功", "data": { "id": 1, "username": "user-13", "password": "pass-13", "nickname": "小李" } }
失败响应:
{ "code": 500, "message": "更新失败" }
7. 删除用户
请求地址:http://localhost:8081/users/{id}
请求方法:DELETE
请求路径参数:
参数名称 | 参数类型 | 是否必须 | 示例值 | 参数说明 |
---|---|---|---|---|
id | Long | 是 | 12 | 用户 ID |
成功响应:
{ "code": 200, "message": "删除成功" }
失败响应:
{ "code": 500, "message": "删除失败" }
前端编写
页面编写
效果展示
文件目录
pages.json
manifest.json
{ "name": "LoginAndRegister", "appid" : "", "description" : "", "versionName" : "1.0.0", "versionCode" : "100", "transformPx" : false, /* 5+App特有相关 */ "app-plus" : { "usingComponents" : true, "nvueStyleCompiler" : "uni-app", "compilerVersion" : 3, "splashscreen" : { "alwaysShowBeforeRender" : true, "waiting" : true, "autoclose" : true, "delay" : 0 }, /* 模块配置 */ "modules" : {}, /* 应用发布信息 */ "distribute" : { /* android打包配置 */ "android" : { "permissions" : [ "<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>", "<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>", "<uses-permission android:name=\"android.permission.VIBRATE\"/>", "<uses-permission android:name=\"android.permission.READ_LOGS\"/>", "<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>", "<uses-feature android:name=\"android.hardware.camera.autofocus\"/>", "<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>", "<uses-permission android:name=\"android.permission.CAMERA\"/>", "<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>", "<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>", "<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>", "<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>", "<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>", "<uses-feature android:name=\"android.hardware.camera\"/>", "<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>" ] }, /* ios打包配置 */ "ios" : {}, /* SDK配置 */ "sdkConfigs" : {} } }, /* 快应用特有相关 */ "quickapp" : {}, /* 小程序特有相关 */ "mp-weixin" : { "appid" : "", "setting" : { "urlCheck" : false }, "usingComponents" : true }, "mp-alipay" : { "usingComponents" : true }, "mp-baidu" : { "usingComponents" : true }, "mp-toutiao" : { "usingComponents" : true }, "uniStatistics" : { "enable" : false }, "vueVersion" : "2", "h5" : { "devServer" : { "port" : 8080, //浏览器运行端口 "disableHostCheck" : true, //设置跳过host检查 "proxy" : { "/api" : { "target" : "http://localhost:8081", //目标接口域名 "changeOrigin" : true, //是否跨域 "secure" : false, // 设置支持https协议的代理 "pathRewrite":{"^/api":""} } } } } }
index.vue
<template> <view class="content"> <image class="logo" src="/static/logo.png"></image> <view class="text-area"> <text class="title">{{title}}</text> <button @click="handleClick">点击我</button> </view> </view> </template> <script> export default { data() { return { title: 'Hello' } }, onLoad() { }, methods: { handleClick() { console.log('您点击了该按钮!') } } } </script> <style> .content { display: flex; flex-direction: column; align-items: center; justify-content: center; } .logo { height: 200rpx; width: 200rpx; margin-top: 200rpx; margin-left: auto; margin-right: auto; margin-bottom: 50rpx; } .text-area { display: flex; justify-content: center; } .title { font-size: 36rpx; color: #8f8f94; } </style>
login.vue
<template> <view class="login"> <image class="logo" src="/static/logo.png"></image> <view class="input-item"> <input type="text" v-model="username" placeholder="请输入用户名"> </view> <view class="input-item"> <input type="password" v-model="password" placeholder="请输入密码"> </view> <button @click="login" class="login-btn">登录</button> <button @click="goToRegister" class="register-btn">注册</button> </view> </template> <script> import axios from 'axios' export default { data() { return { username: '', password: '' } }, methods: { login() { if (!this.username || !this.password) { uni.showToast({ title: '请填写用户名和密码', icon: 'none' }) return } // 发送请求验证用户 axios.post('/api/users/login', { username: this.username, password: this.password }).then(res => { console.log(res.data.code) if (res.data.code === 200) { // 将用户信息保存到客户端本地缓存中 uni.setStorageSync('userInfo', { id: res.data.data.id, username: res.data.data.username, password: res.data.data.password, nickname: res.data.data.nickname }) // 跳转到首页 uni.navigateTo({ url: '/pages/index/index' }) } else { uni.showToast({ title: res.data.message, icon: 'none' }) } }).catch(err => { uni.showToast({ title: '网络请求失败,请重试', icon: 'none' }) }) }, goToRegister() { uni.navigateTo({ url: '/pages/register/register' }) } } } </script> <style scoped> .login { display: flex; flex-direction: column; justify-content: center; align-items: center; margin-top: 100rpx; } .logo { width: 200rpx; height: 200rpx; margin-bottom: 20rpx; } .login-form { width: 90%; padding: 40rpx; background-color: #fff; border-radius: 5rpx; } .input-item { width: 80%; margin: 10rpx 0; border-bottom: 1rpx solid #ddd; } input { width: 100%; height: 50rpx; padding: 10rpx; font-size: 16rpx; outline: none; border: none; } .login-btn { display: block; margin: 30rpx auto 0; width: 80%; height: 80rpx; line-height: 80rpx; text-align: center; background-color: #007aff; color: #fff; border-radius: 5rpx; font-size: 20rpx; } .register-btn { margin-top: 20rpx; color: #007aff; width: 60%; height: 80rpx; } </style>
register.vue
<template> <view class="register"> <image class="logo" src="/static/logo.png"></image> <form class="register-form"> <view class="input-item"> <input type="text" v-model="nickname" placeholder="请输入昵称"> </view> <view class="input-item"> <input type="text" v-model="username" placeholder="请输入用户名"> </view> <view class="input-item"> <input type="password" v-model="password" placeholder="请输入密码"> </view> <view class="input-item"> <input type="password" v-model="confirmPassword" placeholder="请确认密码"> </view> <button type="button" class="register-btn" @click="register">注册</button> </form> <button class="back-btn" @click="goBack">返回</button> </view> </template> <script> import axios from 'axios'; export default { data() { return { username: '', password: '', confirmPassword: '', nickname: '' }; }, methods: { async register() { if(!this.username || !this.password || !this.nickname) { uni.showToast({ title: '请填写完整信息', icon: 'none' }); return; } if(this.password !== this.confirmPassword) { uni.showToast({ title: '两次输入密码不一致', icon: 'none' }); return; } try { const response = await axios.post('/api/users/register', { username: this.username, password: this.password, nickname: this.nickname }); const responseData = response.data; if(responseData.code === 200) { uni.showToast({ title: responseData.message, icon: 'success' }); uni.navigateTo({ url: '/pages/login/login' }); } else { uni.showToast({ title: responseData.message, icon: 'none' }); } } catch (error) { let errorMessage = '注册失败,请稍后再试'; if(error.response) { if(error.response.status === 500) { errorMessage = error.response.data.message; } } uni.showToast({ title: errorMessage, icon: 'none' }); } }, goBack() { uni.navigateBack(); } } }; </script> <style scoped> .register { display: flex; flex-direction: column; justify-content: center; align-items: center; margin-top: 100rpx; } .logo { width: 200rpx; height: 200rpx; margin-bottom: 20rpx; } .register-form { width: 90%; padding: 40rpx; background-color: #fff; border-radius: 5rpx; } .input-item { margin: 10rpx 0; border-bottom: 1rpx solid #ddd; } input { width: 100%; height: 50rpx; padding: 10rpx; font-size: 16rpx; outline: none; border: none; } .register-btn { display: block; margin: 30rpx auto 0; width: 90%; height: 80rpx; line-height: 80rpx; text-align: center; background-color: #007aff; color: #fff; border-radius: 5rpx; font-size: 20rpx; } .back-btn { margin-top: 20rpx; color: #007aff; width: 60%; height: 80rpx; } </style>
总结
到此这篇关于uniapp如何编写含有后端的登录注册页面的文章就介绍到这了,更多相关uniapp有后端登录注册页面内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!