Vue2 + ElementUI 实现简单的功能(第三天)

 第三天任务:与后端进行请求交互,在本地写入用户信息。

与后端进行请求交互

我们现在项目目录下面创建一个 .env.development 的配置文件。

然后我们在主目录下的 src 文件夹下新建三个文件夹,名称分别为 service、store、utils:service 里面用来写向后端发送的请求体; store 里面用来处理发送前后需要处理的事情,最常见的例如存储数据;utils 用来处理请求相关。创建如图示目录文件夹及文件:

下面开始写 request.js

import axios from 'axios';
import storageService from '@/service/storageService';

const service = axios.create({
    baseURL: process.env.VUE_APP_API_BASE_URL,
    timeout: 1000 * 5,
});

// Add a request interceptor
service.interceptors.request.use(function (config) {
    // Do something before send request
    Object.assign(config.headers, { Authorization: `Bearer ${storageService.get(storageService.USER_TOKEN)}` });
    return config;
}, function (error) {
    // deal with the request error
    return Promise.reject(error);
});

export default service;

然后写 storageService ,这里选择把用户信息存到 vuex 当中,把 token 存在本地。

storageService.js

// local storage service
// your project prefix name as the storage prefix name
const PREFIX = 'Five Elements Six Gases';

// set user module 
const USER_PREFIX = `${PREFIX}user_`;
const USER_TOKEN = `${USER_PREFIX}token`;
const USER_INFO = `${USER_PREFIX}info`;

// storage
const set = (key, data) => {
    localStorage.setItem(key, data);
};

// get local storage info
const get = (key) => localStorage.getItem(key);

export default {
    set,
    get,
    USER_INFO,
    USER_TOKEN,
};

下面来写 userService.js 这里面主要是把数据封装进请求体中,例如 register 这里使用 formdata 表单封装数据。

import request from '@/utils/request';

// 用户注册
const register = ({ username, email, password }) => {
    const formData = new FormData();
    formData.append('UserName', username);
    formData.append('UserEmail', email);
    formData.append('UserPassword', password);

    return request.post('auth/register', formData, {
        headers: {
            'Content-Type': 'multipart/form-data'
        }
    });
};

// 用户登录
const login = ({ username, password }) => {
    const formData = new FormData();
    formData.append('UserName', username);
    formData.append('UserPassword', password);

    return request.post('auth/login', formData, {
        headers: {
            'Content-Type': 'multipart/form-data'
        }
    });
};

// 用户编辑
const edit = ({ UserName, UserEmail, UserPassword, NewPassword }) => {
    const formData = new FormData();
    formData.append('UserName', UserName);
    formData.append('UserEmail', UserEmail);
    formData.append('UserPassword', UserPassword);
    formData.append('NewPassword', NewPassword);
    return request.put('auth/edit', formData, {
        headers: {
            'Content-Type': 'multipart/form-data'
        }
    });
}

// 获取用户信息
const info = (headers) => {
    return request.get('auth/info', {
        headers: headers,
    });
};

export default {
    register,
    info,
    login,
    edit,
};

user.js 代码

import storageService from '@/service/storageService';

import userService from '@/service/userService';

const userModule = {
    namespaced: true,
    state: {
        token: storageService.get(storageService.USER_TOKEN),
        userInfo: null,
    },

    mutations: {
        SET_TOKEN(state, token) {
            // update local storage
            storageService.set(storageService.USER_TOKEN, token);
            // update state
            state.token = token;
        },
        SET_USERINFO(state, userInfo) {
            // update state
            state.userInfo = userInfo;
        },
    },

    actions: {
        register(context, { username, email, password }) {
            console.log("im register")
            return new Promise((resolve, reject) => {
                userService.register({ username, email, password }).then((res) => {
                    // save token
                    context.commit('SET_TOKEN', res.data.data.token);
                    return userService.info();
                }).then((res) => {
                    // save user info
                    context.commit('SET_USERINFO', res.data.data.user);
                    resolve(res);
                }).catch((err) => {
                    reject(err);
                });
            });
        },
        login(context, { username, password }) {
            console.log("im login")
            // console.log(username)
            // console.log(password)
            return new Promise((resolve, reject) => {
                userService.login({ username, password }).then((res) => {
                    // 保存 token
                    context.commit('SET_TOKEN', res.data.data.token);
                    return userService.info();
                }).then((res) => {
                    // 保存用户信息
                    context.commit('SET_USERINFO', res.data.data.user);
                    resolve(res);
                }).catch((err) => {
                    reject(err);
                });
            });
        },
        logout({ commit }) {
            // 清除 token
            commit('SET_TOKEN', '');
            storageService.set(storageService.USER_TOKEN, '')

            window.location.reload();
        },
        edit(context, { UserName, UserEmail, UserPassword, NewPassword }) {
            return new Promise((resolve, reject) => {
                // console.log('userEdit method called');
                // console.log(Response)
                userService.edit({ UserName, UserEmail, UserPassword, NewPassword }).then((res) => {
                    // 清除 token
                    // context.commit('SET_TOKEN', '');
                    // storageService.set(storageService.USER_TOKEN, '');
                    // 清除用户信息
                    console.log(res)
                    context.commit('SET_USERINFO', '');
                    storageService.set(storageService.USER_INFO, '');
                    // // 保存 token
                    return userService.info();
                    // 保存用户信息
                }).then((res) => {
                    context.commit('SET_USERINFO', res.data.data.user);
                    resolve(res);
                }).catch((err) => {
                    context.commit('SET_TOKEN', '');
                    storageService.set(storageService.USER_TOKEN, '')

                    window.location.reload();
                    reject(err);
                });
            });
        },
        async getInfo(context, state) {
            const { token } = state;
            try {
                const headers = {
                    // 在请求头中添加 token
                    Authorization: `Bearer ${token}`,
                };
                const response = await userService.info(headers);
                context.commit('SET_USERINFO', response.data.data.user);
            } catch (error) {
                // 处理请求错误  
                console.error('Request failed:', error);
                throw error;
            }
        }
    },
};

export default userModule;

在写 index.js 之前我们需要先安装 vuex 和 axios。

我们在命令行当中输入 

yarn add vuex@3
yarn add axios

index.js 代码

import Vue from 'vue';
import Vuex from 'vuex';
import UserModule from './module/user'

Vue.use(Vuex);

export default new Vuex.Store({
    state: {
    },
    getters: {
    },
    mutations: {
    },
    actions: {
    },
    modules: {
        UserModule,
    },
});

当然到现在并没有完成,还记得之前的 login 和 register 点击的事件吗?没错,这个请求的发出当然和点击对应的事件相关联。

修改main.js代码:

import Vue from 'vue'
import App from './App.vue'
import router from './router';
import axios from 'axios';
import store from './store';
import { Button, Menu, Input, MenuItem, Form, FormItem, Submenu, MessageBox, Message, Notification } from 'element-ui';

Vue.config.productionTip = false

Vue.component(Button.name, Button);
Vue.component(Menu.name, Menu);
Vue.component(MenuItem.name, MenuItem);
Vue.component(Submenu.name, Submenu);
Vue.component(Form.name, Form);
Vue.component(FormItem.name, FormItem);
Vue.component(Input.name, Input);
Vue.prototype.$msgbox = MessageBox;
Vue.prototype.$alert = MessageBox.alert;
Vue.prototype.$confirm = MessageBox.confirm;
Vue.prototype.$prompt = MessageBox.prompt;
Vue.prototype.$notify = Notification;
Vue.prototype.$message = Message;

Vue.use(axios);

new Vue({
  router,
  store,
  render: h => h(App),
}).$mount('#app')

register 部分代码:我这里与之前不同的是在 register.vue 中加入了 email 字段,

下面开始写发送请求的代码:

UserRegister.vue

<template>
  <div class="register-form">
    <el-form :model="registerForm" :rules="rules" ref="registerForm" @submit.native.prevent="handleRegister">
      <el-form-item label="用户名:" prop="username">
        <el-input v-model="registerForm.username"></el-input>
      </el-form-item>
      <el-form-item label="邮箱:" prop="email">
        <el-input v-model="registerForm.email"></el-input>
      </el-form-item>
      <el-form-item label="密码:" prop="password">
        <el-input type="password" v-model="registerForm.password"></el-input>
      </el-form-item>
      <el-form-item label="确认密码:" prop="confirmPassword">
        <el-input type="password" v-model="registerForm.confirmPassword"></el-input>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="submitForm('registerForm')">注册</el-button>
        <el-button @click="resetForm('registerForm')">返回登录</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>

<script>
import { mapActions } from 'vuex';

export default {
  data() {
    return {
      registerForm: {
        username: '',
        email: '',
        password: '',
        confirmPassword: '', // 将 confirmPassword 纳入 registerForm
      },
      rules: {
        username: [
          { required: true, message: '请输入用户名', trigger: 'blur' },
          { min: 5, max: 16, message: '长度在 5 到 16 个字符', trigger: 'blur' },
        ],
        email: [
          { required: true, message: '请输入邮箱', trigger: 'blur' },
          { type: 'email', message: '请输入正确的邮箱地址', trigger: ['blur', 'change'] },
        ],
        password: [
          { required: true, message: '请输入密码', trigger: 'blur' },
          { min: 5, max: 16, message: '长度在 5 到 16 个字符', trigger: 'blur' },
        ],
        confirmPassword: [
          { required: true, message: '请确认密码', trigger: 'blur' },
          { validator: this.validateConfirm, trigger: 'blur' },
        ],
      },
    };
  },
  methods: {
    ...mapActions('userModule', { userRegister: 'register' }),
    validateConfirm(rule, value, callback) {
      if (value !== this.registerForm.password) {
        callback(new Error('两次输入密码不一致'));
      } else {
        callback();
      }
    },
    submitForm(formName) {
      this.$refs[formName].validate((valid) => {
        if (valid) {
          // 发送注册请求
          this.userRegister(this.registerForm).then(() => {
            this.$message({
              showClose: true,
              message: '提交成功',
              type: 'success',
            });
            this.$router.replace({ name: 'Home' });
          }).catch(() => {
            this.$message({
              showClose: true,
              message: '注册请求失败',
              type: 'error',
            });
          });
        } else {
          console.log('error submit!!');
          return false;
        }
      });
    },
    resetForm(formName) {
      this.$refs[formName].resetFields();
    },
  },
};
</script>

<style scoped>
.register-form {
  width: 300px;
  margin: 100px auto;
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
}
</style>

UserLogin.vue 代码

<template>
  <div class="login-container">
    <el-form :model="loginForm" :rules="rules" ref="loginForm" label-width="100px" class="demo-ruleForm">
      <el-form-item label="用户名" prop="username">
        <el-input v-model="loginForm.username"></el-input>
      </el-form-item>
      <el-form-item label="密码" prop="password">
        <el-input type="password" v-model="loginForm.password"></el-input>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="submitForm('loginForm')">登录</el-button>
        <el-button @click="resetForm('loginForm')">重置</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>
 
<script>
import { mapActions } from 'vuex';

export default {
  data() {
    return {
      loginForm: {
        username: '',
        password: '',
      },
      rules: {
        username: [
          { required: true, message: '请输入用户名', trigger: 'blur' },
          { min: 5, max: 16, message: '长度在 5 到 16 个字符', trigger: 'blur' },
        ],
        password: [
          { required: true, message: '请输入密码', trigger: 'blur' },
          { min: 5, max: 16, message: '长度在 5 到 16 个字符', trigger: 'blur' },
        ],
      },
    };
  },
  methods: {
    ...mapActions('userModule', { userLogin: 'login' }),
    submitForm(formName) {
      this.$refs[formName].validate((valid) => {
        if (valid) {
          this.$message({
            showClose: true,
            message: '提交成功',
            type: 'success'
          });
          // 在这里你可以添加登录逻辑,比如发送请求到服务器
          console.log(this.loginForm)
          this.userLogin(this.loginForm).then(() => {
            // 跳转页面
            this.$router.replace({ name: 'Home' });
          }).catch(() => {
            this.$message({
              showClose: true,
              message: '登录请求错误',
              type: 'error'
            });
          });
          } else {
            this.$message({
              showClose: true,
              message: '提交请求失败',
              type: 'error'
            });
            return false;
          }
      });
    },
    resetForm(formName) {
      this.$refs[formName].resetFields();
    }
  }
};
</script>
 
<style scoped>
.login-container {
  width: 400px;
  margin: 200px auto;
  /* border: 1px red ridge; */
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); /* 添加的阴影效果 */
}
</style>

运行结果:
我们右击空白的地方点击检查

如果配置的和显示的结果一致那么就成功了,第三天的任务算是完成了。

后面根据本人情况再进行选择性的更。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值