主要知识点:

1.使用vuex/store管理数据

2.登录注册逻辑

3.Nuxt的本地存储

1.登录页面

1.1登录页面布局

替换pages/user/login.vue的代码如下

<template>
<div class="container">
<!-- 主要内容 -->
<el-row
type="flex"
justify="center"
align="middle"
class="main"> <div class="form-wrapper">
<!-- 表单头部tab -->
<el-row type="flex" justify="center" class="tabs">
<span :class="{active: currentTab === index}"
v-for="(item, index) in [`登录`, `注册`]"
:key="index"
@click="handleChangeTab(index)">
{{item}}
</span>
</el-row> <!-- 登录功能组件 -->
<LoginForm v-if="currentTab == 0"/> <!-- 注册功能组件 -->
<!-- <RegisterForm v-if="currentTab == 1"/> -->
</div>
</el-row>
</div>
</template> <script>
import LoginForm from '@/components/user/loginForm'
export default {
components: {
LoginForm
},
data(){
return {
currentTab: 0
}
},
methods: {
handleChangeTab(index){
this.currentTab = index;
},
}
}
</script> <style scoped lang="less">
.container{
background:url(http://157.122.54.189:9095/assets/images/th03.jfif) center 0;
height: 700px;
min-width:1000px; .main{
width:1000px;
height: 100%;
margin:0 auto;
position: relative; .form-wrapper{
width:400px;
margin:0 auto;
background:#fff;
box-shadow: 2px 2px 0 rgba(0,0,0,0.1);
overflow:hidden; .tabs{
span{
display: block;
width:50%;
height: 50px;
box-sizing: border-box;
border-top:2px #eee solid;
background:#eee;
line-height: 48px;
text-align: center;
cursor: pointer;
color:#666; &.active{
color:orange;
border-top-color: orange;
background:#fff;
font-weight: bold;
}
}
}
}
}
}
</style>

pages/user/login.vue

1.2 登录功能

思路:

1.在components/user中新建loginForm.vue表单组件

2.使用Element-ui的表单组件

3.表单数据绑定

4.表单验证

5.登录接口

实现步骤:

1.新建loginForm.vue表单组建

components/user中新建loginForm.vue组件,新增内容如下

<template>
<el-form
:model="form"
ref="form"
:rules="rules"
class="form"> <el-form-item class="form-item">
<el-input
placeholder="用户名/手机">
</el-input>
</el-form-item> <el-form-item class="form-item">
<el-input
placeholder="密码"
type="password">
</el-input>
</el-form-item> <p class="form-text">
<nuxt-link to="#">忘记密码</nuxt-link>
</p> <el-button
class="submit"
type="primary"
@click="handleLoginSubmit">
登录
</el-button>
</el-form> </template> <script>
export default {
data(){
return {
// 表单数据
form: {},
// 表单规则
rules: {},
}
},
methods: {
// 提交登录
handleLoginSubmit(){
console.log(this.form)
}
}
}
</script> <style scoped lang="less">
.form{
padding:25px;
} .form-item{
margin-bottom:20px;
} .form-text{
font-size:12px;
color:#409EFF;
text-align: right;
line-height: 1;
} .submit{
width:100%;
margin-top:10px;
}
</style>

components/user/loginForm.vue

注意:新增了组件后在pages/user/login.vue中导入即可,导入位置,去除下面部分的组件的注释

<!-- 登录功能组件 -->
<!-- <LoginForm v-if="currentTab == 0"/> -->

2.表单数据绑定

修改dataform数据,然后使用v-model绑定到对应的表单字段。

编辑components/user/loginForm.vue

// 其他代码...

data(){
return {
// 表单数据
form: {
username: "", // 登录用户名/手机
password: "" // 登录密码
},
// 其他代码...
}
}, // 其他代码...

使用v-model绑定到对应的表单字段

<!-- 其他代码... -->

<el-form-item class="form-item">
<!-- 新增了v-model -->
<el-input
placeholder="用户名/手机"
v-model="form.username">
</el-input>
</el-form-item> <el-form-item class="form-item">
<!-- 新增了v-model -->
<el-input
placeholder="密码"
type="password"
v-model="form.password">
</el-input>
</el-form-item> <!-- 其他代码... -->

3.表单验证

双向数据绑定到form字段后,我们现在可以来提交表单了,但是提交之前还需要验证下表单字段是否合法,比如不能为空。

继续编辑components/user/loginForm.vue

// 其他代码...

data(){
return {
// 其他代码... // 表单规则
rules: {
username: [
{
required: true,
message: '请输入用户名',
trigger: 'blur'
},
],
password: [
{
required: true,
message: '请输入密码',
trigger: 'blur'
},
],
},
}
}, // 其他代码...

在el-form-item添加prop属性

<!-- 其他代码... -->

<!-- 新增了prop属性 -->
<el-form-item class="form-item" prop="username">
<el-input
placeholder="用户名/手机"
v-model="form.username">
</el-input>
</el-form-item> <!-- 新增了prop属性 -->
<el-form-item class="form-item" prop="password">
<el-input
placeholder="密码"
type="password"
v-model="form.password">
</el-input>
</el-form-item> <!-- 其他代码... -->

现在可以尝试在把input输入框的值清空,会出现在rules中的定义的提示内容

4.登录接口

接下来要调用登录的接口进行登录了,如果一切正常的话,我们可以看到后台返回的用户信息,如果登录失败,我们需要对统一对错误的返回进行处理,这个我们在最后再统一实现。

修改components/user/loginForm.vue的提交登录事件:

// 其他代码...

// 提交登录
methods: {
handleLoginSubmit(){
// 验证表单
this.$refs['form'].validate((valid) => {
// 为true表示没有错误
if (valid) {
this.$axios({
url: "/accounts/login",
method: "POST",
data: this.form
}).then(res => {
console.log(res.data);
})
}
})
}
} // 其他代码...

现在登录接口可以开始访问了,服务器给我们提供了测试账号密码

账号:13800138000

密码:123456

如果正常登录应该可以在控制看到打印出来的用户信息,则表示登录成功了。

5.总结

  1. components/user中新建loginForm.vue表单组件

  2. 使用Element-ui的表单组件绑定数据和验证表单

  3. 调用登录接口

2.使用store管理数据

思路:

使用vuex统一管理用户登录注册行为和用户信息。

1.在store文件夹下新建user.js

2.在store/user.js中实现登录,并保存数据到store的state中

3.在头部组建中显示用户信息

实现步骤:

新建状态文件

// 每个小仓库都必须暴露出 state, mutations

export const state = {
userInfo: {
// 用户验证的token
token: "",
// 用户信息
user: {

}

}
}

export const mutations = {
// 设置用户信息
setUserInfo(state, data){
state.userInfo = data;
}
}

在登录请求发送成功后存储用户输入的数据到vuex的store仓库中。

        // 提交登录
handleLoginSubmit(){
// 验证表单
this.$refs['form'].validate((valid)=>{
// 为true表示没有错误
if(valid){
this.$axios({
url: '/accounts/login',
method: 'POST',
data: this.form
}).then(res=>{
// 1.保存到vuex, 注意调用方法时加上命名空间,也就是方法所在的模块user
this.$store.commit('user/setUserInfo', res.data)
})
}
})
}

loginForm.vue

在页面中显示用户登录的手机号,在header.vue组件中替换下面代码。

<span class="el-dropdown-link">
<img src="http://157.122.54.189:9095/assets/images/avatar.jpg" alt="">
{{this.$store.state.user.userInfo.user.username}}
<i class="el-icon-arrow-down el-icon--right"></i>
</span>

nuxt下的store的使用

1.先新建数据的模块,一个模块就是一个文件,文件名字就是模块的名字,比如新建一个user模块,每个模块里面可以暴露出3个常用的属性

  • state
  • mutations
  • actions
// 每个小仓库都必须暴露出 state, mutations

export const state = {
userInfo: {
// 用户验证的token
token: "",
// 用户信息
user: { } }
} export const mutations = {
// 设置用户信息
setUserInfo(state, data){
state.userInfo = data;
}
}

store/user.js

2.读取user下面的用户

{{ $store.state.user.userInfo.user.username }} 

components/header.vue

3.调用mutations下的方法时候必须要带有模块名称

// 1.保存到vuex
this.$store.commit("user/setUserInfo", res.data);

components/user/loginForm.vue

把store数据保存到本地

因为这个项目是Node.js项目,所以不能使用使用localStorage方法来存储,这里需要安装一个插件解决这个本地存储问题。

插件地址:https://github.com/robinvdvleuten/vuex-persistedstate

安装依赖

安装:yarn add vuex-persistedstate

配置nuxt.config.js,在plugins中添加下面配置。

{ src: '~/plugins/localStorage.js', ssr: false }

在plugins目录中新建localStorage.js并添加如下代码。

// ~/plugins/localStorage.js

import createPersistedState from 'vuex-persistedstate'

export default ({store}) => {
window.onNuxtReady(() => {
createPersistedState({
key: 'store'
})(store)
})
}

使用一个第三方的插件vuex-persistedstate, 通过这个插件会自动把store的数据保存到本地,并且在应用加载完后会自动把本地的数据重新赋值给store。

3.判断显示页面信息

当本地保存的数据被清除后,页面中仍会显示头像,应该显示的是"登录/注册"按钮,修改成下面的代码即可。

<div>
<div v-if="!$store.state.user.userInfo.token">
<nuxt-link to="/user/login">登录 / 注册</nuxt-link>
</div>
<div v-else>
<el-dropdown>
<span class="el-dropdown-link">
<img
:src="$axios.defaults.baseURL + $store.state.user.userInfo.user.defaultAvatar"
alt
/>
{{this.$store.state.user.userInfo.user.username}}
<i
class="el-icon-arrow-down el-icon--right"
></i>
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item>个人中心</el-dropdown-item>
<el-dropdown-item>退出</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</div>

header.vue

4.退出登录

给header.vue组件中的退出按钮添加一个退出事件

<!-- 给通过native给elementUI组件绑定原生事件 -->
<el-dropdown-item @click.native="handleLogout">退出</el-dropdown-item>
  methods: {
// 退出登录,清空本地用户数据
handleLogout(){
this.$store.commit('user/clearUserInfo');
}
}

在store/user.js模块的mutations中添加一个清空数据的方法。

  // 设置用户数据为空
clearUserInfo(state){
state.userInfo = {};
}

登录成功之后跳转到首页,在loginForm.vue中添加下面代码。

// 跳转到首页
this.$router.push("/");

5.actions的使用

actions是异步的修改仓库的数据,并且依赖mutations。

mutations:用于同步修改仓库的数据。

actions:用于异步修改仓库的数据,例如登录。

将发送登录请求的代码写到actions的方法里面,方便以后维护和调用。

在store/user.js中新增actions。

// 异步修改仓库的数据
export const actions = {
// login(store, data){
login({commit}, data){
return this.$axios({
url: "/accounts/login",
method: "POST",
data:data
}).then(res => {
// store.commit("setUserInfo", res.data)
commit("setUserInfo", res.data)
// 1.保存到vuex, 注意调用方法时加上命名空间,也就是方法所在的模块user // 登录后的行为应该由调用的页面去执行,不能写死,因为每个页面登录成功执行的操作可能不一样
// this.$router.push("/"); });
}
}

loginForm.vue组件中的发送登录请求方法的代码改为:

  methods: {
// 提交登录
handleLoginSubmit() {
// 验证表单
this.$refs["form"].validate(valid => {
// 为true表示没有错误
if (valid) {
this.$store.dispatch('user/login', this.form).then(res=>{
this.$router.push('/');
})
}
});
}
}

actions总结

什么情况下把方法封装到actions?

  异步的方法需要复用的时候,可以考虑把方法封装到actions,比如登录这些方法。

actions要怎么声明?

  actions里面的方法第一个参数是store对象,这个对象下面可以访问到所有store的属性(commit, dispatch, state...)用commit修改state数据;

  第二个是可选的,是传递进来的参数。

怎么调用actions的方法?

this.$store.dispatch('user/login', this.form).then(res=>{ this.$router.push('/'); })

store总结

 什么时候使用Vuex?

  项目数据比较多,需要多个组件去共享数据的时候可以使用vuex

怎么使用?

  state: 存储数据

  mutations: 设置修改state的数据

  actions: 异步修改state的数据,把可以复用的请求放到actions里面(actions需要调用mutations的方法修改数据)

使用时候注意的问题

  单词别写错

  注意调用mutations和actions的方法记得加上模块名字(命名空间)

Nuxt.js打造旅游网站第3篇_登录页面的编写的更多相关文章

  1. Nuxt.js打造旅游网站第1篇_项目环境搭建

    1. 安装 使用官网提供的脚手架工具 create-nuxt-app,创建一个nuxtjs项目. npx create-nuxt-app xianyun 注意:在NPM版本5.2.0默认安装了npx, ...

  2. Nuxt.js打造旅游网站第2篇_首页开发

    页面效果: 1.初始化默认布局 nuxtjs提供了一个公共布局组件layouts/default.vue,该布局组件默认作用于所有页面,所以我们可以在这里加上一些公共样式,在下一小结中还会导入公共组件 ...

  3. 基于 Vue.js 2.0 酷炫自适应背景视频登录页面的设计『转』

    本文讲述如何实现拥有酷炫背景视频的登录页面,浏览器窗口随意拉伸,背景视频及前景登录组件均能完美适配,背景视频可始终铺满窗口,前景组件始终居中,视频的内容始终得到最大限度的保留,可以得到最好的视觉效果. ...

  4. 原生js+css实现重力模拟弹跳系统的登录页面

    今天小颖把之前保存的js特效视频看了一遍,跟着视频敲了敲嘻嘻,用原生js实现一个炫酷的登录页面.怎么个炫酷法呢,看看下面的图片大家就知道啦. 效果图: 不过在看代码之前呢,大家先和小颖看看css中的o ...

  5. 从壹开始前后端分离 [ vue + .netcore 补充教程 ] 二八║ Nuxt 基础:面向源码研究Nuxt.js

    前言 哈喽大家周五好,又是一个开开心心的周五了,接下来就是三天小团圆啦,这里先祝大家节日快乐咯,希望都没有加班哈哈,今天公司发了月饼,嗯~时间来不及了,上周应该搞个活动抽中几个粉丝发月饼的,下次吧,这 ...

  6. Nuxt.js开启SSR渲染快速入门

    第一节:nuxt.js相关概述 nuxt.js简单的说是Vue.js的通用框架,最常用的就是用来作SSR(服务器端渲染).Vue.js是开发SPA(单页应用)的,Nuxt.js这个框架,用Vue开发多 ...

  7. Nuxt.js入门学习

    Nuxt.js简单的说是Vue.js的通用框架,最常用的就是用来作SSR(服务器端渲染).再直白点说,就是Vue.js原来是开发SPA(单页应用)的,但是随着技术的普及,很多人想用Vue开发多页应用, ...

  8. Nuxt.js 基础入门教程

    原文链接 Vue 开发一个单页面应用,相信很多前端工程师都已经学会了,但是单页面应用有一个致命的缺点,就是 SEO 极不友好.除非,vue 能在服务端渲染(ssr)并直接返回已经渲染好的页面,而并非只 ...

  9. 原生js验证简洁美观注册登录页面

    序 一个以js验证表单的简洁的注册登录页面,不多说直接上图 效果 主要文件 完整代码 sign_up.html 注册表单 <!DOCTYPE html> <html lang=&qu ...

随机推荐

  1. PHP苹果推送实现(APNS)

    以下资料网上收集整理得来 1.在ios dev center制作相关证书和文件用客户端实现(不再赘述,网上很多,) 网上教程: http://blog.csdn.net/lizhenning87/ar ...

  2. wsgi Python的WEB框架

    Bottle是一个快速.简洁.轻量级的基于WSIG的微型Web框架,此框架只由一个 .py 文件,除了Python的标准库外,其不依赖任何其他模块. pip install bottle easy_i ...

  3. 异步 I/O 和事件驱动

    异步IO(asynchronous I/O) 首先来理解几个容易混淆的概念,阻塞IO(blocking I/O)和非阻塞IO(non-blocking I/O),同步IO(synchronous I/ ...

  4. netbeans7.4 在项目内查找 快捷键 ctrl shift f

  5. 【CODEVS】2833 奇怪的梦境

    2833 奇怪的梦境 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description Aiden陷入了一个奇怪的梦境:他被困在一个小房子中,墙上有很 ...

  6. 导出excel表

    <?phppublic function export(){          #提现状态               $status = isset($_REQUEST['status'])? ...

  7. WPF 触发器例子

    WPF的触发器很强大,这里简单附上触发器的一个小例子,分别用XMAL和CS代码来实现一个功能,鼠标悬停在button上时改变字体颜色 1.XMAL代码如下: <Window x:Class=&q ...

  8. FatMouse' Trade (贪心)

    #include <iostream> #include <stdio.h> #include <cstring> #include <cmath> # ...

  9. C++学习笔记----3.2 C++引用在本质上是什么,它和指针到底有什么区别

    从概念上讲.指针从本质上讲就是存放变量地址的一个变量,在逻辑上是独立的,它可以被改变,包括其所指向的地址的改变和其指向的地址中所存放的数据的改变. 而引用是一个别名,它在逻辑上不是独立的,它的存在具有 ...

  10. java 2类与对象[学堂在线]

    java的面向对象方法和特征(略) 累的声明格式 语法:先定义一个引用变量名 穿件对象 new aclock=new CLock() 没有ststaic 就是实例变量 类变量static 类变量 方法 ...