uniapp如何編寫(xiě)含有后端的登錄注冊(cè)頁(yè)面
uniapp-含有后端的登錄注冊(cè)頁(yè)面編寫(xiě)
創(chuàng)建數(shù)據(jù)庫(kù)
數(shù)據(jù)庫(kù)結(jié)構(gòu)
表名:user
列名 | 數(shù)據(jù)類(lèi)型 | 描述 |
---|---|---|
id | int | 自增ID |
username | varchar | 用戶(hù)名 |
password | varchar | 密碼 |
nickname | varchar | 昵稱(chēng) |
這個(gè)方案只保留了id、username、password和nickname四個(gè)字段,以最簡(jiǎn)單的方式存儲(chǔ)用戶(hù)基本信息。需要注意的是,密碼應(yīng)該進(jìn)行安全處理(如加密),避免泄露敏感信息。如果后續(xù)有新增信息需求,則可以隨時(shí)更改表結(jié)構(gòu),添加相應(yīng)的列即可。
數(shù)據(jù)庫(kù)代碼
-- 創(chuàng)建 usertable 數(shù)據(jù)庫(kù) CREATE DATABASE IF NOT EXISTS usertable; -- 切換至 usertable 數(shù)據(jù)庫(kù) USE usertable; -- 創(chuàng)建 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; -- 添加一些測(cè)試數(shù)據(jù) 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代碼用于創(chuàng)建一個(gè)名為user
的表格,并且添加了一些簡(jiǎn)單的測(cè)試數(shù)據(jù)。其中,id
列使用了自增主鍵約束,保證數(shù)據(jù)的唯一性。
username
列使用了unique
約束,確保用戶(hù)名的唯一性。請(qǐng)注意,utf8mb4
是一種更高效和更通用的字符編碼,支持更廣泛的Unicode字符集,所以它比utf-8更推薦使用。
后端編寫(xiě)
創(chuàng)建項(xiàng)目(準(zhǔn)備工作)
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 的實(shí)現(xiàn),還需要添加以下依賴(lài) --> <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") // 聲明對(duì)應(yīng)的數(shù)據(jù)庫(kù)表名(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; // 狀態(tài)碼 private String message; // 狀態(tài)信息 private Object data; // 數(shù)據(jù) }
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) { // 允許來(lái)自本地的8080端口發(fā)起的跨域請(qǐng)求 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> { /** * 分頁(yè)查詢(xún)用戶(hù)列表 */ IPage<User> selectPage(Page<User> page); /** * 用戶(hù)注冊(cè) */ boolean register(User user); /** * 用戶(hù)登錄 */ 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); } /** * 注冊(cè)新用戶(hù)(需先檢查用戶(hù)名是否已被使用) */ @Override public boolean register(User user) { String username = user.getUsername(); // 根據(jù)用戶(hù)名查詢(xún)用戶(hù) User u = this.getOne(new QueryWrapper<User>().eq("username", username)); if (u != null) { // 用戶(hù)名已存在 return false; } else { // 將用戶(hù)保存到數(shù)據(jù)庫(kù) return this.save(user); } } /** * 用戶(hù)登錄(根據(jù)用戶(hù)名和密碼查詢(xún)用戶(hù)) */ @Override public User login(String username, String password) { if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) { // 用戶(hù)名和密碼不能為空 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; /** * 獲取用戶(hù)列表(分頁(yè)) */ @GetMapping("/") public Result list(@RequestParam(defaultValue = "1") Integer pageNum, @RequestParam(defaultValue = "10") Integer pageSize) { // 構(gòu)建分頁(yè)對(duì)象 Page<User> page = new Page<>(pageNum, pageSize); // 分頁(yè)查詢(xún)用戶(hù)數(shù)據(jù) IPage<User> userPage = userService.page(page, null); return Result.builder() .code(200) .message("獲取成功") .data(userPage) .build(); } /** * 根據(jù) ID 獲取用戶(hù)信息 */ @GetMapping("/{id}") public Result detail(@PathVariable Long id) { // 查詢(xún)用戶(hù)信息 User user = userService.getById(id); if (user != null) { return Result.builder() .code(200) .message("獲取成功") .data(user) .build(); } else { return Result.builder() .code(404) .message("用戶(hù)不存在") .build(); } } /** * 注冊(cè) */ @PostMapping("/register") public Result register(@RequestBody @Validated User user) { boolean success = userService.register(user); if (success) { return Result.builder() .code(200) .message("注冊(cè)成功") .data(user) .build(); } else { return Result.builder() .code(500) .message("用戶(hù)名已存在") .build(); } } /** * 登錄 */ @PostMapping("/login") public Result login(@RequestBody User user) { String username = user.getUsername(); String password = user.getPassword(); // 查詢(xún)用戶(hù) 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("用戶(hù)名或密碼錯(cuò)誤") .build(); } } /** * 新增用戶(hù) */ @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(); } } /** * 更新用戶(hù)信息 */ @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(); } } /** * 刪除用戶(hù) */ @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測(cè)試
測(cè)試所有的接口
以下是基于8081端口號(hào)的 Postman 測(cè)試:
1. 獲取用戶(hù)列表(分頁(yè))
請(qǐng)求地址:http://localhost:8081/users/
請(qǐng)求方法:GET
請(qǐng)求參數(shù):
參數(shù)名稱(chēng) | 參數(shù)類(lèi)型 | 是否必須 | 默認(rèn)值 | 參數(shù)說(shuō)明 |
---|---|---|---|---|
pageNum | Integer | 否 | 1 | 當(dāng)前頁(yè)碼 |
pageSize | Integer | 否 | 10 | 每頁(yè)記錄數(shù) |
成功響應(yīng):
{ "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. 根據(jù) ID 獲取用戶(hù)信息
請(qǐng)求地址:http://localhost:8081/users/{id}
請(qǐng)求方法:GET
請(qǐng)求路徑參數(shù):
參數(shù)名稱(chēng) | 參數(shù)類(lèi)型 | 是否必須 | 示例值 | 參數(shù)說(shuō)明 |
---|---|---|---|---|
id | Long | 是 | 1 | 用戶(hù) ID |
成功響應(yīng):
{ "code": 200, "message": "獲取成功", "data": { "id": 1, "username": "user1", "password": "password1", "nickname": "張三" } }
3. 注冊(cè)
請(qǐng)求地址:http://localhost:8081/users/register
請(qǐng)求方法:POST
請(qǐng)求參數(shù):
參數(shù)名稱(chēng) | 參數(shù)類(lèi)型 | 是否必須 | 示例值 | 參數(shù)說(shuō)明 |
---|---|---|---|---|
username | String | 是 | user-11 | 用戶(hù)名 |
password | String | 是 | pass-11 | 密碼 |
nickname | String | 否 | lihua | 昵名 |
請(qǐng)求示例:
{ "username": "user-11", "password": "pass-11", "nickname":"lihua" }
成功響應(yīng):
{ "code": 200, "message": "注冊(cè)成功", "data": { "id": 4, "username": "user-11", "password": "pass-11", "nickname": "lihua" } }
失敗響應(yīng):
{ "code": 500, "message": "用戶(hù)名已存在" }
4. 登錄
請(qǐng)求地址:http://localhost:8081/users/login
請(qǐng)求方法:POST
請(qǐng)求參數(shù):
參數(shù)名稱(chēng) | 參數(shù)類(lèi)型 | 是否必須 | 示例值 | 參數(shù)說(shuō)明 |
---|---|---|---|---|
username | String | 是 | user-1 | 用戶(hù)名 |
password | String | 是 | pass-1 | 密碼 |
請(qǐng)求示例:
{ "username": "user2", "password": "password2" }
成功響應(yīng):
{ "code": 200, "message": "登錄成功", "data": { "password": "password2", "nickname": "李四", "id": 2, "username": "user2" } }
失敗響應(yīng):
{ "code": 401, "message": "用戶(hù)名或密碼錯(cuò)誤", "data": null }
5. 新增用戶(hù)
請(qǐng)求地址:http://localhost:8081/users/
請(qǐng)求方法:POST
請(qǐng)求參數(shù):
參數(shù)名稱(chēng) | 參數(shù)類(lèi)型 | 是否必須 | 示例值 | 參數(shù)說(shuō)明 |
---|---|---|---|---|
username | String | 是 | user-12 | 用戶(hù)名 |
password | String | 是 | pass-12 | 密碼 |
nickname | String | 否 | 小李 | 昵名 |
請(qǐng)求示例:
{ "username": "user-12", "password": "pass-12", "nickname": "小李" }
成功響應(yīng):
{ "code": 200, "message": "新增成功", "data": { "id": 5, "username": "user-12", "password": "pass-12", "nickname": "小李" } }
失敗響應(yīng):
{ "code": 500, "message": "新增失敗" }
6. 更新用戶(hù)信息
請(qǐng)求地址:http://localhost:8081/users/{id}
請(qǐng)求方法:PUT
請(qǐng)求路徑參數(shù):
參數(shù)名稱(chēng) | 參數(shù)類(lèi)型 | 是否必須 | 示例值 | 參數(shù)說(shuō)明 |
---|---|---|---|---|
username | String | 否 | user-12-update | 用戶(hù)名 |
password | String | 否 | pass-12-update | 密碼 |
String | 否 | user-12-update@example.com | 郵箱 | |
phone | String | 否 | 12345678901 | 手機(jī)號(hào) |
請(qǐng)求示例:
{ "username": "user-13", "password": "pass-13", "nickname": "小李" }
成功響應(yīng):
{ "code": 200, "message": "更新成功", "data": { "id": 1, "username": "user-13", "password": "pass-13", "nickname": "小李" } }
失敗響應(yīng):
{ "code": 500, "message": "更新失敗" }
7. 刪除用戶(hù)
請(qǐng)求地址:http://localhost:8081/users/{id}
請(qǐng)求方法:DELETE
請(qǐng)求路徑參數(shù):
參數(shù)名稱(chēng) | 參數(shù)類(lèi)型 | 是否必須 | 示例值 | 參數(shù)說(shuō)明 |
---|---|---|---|---|
id | Long | 是 | 12 | 用戶(hù) ID |
成功響應(yīng):
{ "code": 200, "message": "刪除成功" }
失敗響應(yīng):
{ "code": 500, "message": "刪除失敗" }
前端編寫(xiě)
頁(yè)面編寫(xiě)
效果展示
文件目錄
pages.json
manifest.json
{ "name": "LoginAndRegister", "appid" : "", "description" : "", "versionName" : "1.0.0", "versionCode" : "100", "transformPx" : false, /* 5+App特有相關(guān) */ "app-plus" : { "usingComponents" : true, "nvueStyleCompiler" : "uni-app", "compilerVersion" : 3, "splashscreen" : { "alwaysShowBeforeRender" : true, "waiting" : true, "autoclose" : true, "delay" : 0 }, /* 模塊配置 */ "modules" : {}, /* 應(yīng)用發(fā)布信息 */ "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" : {} } }, /* 快應(yīng)用特有相關(guān) */ "quickapp" : {}, /* 小程序特有相關(guān) */ "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, //瀏覽器運(yùn)行端口 "disableHostCheck" : true, //設(shè)置跳過(guò)host檢查 "proxy" : { "/api" : { "target" : "http://localhost:8081", //目標(biāo)接口域名 "changeOrigin" : true, //是否跨域 "secure" : false, // 設(shè)置支持https協(xié)議的代理 "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">點(diǎn)擊我</button> </view> </view> </template> <script> export default { data() { return { title: 'Hello' } }, onLoad() { }, methods: { handleClick() { console.log('您點(diǎn)擊了該按鈕!') } } } </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="請(qǐng)輸入用戶(hù)名"> </view> <view class="input-item"> <input type="password" v-model="password" placeholder="請(qǐng)輸入密碼"> </view> <button @click="login" class="login-btn">登錄</button> <button @click="goToRegister" class="register-btn">注冊(cè)</button> </view> </template> <script> import axios from 'axios' export default { data() { return { username: '', password: '' } }, methods: { login() { if (!this.username || !this.password) { uni.showToast({ title: '請(qǐng)?zhí)顚?xiě)用戶(hù)名和密碼', icon: 'none' }) return } // 發(fā)送請(qǐng)求驗(yàn)證用戶(hù) axios.post('/api/users/login', { username: this.username, password: this.password }).then(res => { console.log(res.data.code) if (res.data.code === 200) { // 將用戶(hù)信息保存到客戶(hù)端本地緩存中 uni.setStorageSync('userInfo', { id: res.data.data.id, username: res.data.data.username, password: res.data.data.password, nickname: res.data.data.nickname }) // 跳轉(zhuǎn)到首頁(yè) uni.navigateTo({ url: '/pages/index/index' }) } else { uni.showToast({ title: res.data.message, icon: 'none' }) } }).catch(err => { uni.showToast({ title: '網(wǎng)絡(luò)請(qǐng)求失敗,請(qǐng)重試', 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="請(qǐng)輸入昵稱(chēng)"> </view> <view class="input-item"> <input type="text" v-model="username" placeholder="請(qǐng)輸入用戶(hù)名"> </view> <view class="input-item"> <input type="password" v-model="password" placeholder="請(qǐng)輸入密碼"> </view> <view class="input-item"> <input type="password" v-model="confirmPassword" placeholder="請(qǐng)確認(rèn)密碼"> </view> <button type="button" class="register-btn" @click="register">注冊(cè)</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: '請(qǐng)?zhí)顚?xiě)完整信息', 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 = '注冊(cè)失敗,請(qǐng)稍后再試'; 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>
總結(jié)
到此這篇關(guān)于uniapp如何編寫(xiě)含有后端的登錄注冊(cè)頁(yè)面的文章就介紹到這了,更多相關(guān)uniapp有后端登錄注冊(cè)頁(yè)面內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
KnockoutJS 3.X API 第四章之表單textInput、hasFocus、checked綁定
這篇文章主要介紹了KnockoutJS 3.X API 第四章之表單textInput、hasFocus、checked綁定的相關(guān)資料,需要的朋友可以參考下2016-10-10根據(jù)后端返回的json數(shù)據(jù)快速生成ts類(lèi)型的實(shí)現(xiàn)代碼
在前端開(kāi)發(fā)中,我們通常需要處理來(lái)自后端或其他數(shù)據(jù)源的 JSON 數(shù)據(jù),這些數(shù)據(jù)可能非常復(fù)雜,包含不同類(lèi)型的屬性,甚至嵌套對(duì)象和數(shù)組,為了更好地使用這些數(shù)據(jù),我們希望將其轉(zhuǎn)換為T(mén)ypeScript類(lèi)型定義,以獲得類(lèi)型檢查和代碼智能提示的好處2023-10-10淺析JavaScript如何解決跨域問(wèn)題并手寫(xiě)一個(gè)jsonp
跨域是指瀏覽器為了安全性,實(shí)施的同源策略,同源策略要求,只有協(xié)議、域名和端口號(hào)完全相同的網(wǎng)頁(yè),才能共享資源,本文整理了一些常用的跨域解決方法,希望對(duì)大家有所幫助2024-03-03JS數(shù)組中的splice()方法及用原生寫(xiě)法分享
這篇文章主要介紹了JS中數(shù)組的splice()方法,包括其用途、參數(shù)(起始位置、刪除元素個(gè)數(shù)、添加元素等)、不同參數(shù)情況的處理方式,還詳細(xì)講解了用原生JS手寫(xiě)splice()方法的思路和代碼實(shí)現(xiàn)2024-11-11JavaScript圣杯布局與雙飛翼布局實(shí)現(xiàn)案例詳解
這篇文章主要介紹了JavaScript圣杯布局與雙飛翼布局實(shí)現(xiàn)案例,這是前端面試中需要掌握的知識(shí)點(diǎn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-08-08

微信小程序骨架屏的應(yīng)用與實(shí)現(xiàn)步驟詳細(xì)記錄