小白学 VUE 系列vue cli 制作登录注册页面
附件下载
本文目录
vue cli 登录注册实例步骤
本文采用 vue cli 4
版本,vue2.6版本
- 1.安装脚手架(忽略)
- 2.创建项目
- 3.安装依赖包
- 4.部署
vuex
数据 - 5.编写接口数据,本地采用
mock.js
模拟数据 - 6.封装
axios
请求 - 7.编写接口请求方法
- 8.编写
vuex
异步接口逻辑 - 9.辅助方法
- 10.制作页面编写逻辑实现整个流程
2.vue cli 登录注册创建项目
vue create login
按 空格键
进行选择,然后 回车
下一步
选择2.x
,路由本地选择history
Vue CLI v4.5.12
? Please pick a preset: Manually select features
? Check the features needed for your project: Choose Vue version, Babel, Router, Vuex, CSS Pre-processors
? Choose a version of Vue.js that you want to start the project with 2.x
? Use history mode for router? (Requires proper server setup for index fallback in production) Yes
? Pick a CSS pre-processor (PostCSS, Autoprefixer and CSS Modules are supported by default): Less
? Where do you prefer placing config for Babel, ESLint, etc.? In package.json
? Save this as a preset for future projects? Yes
? Save preset as: vue2.xNoCodeCheck
静候等待安装完毕。
提示这样就表示安装完毕了。
3. 安装依赖包
这里需要用到axios
,mock
,所以进行执行如下代码
npm install axios
npm install --save-dev mockjs
--save-dev 表示开发时候用到的依赖,正式环境不需要加载依赖包。
4.部署 vuex
数据
我们登录注册功能,主要分了以下几个常用的状态:
- 1.登录状态
isLogin
- 2.登录接口
token
- 3.会员昵称
nickname
- 4.会员id
userId
- 5.会员对象信息:
userInfo
除了登录状态外,我们还需要请求后端数据,所以需要使用到
mutations
,actions
方法。我们先分析异步接口:
- 1.注册动作
register
- 2.登录动作
login
- 3.退出登录
loginOut
- 4.检验登录状态
checkLogin
分析出来了异步接口,那么异步接口需要交互状态属性更改,所以需要用到
vuex mutations
:
- 1.注册登录后状态属性更改
updateLoginRegister
- 2.退出登录属性更改
loginOutUpdate
这里我们把上述所需的功能进行编写,这里采用 vuex
的命名空间模块模式。所以新建/src/store/modules/user.js
export default {
namespaced:true,
state:{
isLogin:"",
token:"",
nickname:"",
userId:"",
userInfo:""
},
mutations:{
updateLoginRegister(state,data){
},
loginOutUpdate(state){
}
},
actions:{
register(content,data){
},
login(content,data){
},
loginOut(content,data){
},
checkLogin(content,data){
}
}
}
将其引入到 \src\store\index.js
下
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
import user from './modules/user';
export default new Vuex.Store({
modules: {
user
}
})
5.编写接口数据,本地采用 mock.js
模拟数据
我们在 src
下新建一个 api
文件夹,再新建一个 mockApi.js
、config.js
文件,编写 vuex
里面的4个 actions
接口请求。
config.js,这个主要用来配置接口配置信息。例如:
export const BASE_URL="http://api.kq.com/api/v1";
mockApi.js 主要是拦截接口地址,进行本地测试。
const Mock = require('mockjs');
import {BASE_URL} from './config';
//登录
var login = function (options) {
let params = JSON.parse(options.body);
if (!params.account) {
return {
code: 1,
msg: "账号不能为空"
}
}
if (!params.password) {
return {
code: 1,
msg: "密码不能为空"
}
}
let users = localStorage.getItem("users");
if (!users) {
return {
code: 1,
msg: "请先注册"
}
}
let data = null;
users = JSON.parse(users);
for (let item in users) {
if (users[item].account == params.account && users[item].password == params.password) {
data = users[item];
break;
}
}
if (data) {
return {
code: 200,
msg: "登录成功",
data: data
}
}
return {
code: 1,
msg: "登录失败"
}
};
//注册
var register = function (options) {
let params = JSON.parse(options.body);
if (!params.account) {
return {
code: 1,
msg: "账号不能为空"
}
}
if (!params.name) {
return {
code: 1,
msg: "昵称不能为空"
}
}
if (!params.password) {
return {
code: 1,
msg: "密码不能为空"
}
}
let users = localStorage.getItem("users");
if (!users) {
users = {};
} else {
users = JSON.parse(users);
}
if (users[params.account]) {
return {
code: 1,
msg: "已经被注册了"
}
}
let data = {
name: params.name,
account: params.account,
id: Object.keys(users).length + 1,
token: (new Date()).getTime(),
password: params.password
}
users[params.account] = data;
localStorage.setItem('users', JSON.stringify(users));
data.password = "";
return {
code: 200,
msg: "注册成功",
data: data
}
}
//账号信息
var userInfo = function (options) {
let params = JSON.parse(options.body);
let users = localStorage.getItem("users");
if (!users) {
return {
code: 1,
msg: "还没有登录"
}
}
users = JSON.parse(users);
let data = null;
for (let item in users) {
if (users[item].token == params.api_token) {
data = users[item];
break;
}
}
if (data) {
return {
code: 200,
msg: "登录成功",
data: data
}
}
return {
code: 1,
msg: "还没有登录"
}
}
//注册拦截
Mock.mock(BASE_URL + '/register', 'post', register);
//登录拦截
Mock.mock(BASE_URL + '/login', 'post', login);
//检验和获取用户信息拦截
Mock.mock(BASE_URL + '/user', 'post', userInfo);
在 login/src/main.js
引入
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
Vue.config.productionTip = false;
import './api/mockApi.js' //引入mock
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
6.封装 axios
请求
新建login/src/assets/js/request.js
import Axios from 'axios';
import {BASE_URL} from '../../api/config';
export function post(url, data, _config) {
let config = {
method: "post",
url: url,
data: data
};
//合并参数
Object.assign(config, _config);
return request(config);
}
export function get(url, data, _config) {
let config = {
method: "get",
url: url,
data: data
};
//合并参数
Object.assign(config, _config);
return request(config);
}
export function request(_config) {
var req = Axios.create({
baseURL: BASE_URL
});
req.interceptors.request.use(function (config) {
// 在发送请求之前做些什么Authorization
//判断是否登录,登录就注入token
let token = localStorage.getItem("token");
if (token) {
if (!config.data) {
let data = {
"api_token": token
}
config.data = JSON.stringify(data);
} else {
config.data.api_token = token;
}
}
return config;
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error);
});
req.interceptors.response.use(function (response) {
// 对响应数据做点什么
return response;
}, function (error) {
// 对响应错误做点什么
return Promise.reject(error);
});
return req.request(_config)
}
export default {
post,
get,
request
}
在 src/main.js
引入到全局
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import './api/mockApi.js' //引入mock
import request from './assets/js/request.js'
Vue.config.productionTip = false;
Vue.prototype.$request=request;
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
7.编写接口请求方法
新建/src/api/user/index.js
import request from '../../assets/js/request'
//登录
export function login(account,password) {
return request.post('login',{
type:"h5",
account,password
})
}
//注册
export function register(name,account,password) {
return request.post('register',{
type:"h5",
name, account,password
})
}
//个人信息
export function info() {
return request.post("user")
}
//个人信息
export function loginOut() {
return request.post("loginOut")
}
8.编写 vuex
异步接口逻辑
import {info, login, register, loginOut} from "../../api/user/index";
export default {
namespaced: true,
state: {
isLogin: localStorage.getItem("isLogin") || false,
token: localStorage.getItem("token") || "",
nickname: localStorage.getItem("nickname") || "",
userId: localStorage.getItem("userId") || "",
userInfo: localStorage.getItem("userId") ? JSON.parse(localStorage.getItem("userId")) : {}
},
mutations: {
updateLoginRegister(state, data) {
state.isLogin = true;
state.token = data.token;
state.nickname = data.name;
state.userId = data.id;
localStorage.setItem("isLogin", true);
localStorage.setItem("token", data.token);
localStorage.setItem("nickname", data.name);
localStorage.setItem("userId", data.id);
localStorage.setItem("userInfo", JSON.stringify(data));
},
loginOutUpdate(state) {
state.isLogin = false;
state.token = "";
state.nickname = "";
state.userId = "";
state.userInfo = "";
localStorage.removeItem("isLogin");
localStorage.removeItem("token", "");
localStorage.removeItem("nickname");
localStorage.removeItem("userId");
localStorage.removeItem("userInfo")
}
},
actions: {
register(content, data) {
console.log(data);
return register(data.username, data.account, data.password).then(res => {
//进行
if (res.data.code == 200) {
if (data.complete) {
//进行 commit
content.commit("updateLoginRegister", res.data.data)
return data.complete(res.data.data);
}
} else {
if (data.fail) {
return data.fail(res.data);
} else {
console.log('我出发了');
return alert(res.data.msg)
}
}
});
},
login(content, data) {
return login(data.account, data.password).then(res => {
if (res.data.code == 200) {
if (data.complete) {
//进行 commit
content.commit("updateLoginRegister", res.data.data)
return data.complete(res.data.data);
}
} else {
if (data.fail) {
return data.fail(res.data);
} else {
return alert(res.data.msg)
}
}
});
},
loginOut(content, data) {
return loginOut().then(res => {
if (res.data.code == 200) {
if (data.complete) {
content.commit("loginOutUpdate")
return data.complete(res.data);
}
} else {
if (data.fail) {
return data.fail(res.data);
} else {
return alert(res.data.msg)
}
}
});
},
checkLogin(content, data) {
return info().then(res => {
if (res.data.code != 200) {
if (data.complete) {
return data.complete();
}
}
})
}
}
}
9.辅助方法
比如检验登录,这个写到辅助函数里面,方便我们快速调用。新建/src/assets/js/function.js
export function checkLogin(_this){
_this.$store.dispatch('user/checkLogin',{
complete:()=>{
_this.$store.commit("user/loginOut");
_this.$router.replace("/login")
}
});
}
10.制作页面编写逻辑实现整个流程
创建页面:
- 1.登录页面
- 2.注册页面
- 3.会员中心
Login.vue
<template>
<div class="about">
<h1>登录</h1>
<input type="text" v-model="username" placeholder="请输入账号"><br/>
<input type="text" v-model="password" placeholder="请输入密码"><br/>
<button type="button" @click="submit">登录</button>
</div>
</template>
<script>
import {mapActions} from 'vuex';
export default {
name: 'Login',
data(){
return {
username:"",
password:""
}
},
methods:{
...mapActions({
login:'user/login'
}),
async submit(){
if(!this.username){
alert('请输入账号');
return false;
}
if(!this.password){
alert('请输入密码');
return false;
}
this.login({ account:this.username,password:this.password,complete:res=>{
this.$router.replace("/user")
}});
}
}
}
</script>
<style scoped lang="less">
input{
line-height: 30px;
margin-bottom: 10px;
outline: none;
}
</style>
Register.vue
<template>
<div class="about">
<h1>注册</h1>
<input type="text" v-model="username" placeholder="请输入昵称"><br/>
<input type="text" v-model="account" placeholder="请输入账号"><br/>
<input type="text" v-model="password" placeholder="请输入密码"><br/>
<button type="button" @click="submit">注册</button>
</div>
</template>
<script>
import {mapActions} from 'vuex';
export default {
name: 'Register',
data(){
return {
username:"",
account:"",
password:""
}
},
methods:{
...mapActions({
register:"user/register"
}),
submit(){
if(!this.username){
alert('请输入昵称');
return false;
}
if(!this.account){
alert('请输入账号');
return false;
}
if(!this.password){
alert('请输入密码');
return false;
}
this.register({
username:this.username,account:this.account,password:this.password,complete:res=>{
this.$router.replace("/user");
}
});
}
}
}
</script>
<style scoped lang="less">
input{
line-height: 30px;
margin-bottom: 10px;
outline: none;
}
</style>
User.vue
<template>
<div class="home">
个人主页
<br/>
昵称:{{ this.$store.state.user.nickname}}
<br/>
ID:{{ this.$store.state.user.userId }}
</div>
</template>
<script>
import {checkLogin} from "../assets/js/function";
export default {
name: 'User',
data() {
return {
username: "",
userId: ""
}
},
created(){
checkLogin(this);
},
methods: {}
}
</script>
login/src/App.vue
<template>
<div id="app">
<div id="nav">
<router-link to="/">首页</router-link>
|
<template v-if="$store.state.user.isLogin==false">
<router-link to="/register">注册</router-link>
|
<router-link to="/login">登录</router-link>
</template>
<template v-else>
<router-link to="/user">个人中心</router-link>
|
<a href="javascript:void(0)" @click="loginOut" class="">退出登录</a>
</template>
</div>
<router-view/>
</div>
</template>
<script>
import {mapActions} from 'vuex';
export default {
name: 'home',
data() {
return {}
},
created(){
console.log
},
methods: {
...mapActions({
loginOut2: "user/loginOut"
}),
loginOut() {
this.loginOut2({
complete: () => {
this.$router.replace("/login");
}
})
}
}
}
</script>
<style lang="less">
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}
#nav {
padding: 30px;
a {
font-weight: bold;
color: #2c3e50;
&.router-link-exact-active {
color: #42b983;
}
}
}
</style>
User.vue
<template>
<div class="home">
个人主页
<br/>
昵称:{{ this.$store.state.user.nickname}}
<br/>
ID:{{ this.$store.state.user.userId }}
</div>
</template>
<script>
import {checkLogin} from "../assets/js/function";
export default {
name: 'User',
data() {
return {
username: "",
userId: ""
}
},
created(){
checkLogin(this);
},
methods: {}
}
</script>
整个演示
版权提示
1.除了标识原创之外,其他可能来源于网友的分享,仅供学习使用2.如您发现侵犯了您的权利,请联系我们删除
3.转载必须带本文链接,否则你将侵权
4.关于会员或其发布的相关内容均由会员自行提供,会员依法应对其提供的任何信息承担全部责任,本站不对此承担任何法律责任