欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解SpringBoot項(xiàng)目整合Vue做一個(gè)完整的用戶注冊(cè)功能

 更新時(shí)間:2022年07月15日 09:14:27   作者:heshengfu1211  
本文主要介紹了SpringBoot項(xiàng)目整合Vue做一個(gè)完整的用戶注冊(cè)功能,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

前言

用戶注冊(cè)功能是每一個(gè)系統(tǒng)的入口門(mén)面功能,很多人可能會(huì)以為很簡(jiǎn)單,不就是一個(gè)簡(jiǎn)單的CRUD嗎?其實(shí)不然,要把前后端功能都做出來(lái),頁(yè)面跳轉(zhuǎn)也沒(méi)問(wèn)題,還真不簡(jiǎn)單。這次筆者做這么一個(gè)看似簡(jiǎn)單的用戶注冊(cè)功能就花了足足兩天多時(shí)間,中間調(diào)試和解決Bug也花了好長(zhǎng)時(shí)間。這次我就把自己做出的完整功能的實(shí)現(xiàn)過(guò)程作了一個(gè)提煉分享到我的公眾號(hào)上來(lái)。希望有需要了解如何實(shí)現(xiàn)用戶注冊(cè)完整過(guò)程的讀者朋友能夠仔細(xì)看一看。

說(shuō)明:本文前后端代碼的實(shí)現(xiàn)分別在本人之前二次開(kāi)發(fā)的開(kāi)源項(xiàng)目vue-element-adminvueblog兩個(gè)項(xiàng)目的基礎(chǔ)上進(jìn)行

1 實(shí)現(xiàn)用戶注冊(cè)流程

1.1 用戶注冊(cè)完整流程

1.2 用戶注冊(cè)信息及校驗(yàn)

2 后臺(tái)接口設(shè)計(jì)

2.1 上傳頭像接口

2.1.1 接口url

http://localhost:8081/blog/upload/user/avatar

2.1.2 請(qǐng)求類型

POST

2.1.3 接口入?yún)?/p>

參數(shù)名稱參數(shù)類型是否必傳備注
fileMultipartFile多媒體圖片文件

2.1.4 接口出參

參數(shù)名稱參數(shù)類型示例值備注
statusInteger200狀態(tài)碼:200-成功; 500-失敗
msgString“success”響應(yīng)信息:“success”-上傳頭像成功; "upload file failed"-上傳頭像失敗
dataStringvueblog2022.oss-cn-shenzhen.aliyuncs.com/avatar/63be…上傳頭像成功后的下載地址

2.2 用戶注冊(cè)接口

2.2.1 接口url

http://localhost:8081/blog/user/reg

2.2.2 請(qǐng)求類型

POST

2.2.3 接口入?yún)?/p>

參數(shù)名稱參數(shù)類型是否必填備注
usernameString用戶賬號(hào)
nicknameString用戶昵稱
passwordString用戶登錄密碼
userfaceString用戶頭像鏈接地址
phoneNumLong用戶手機(jī)號(hào)碼
emailString用戶郵箱地址

2.2.3 接口出參

參數(shù)名稱參數(shù)類型示例值備注
statusInteger200響應(yīng)碼: 200-成功;500-失敗
msgString注冊(cè)成功響應(yīng)消息
dataInteger0注冊(cè)成功標(biāo)識(shí):0-注冊(cè)成功;1-用戶名重復(fù); null-內(nèi)部服務(wù)異常

3 后端代碼實(shí)現(xiàn)

3.1 用戶頭像上傳接口編碼實(shí)現(xiàn)

文件上傳,這里選用了阿里云的對(duì)象存儲(chǔ),需要先開(kāi)通阿里云對(duì)象存儲(chǔ)服務(wù),關(guān)于如何開(kāi)通阿里云短信服務(wù)并將阿里云對(duì)象存儲(chǔ)服務(wù)集成到SpringBoot項(xiàng)目中,請(qǐng)參考我之前發(fā)布的文章SpringBoot項(xiàng)目集成阿里云對(duì)象存儲(chǔ)服務(wù)實(shí)現(xiàn)文件上傳

3.1.1 服務(wù)層編碼

新建OssClientService類繼承阿里云對(duì)象存儲(chǔ)服務(wù)SDK完成圖片上傳功能

@Service
public class OssClientService {

    @Resource
    private OssProperties ossProperties;

    private static final Logger logger =  LoggerFactory.getLogger(OssClientService.class);

    public String uploadFile(MultipartFile file){
        // 創(chuàng)建OSSClient實(shí)例。
        OSS ossClient = new OSSClientBuilder().build(ossProperties.getEndPoint(), ossProperties.getAccessKey(),
                ossProperties.getSecretKey());
        String uuid = UUID.randomUUID().toString().replaceAll("-", "");
        String objectName = "avatar/" + uuid + ".png";
        String imageUrl = null;
        try {
            InputStream inputStream =  file.getInputStream();  
            ossClient.putObject(ossProperties.getBucketName(), objectName, inputStream);
            imageUrl = "https://" + ossProperties.getBucketName() + "." + ossProperties.getEndPoint() + "/" + objectName;
        } catch (OSSException oe) {
            logger.error("Caught an OSSException, which means your request made it to OSS, but was rejected with an error response for some reason.");
            logger.error("Error Message:" + oe.getErrorMessage());
            logger.error("Error Code:" + oe.getErrorCode());
            logger.error("RequestId: " + oe.getRequestId());
            logger.error("Host ID:" + oe.getHostId());
        } catch (ClientException ce) {
            logger.error("Caught an ClientException, which means the client encountered a serious internal problem " +
                    "while trying to communicate with OSS,such as not being able to access the network");
            logger.error("Error Message:" + ce.getErrorMessage());
        } catch (FileNotFoundException fe) {
            logger.error("file not found exception");
            logger.error("Error Message:" + fe.getMessage(), fe);
        } catch (IOException exception){
            logger.error("file get input stream error, caused by " + exception.getMessage(), exception);
        }
        finally {
            if (ossClient!=null) {
                ossClient.shutdown();
            }
        }
        return imageUrl;
    }
}

注意:升級(jí)到3.9.1版本后的aliyun-sdk-oss需要在每次上傳文件時(shí)新建一個(gè)OSS實(shí)例, 上傳完文件之后再調(diào)用shutdown方法關(guān)閉這個(gè)實(shí)例

3.1.2 控制器層編碼

新建UploadFileController類完成從前端接收附件參數(shù),并調(diào)用OssClientService服務(wù)實(shí)現(xiàn)圖片上傳

@RestController
@RequestMapping("/upload")
public class UploadFileController {

    @Resource
    private OssClientService ossClientService;

    @PostMapping("/user/avatar")
    @ApiOperation(value = "userAvatar", notes = "用戶上傳頭像接口",
    produces = "application/octet-stream", consumes = "application/json")
    public RespBean uploadUserAvatar(HttpServletRequest request){
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
        // 獲取上傳文件對(duì)象
        MultipartFile file = multipartRequest.getFile("file");
        RespBean respBean = new RespBean();
        String downloadUrl = ossClientService.uploadFile(file);
        if (!StringUtils.isEmpty(downloadUrl)) {
            respBean.setStatus(200);
            respBean.setMsg("success");
            respBean.setData(downloadUrl);
        } else {
            respBean.setStatus(500);
            respBean.setMsg("upload file failed");
        }
        return respBean;
    }
}

3.2 用戶注冊(cè)接口

3.2.1 數(shù)據(jù)庫(kù)訪問(wèn)層編碼

UserMapper接口類中新增注冊(cè)用戶抽象方法

int registerUser(UserDTO user);

然后在UserMapper.xml文件中完成用戶數(shù)據(jù)入庫(kù)sql編寫(xiě)

<insert id="registerUser" useGeneratedKeys="true" keyProperty="id" parameterType="org.sang.pojo.dto.UserDTO">
        INSERT INTO user(username, nickname, password, phoneNum,email, userface, regTime,enabled)
        values(#{username,jdbcType=VARCHAR},#{nickname,jdbcType=VARCHAR},
        #{password,jdbcType=VARCHAR}, #{phoneNum,jdbcType=BIGINT}, #{email,jdbcType=VARCHAR},
        #{userface,jdbcType=VARCHAR},now(),1)
    </insert>

3.2.2 服務(wù)層編碼

CustomUserDetailsService接口類中添加注冊(cè)用戶抽象方法

int registerUser(UserDTO user);

然后在 CustomUserDetailsService接口類的實(shí)現(xiàn)類UserService類中完成用戶注冊(cè)邏輯

    @Override
    public int registerUser(UserDTO user) {
        // 判斷用戶是否重復(fù)注冊(cè)
        UserDTO userDTO  = userMapper.loadUserByUsername(user.getUsername());
        if (userDTO != null) {
            return 1;
        }
        //插入用戶, 插入之前先對(duì)密碼進(jìn)行加密
        user.setPassword(passwordEncoder.encode(user.getPassword()));
        user.setEnabled(1);//用戶可用
        int result = userMapper.registerUser(user);
        //配置用戶的角色,默認(rèn)都是普通用戶
        List<Integer> roleIds = Arrays.asList(2);
        int i = rolesMapper.setUserRoles(roleIds, user.getId());
        boolean b = i == roleIds.size() && result == 1;
        if (b) {
            // 注冊(cè)成功
            return 0;
        } else {
            // 注冊(cè)失敗
            return 2;
        }
    }

3.2.3 控制器層編碼

LoginRegController類中完成用戶登錄接口從前端接收參數(shù)到調(diào)用UserService服務(wù)類完成用戶注冊(cè)業(yè)務(wù)

@RequestMapping(value = "/login_page", method = RequestMethod.GET)
    @ApiOperation(value = "loginPage", notes = "尚未登錄跳轉(zhuǎn)", produces = "application/json",
            consumes = "application/json", response = RespBean.class)
    public RespBean loginPage() {
        return new RespBean(ResponseStateConstant.UN_AUTHORIZED, "尚未登錄,請(qǐng)登錄!");
    }

    @PostMapping("/user/reg")
    @ApiOperation(value = "reg", notes = "用戶注冊(cè)", produces = "application/json",
            consumes = "application/json", response = RespBean.class)
    public RespBean reg(@RequestBody UserDTO user) {
        int result = userService.registerUser(user);
        if (result == 0) {
            //成功
            return new RespBean(ResponseStateConstant.SERVER_SUCCESS, "注冊(cè)成功!");
        } else if (result == 1) {
            return new RespBean(ResponseStateConstant.DUPLICATE_ERROR, "用戶名重復(fù),注冊(cè)失敗!");
        } else {
            //失敗
            return new RespBean(ResponseStateConstant.SERVER_ERROR, "注冊(cè)失敗!");
        }
    }

由于以上兩個(gè)接口都是需要放開(kāi)權(quán)限控制的,因此完成以上兩個(gè)接口的編碼后還需要在security配置類WebSecurityConfig類中支持匿名訪問(wèn)

只需要在configure(HttpSecurity http)方法中添加如下幾行代碼即可

http.authorizeRequests()
                .antMatchers("/user/reg").anonymous()
                .antMatchers("/upload/user/avatar").anonymous()

完成后端編碼后可以啟動(dòng)Mysql服務(wù)和redis服務(wù),然后運(yùn)行BlogserverApplication類中的Main方法成功后就可以通過(guò)postman工具測(cè)試接口了

4 前端代碼實(shí)現(xiàn)

4.1 完成用戶注冊(cè)界面vue組件編碼

src/views目錄下新建register文件夾,然后在register目錄下新建index.vue文件

完成用戶注冊(cè)組件編碼

這里的文件上傳選擇了element-ui組件庫(kù)中的upload組件

<template>
    <div class="register-container">
        <el-form :model="registerModel" :rules="rules" ref="registerForm" label-width="100px" class="register-form">
            <el-form-item label="用戶賬號(hào)" prop="userAccount" required>
                <el-input 
                  v-model="registerModel.userAccount"
                  placeholder="請(qǐng)輸入用戶名"/>
            </el-form-item>
            <el-form-item label="用戶昵稱" prop="nickName" required>
                <el-input 
                  v-model="registerModel.nickName"
                  type="text"
                  placeholder="請(qǐng)輸入用戶昵稱"/>
            </el-form-item>
            <el-form-item label="登錄密碼" prop="password" required>
                <el-input 
                  v-model="registerModel.password" 
                  type="password"
                  placeholder="請(qǐng)輸入密碼"
                  suffix-icon="el-icon-lock"/>
            </el-form-item>
            <el-form-item label="確認(rèn)密碼" prop="password2" required>
                <el-input 
                  v-model="registerModel.password2"
                  type="password"
                  :show-password="false"  
                  placeholder="請(qǐng)?jiān)俅屋斎朊艽a"
                  suffix-icon="el-icon-lock" />
            </el-form-item>
            <el-form-item label="頭像">
                <el-upload class="avatar-uploader"
                    :show-file-list="false"
                    accept="image"
                    :action="uploadAvatarUrl"
                    :on-preview="previewAvatar" 
                    :before-upload="beforeAvartarUpload"
                    :on-success="handleSuccessAvatar"
                >   
                    <img v-if="avatarUrl" :src="avatarUrl" class="avatar" />
                    <div v-else class="upload-btn" >
                        <el-button>點(diǎn)擊上傳頭像</el-button>
                        <div slot="tip" class="el-upload__tip">只能上傳jpg/png文件,且不超過(guò)10M</div>
                    </div>
                </el-upload>
            </el-form-item>
            <el-form-item label="手機(jī)號(hào)" prop="phoneNum" required>
                <el-input type="tel" 
                v-model="registerModel.phoneNum"
                placeholder="請(qǐng)輸入手機(jī)號(hào)" 
                />
            </el-form-item>
            <el-form-item label="郵箱" prop="email">
                <el-input type="email" 
                v-model="registerModel.email"
                placeholder="請(qǐng)輸入你的郵箱" />
            </el-form-item>
            <el-form-item class="btn-area">
               <el-button class="submit-btn" type="primary" :loading="onLoading"  @click="handleRegister('registerForm')">提交</el-button>
               <el-button class="reset-btn" type="info" @click="resetForm('registerForm')">重置</el-button> 
            </el-form-item>
        </el-form>
    </div>
</template>

<script>
import { Message } from 'element-ui'
import { isNumber, validatePhoneNum, validatePassword, validEmail } from '@/utils/validate'
export default {
    name: 'register',
    data(){
        // 密碼校驗(yàn)器
        const passwordValidator = (rule,value, callback) =>{
            console.log(rule)
            if(!validatePassword(value)){
                callback('密碼強(qiáng)度不滿足要求,密碼必須同時(shí)包含字母、數(shù)字和特殊字符,請(qǐng)重新輸入')
            } else {
                callback()
            }
        }
        // 二次密碼校驗(yàn)器
        const password2Validator = (rule, value, callback) => {
            console.log(rule)
            const password = this.registerModel.password
            if(password!=value){
                callback(new Error('兩次輸入的密碼不一致'))
            } else {
                callback()
            }
        }
        // 手機(jī)號(hào)碼校驗(yàn)器
       const  phoneNumValidator = (rule, value, callback)=> {
             console.log(rule)
            if(!(value.length==11 && isNumber(value))){
                callback(new Error('手機(jī)號(hào)碼必須是11位數(shù)字'))
            } else if(!validatePhoneNum(parseInt(value))){
                callback(new Error('手機(jī)號(hào)碼不合法'))
            } else {
                callback()
            }
       }
       // 郵件地址校驗(yàn)器
       const emailValidator = (rule, value, callback) => {
          console.log(rule)
          if(value!='' && !validEmail(value)){
             callback(new Error('郵箱地址不合法'))
          } else {
            callback()
          }
       }
        // 區(qū)分本地開(kāi)發(fā)環(huán)境和生產(chǎn)環(huán)境
       let uploadAvatarUrl = ''
       if(window.location.host='localhost'){
           uploadAvatarUrl = 'http://localhost:8081/blog/upload/user/avatar'
       } else {
          uploadAvatarUrl = 'http://www.javahsf.club:8081/blog/upload/user/avatar'
       }
        return {
            uploadAvatarUrl: uploadAvatarUrl,
            registerModel: {
                userAccount: '',
                nickName: '',
                password: '',
                password2: '',
                avatarSize: 32,
                uploadUrl: uploadUrl,
                phoneNum: '',
                email: ''
            },
            onLoading: false,
            avatarUrl: '',
            password2Style: {
                dispaly: 'none',
                color: 'red'
            },
            // 表單校驗(yàn)規(guī)則
            rules: {
                userAccount: [
                    { required: true, message: '請(qǐng)輸入用戶賬號(hào)', trigger: 'blur' },
                    { min: 2, max: 64, message: '2-64個(gè)字符', trigger: 'blur' }
                ],
                nickName: [
                    { required: true, message: '請(qǐng)輸入昵稱',  trigger: 'blur' },
                    { min: 2, max: 64, message: '長(zhǎng)度控制在2-64個(gè)字符',trigger: 'blur' }
                ],
                password: [
                    { required: true, message: '請(qǐng)輸入密碼', trigger: 'blur' },
                    { min: 6, max: 18, message: '長(zhǎng)度控制在6-18個(gè)字符', trigger: 'blur' },
                    { validator: passwordValidator, trigger: 'blur' }
                ],
                password2: [
                    { required: true, message: '請(qǐng)?jiān)俅屋斎朊艽a', trigger: 'blur' },
                    { min: 6, max: 18, message: '長(zhǎng)度控制在6-18個(gè)字符', trigger: 'blur' },
                    { validator: password2Validator, trigger: 'blur' }
                ],
                phoneNum: [
                    { required: true, message: '請(qǐng)輸入手機(jī)號(hào)',  trigger: 'blur'},
                    { validator: phoneNumValidator, trigger: 'blur' }
                ],
                email: [
                    { min: 0, max: 64, message: '長(zhǎng)度控制在64個(gè)字符'},
                    { validator: emailValidator, trigger: 'blur' }
                ]

            },
            redirect: undefined
        }
    },
    watch: {
        $route: {
            handler: function(route) {
                const query = route.query
                if (query) {
                this.redirect = query.redirect
                this.otherQuery = this.getOtherQuery(query)
                }
            },
            immediate: true
        }
   },
    methods: {   
        // 圖片上傳之前校驗(yàn)圖片格式和附件大小
        beforeAvartarUpload(file) {
           console.log(file)
           if(!(file.type=='image/jpeg' ||file.type=='image/png')){
              Message.error('頭像圖片必須是jpg或png格式')  
           }else if(file.size/(1024*1024)>10){
              Message.error('圖片大小不能超過(guò)10M')
           }
        },
        // 上傳圖片預(yù)覽
        previewAvatar(file){
            console.log(file)
        },
        // 圖片上傳成功回調(diào)
        handleSuccessAvatar(response){
           console.log(response.data)
           this.avatarUrl = response.data
        },
        // 提交注冊(cè)
        handleRegister(formName){
            this.$refs[formName].validate((valid=>{
                if(valid){ // 表單校驗(yàn)通過(guò)
                    const params = {
                        username: this.registerModel.userAccount,
                        nickname: this.registerModel.nickName,
                        password: this.registerModel.password,
                        phoneNum: this.registerModel.phoneNum,
                        email: this.registerModel.email,
                        userface: this.avatarUrl
                   }
                    this.onLoading = true
                    this.$store.dispatch('user/register', params).then(res=>{
                        this.onLoading = true
                        if(res.status===200){
                            Message.success('恭喜注冊(cè)成功,現(xiàn)在就可以登錄系統(tǒng)了!')
                            // 跳轉(zhuǎn)到登錄界面
                            this.$router.push({ path: '/login', query: this.otherQuery })
                        } else {
                            Message.error(res.msg)
                        }
                    })
                }else{  // 表單校驗(yàn)不通過(guò),拒絕提交注冊(cè)
                    this.onLoading = true
                    Message.error('用戶注冊(cè)信息校驗(yàn)不通過(guò),請(qǐng)重新填寫(xiě)注冊(cè)信息')
                    return false
                }
            }))
        },
        // 表單重置
        resetForm(formName) {
          this.$refs[formName].resetFields()
        },
        getOtherQuery(query) {
            return Object.keys(query).reduce((acc, cur) => {
                if (cur !== 'redirect') {
                acc[cur] = query[cur]
                }
                return acc
            }, {})
        }
    }
}
</script>
<!--頁(yè)面樣式-->
<style lang="scss" scoped>
    .register-container{
        margin-top: 100px;
        margin-left: 10%;
        .el-input{
            width: 60%;
        }
        .avatar-uploader .avatar{
            width: 240px;
            height: 240px;
        }
        .el-button.submit-btn{
            width: 10%;
            height: 40px;
            margin-left: 150px;
            margin-right: 25px;
        }
        .el-button.reset-btn{
            width: 10%;
            height: 40px;
        }
    }
</style>

4.2 工具類中增加校驗(yàn)方法

src/utils/validate.js中增加校驗(yàn)密碼和手機(jī)號(hào)碼的方法

export function validatePhoneNum(phoneNum) {
  const reg = /^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$/
  return reg.test(phoneNum)
}

export function validatePassword(password) {
  // 強(qiáng)密碼:字母+數(shù)字+特殊字符
  const reg = /^(?![a-zA-z]+$)(?!\d+$)(?![!@#$%^&*]+$)(?![a-zA-z\d]+$)(?![a-zA-z!@#$%^&*]+$)(?![\d!@#$%^&*]+$)[a-zA-Z\d!@#$%^&*]+$/
  return reg.test(password)
}

以上校驗(yàn)均使用正則表達(dá)式校驗(yàn)

4.3 API文件中添加用戶注冊(cè)方法

src/api/user.js文件中新增用戶注冊(cè)接口方法

export function register(data) {
  return request({
    url: '/user/reg',
    method: 'post',
    data
  })
}

4.4 全局方法中添加用戶注冊(cè)方法

src/store/modules/user.js 文件中的actions對(duì)象中增加用戶注冊(cè)行為方法

const actions = {
  // user register
  register({ commit }, registerInfo) {
    return new Promise((resolve, reject) => {
      register(registerInfo).then(response => {
        if (response.status === 200 && response.data.status === 200) {
          const resInfo = { status: response.status, msg: '注冊(cè)成功' }
          resolve(resInfo)
        } else {
          const resInfo = { status: response.status, msg: response.data.msg }
          resolve(resInfo)
        }
      }).catch(error => {
        console.error(error)
        reject(error)
      })
    })
  },
    // ......省略其他已有方法
}

因?yàn)橛脩糇?cè)完之后需要跳轉(zhuǎn)到登錄界面,直接在注冊(cè)頁(yè)面調(diào)用后臺(tái)用戶注冊(cè)接口成功后調(diào)用this.$router.push方法發(fā)現(xiàn)無(wú)法實(shí)現(xiàn)頁(yè)面的跳轉(zhuǎn)效果, 因此改為在vuex的全局dispatch中調(diào)用注冊(cè)接口

4.5 路由列表中添加用戶注冊(cè)組件

src/router/index.js文件的固定路由列表中添加注冊(cè)組件的路由

import Register from '@/views/register/index'

export const constantRoutes = [
  {
    id: '0',
    path: '/register',
    component: Register,
    hidden: true
  },
   //...... 省略其他路由
 ]

4.6 登錄組件中添加用戶注冊(cè)的跳轉(zhuǎn)鏈接

src/views/login/index.vue文件中的模板代碼部分的登錄按鈕標(biāo)簽下面添加如下兩行代碼

<div>
   <router-link to="/resetPass" class="forget-password">忘記密碼</router-link>
   <router-link class="register" to="/register">注冊(cè)賬號(hào)</router-link>
 </div>

同時(shí)對(duì)忘記密碼注冊(cè)賬號(hào)兩個(gè)鏈接添加樣式(忘記密碼功能尚待實(shí)現(xiàn))

<style lang="scss" scoped>
    .register, .forget-password{
        width: 20%;
        height: 35px;
        color: blue;
        margin-right: 20px;
        cursor: pointer;	
  }
</style>

4.7 路由跳轉(zhuǎn)控制中添加白名單

在路由跳轉(zhuǎn)控制文件src/permission.js文件中將注冊(cè)用戶的路由添加到白名單中

const whiteList = ['/login', '/register', '/auth-redirect'] // no redirect whitelist

如果不在白名單中加上用戶注冊(cè)的路由,你會(huì)發(fā)現(xiàn)在用戶登錄界面壓根無(wú)法跳轉(zhuǎn)到用戶注冊(cè)界面的

5 效果體驗(yàn)

在啟動(dòng)后端服務(wù)后,在vue-element-admin項(xiàng)目下通過(guò) 鼠標(biāo)右鍵->git bash進(jìn)入命令控制臺(tái)

然后輸入npm run dev 項(xiàng)目啟動(dòng)前端服務(wù)

然后在谷歌瀏覽器中輸入:http://localhost:3000/回車(chē)進(jìn)入登錄界面

點(diǎn)擊下面的【注冊(cè)賬號(hào)】鏈接就能跳轉(zhuǎn)到用【用戶注冊(cè)】頁(yè)面

填寫(xiě)好用戶注冊(cè)信息后就可以點(diǎn)擊下面的【提交】按鈕提交注冊(cè)了,注冊(cè)成功后系統(tǒng)會(huì)彈框提示用戶中注冊(cè)成功,并重新跳轉(zhuǎn)到【用戶登錄】界面

6 寫(xiě)在最后

本文演示了在spring-boot項(xiàng)目中繼承阿里云對(duì)象存儲(chǔ)sdk實(shí)現(xiàn)了圖片上傳和用戶提交登錄兩個(gè)接口的詳細(xì)實(shí)現(xiàn),同時(shí)前端使用element-ui庫(kù)中的upload組件調(diào)用后端圖片上傳接口實(shí)現(xiàn)了附件上傳功能,實(shí)現(xiàn)了一個(gè)完整的用戶登錄信息的校驗(yàn)和提交注冊(cè)及注冊(cè)成功后的頁(yè)面跳轉(zhuǎn)等功能。

相信對(duì)想要了解一個(gè)系統(tǒng)的用戶模塊是如何實(shí)現(xiàn)用戶的注冊(cè)以及注冊(cè)成功后的頁(yè)面跳轉(zhuǎn)的完整功能的是如何實(shí)現(xiàn)的讀者朋友一定會(huì)有所幫助的!

本文前后端項(xiàng)目代碼git倉(cāng)庫(kù)地址如下,對(duì)源碼感興趣的讀者朋友可以克隆到本地參考

blogserver項(xiàng)目gitee倉(cāng)庫(kù)地址

vue-element-admin項(xiàng)目gitee倉(cāng)庫(kù)地址

到此這篇關(guān)于SpringBoot項(xiàng)目整合Vue做一個(gè)完整的用戶注冊(cè)功能的文章就介紹到這了,更多相關(guān)SpringBoot項(xiàng)目整合Vue做一個(gè)完整的用戶注冊(cè)功能內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringBoot調(diào)用公共模塊的自定義注解失效的解決

    SpringBoot調(diào)用公共模塊的自定義注解失效的解決

    這篇文章主要介紹了SpringBoot調(diào)用公共模塊的自定義注解失效的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • Java內(nèi)存模型(JMM)及happens-before原理

    Java內(nèi)存模型(JMM)及happens-before原理

    這篇文章主要介紹了java內(nèi)存模型(JMM)及happens-before原理,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-04-04
  • Jenkins任務(wù)批量修改的技巧分享

    Jenkins任務(wù)批量修改的技巧分享

    這篇文章主要給大家介紹了關(guān)于Jenkins任務(wù)批量修改的一些技巧,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • 如何為Spring Cloud Gateway加上全局過(guò)濾器

    如何為Spring Cloud Gateway加上全局過(guò)濾器

    這篇文章主要介紹了如何為Spring Cloud Gateway加上全局過(guò)濾器,幫助大家更好得理解和學(xué)習(xí)使用Gateway,感興趣的朋友可以了解下
    2021-03-03
  • Springboot如何使用mybatis實(shí)現(xiàn)攔截SQL分頁(yè)

    Springboot如何使用mybatis實(shí)現(xiàn)攔截SQL分頁(yè)

    這篇文章主要介紹了Springboot使用mybatis實(shí)現(xiàn)攔截SQL分頁(yè),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-06-06
  • 淺談如何優(yōu)雅地停止Spring Boot應(yīng)用

    淺談如何優(yōu)雅地停止Spring Boot應(yīng)用

    這篇文章主要介紹了淺談如何優(yōu)雅地停止Spring Boot應(yīng)用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-05-05
  • Spring中ApplicationListener的使用解析

    Spring中ApplicationListener的使用解析

    這篇文章主要介紹了Spring中ApplicationListener的使用解析,ApplicationContext事件機(jī)制是觀察者設(shè)計(jì)模式的實(shí)現(xiàn),通過(guò)ApplicationEvent類和ApplicationListener接口,需要的朋友可以參考下
    2023-12-12
  • Java?8?Time?Api?使用方法技巧

    Java?8?Time?Api?使用方法技巧

    這篇文章主要介紹了Java?8?Time?Api?使用方法技巧,Java?8為Date和Time引入了新的API,以解決舊java.util.Date和java.util.Calendar的缺點(diǎn),更多相關(guān)內(nèi)容需要的小伙伴可以參考一下
    2022-05-05
  • Hadoop的安裝與環(huán)境搭建教程圖解

    Hadoop的安裝與環(huán)境搭建教程圖解

    這篇文章主要介紹了Hadoop的安裝與環(huán)境搭建教程圖解,本文圖文并茂給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-06-06
  • 解決mybatis-plus3.1.1版本使用lambda表達(dá)式查詢報(bào)錯(cuò)的方法

    解決mybatis-plus3.1.1版本使用lambda表達(dá)式查詢報(bào)錯(cuò)的方法

    這篇文章主要介紹了解決mybatis-plus3.1.1版本使用lambda表達(dá)式查詢報(bào)錯(cuò)的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08

最新評(píng)論