闲云旅游项目开发-(第二篇:实现登录功能,使用vuex的store管理数据)

9 篇文章 1 订阅
5 篇文章 0 订阅

目录

一 登录注册页布局

二 登录功能

1.思路

2.实现步骤

2.1 新建登录表单组件

2.2 表单数据绑定及验证

2.3 登录接口

3.总结

 

三  使用vuex/store管理数据

1.思路

2.实现步骤

2.1新建状态文件

2.2实现登录

2.3顶部组件,展示用户信息

 

四 状态持久化

1. 保存store到本地localStorage

 

2.思路

 

3.实现缓存信息到本地

3.1 安装插件

3.2 引入

3.3 导入插件

 4.总结


 

本章涉及知识点:

  • 使用vuex/store管理数据
  • 登录注册逻辑
  • Nuxt的本地存储

一 登录注册页布局

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>
export default {
    data(){
        return {
            currentTab: 0
        }
    },
    methods: {
//点击tab栏根据index切换状态
        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>

在预留的位置导入登录组件和注册组件

 

二 登录功能

1.思路

  • 在components/user 中新建 loginForm.vue 表单组件
  • 使用 Element-ui 的表单组件
  • 表单数据绑定
  • 表单验证
  • 登录接口

2.实现步骤

2.1 新建登录表单组件

在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>

 注意:新增了组件后在pages/user/login.vue 中导入,注册即可使用。

导入位置:


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

        <!-- 注册功能组件 -->
        <registerForm v-if="currentTab == 1" />

2.2 表单数据绑定及验证

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

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

编辑components/user/loginForm.vue

 data() {
    return {
      //  表单数据
      form: {
        username: "13800138000",
        password: "123456"
      },
      // 表单规则
      rules: {
        username: [
          { required: true, message: "请输入用户名", trriger: "blur" }
        ],
        password: [
          {
            required: true,
            message: "请输入密码",
            trriger: "blur"
          },
          {
            min: 6,
            message: "密码不能小于六位",
            trriger: "blur"
          }
        ]
      }
    };

使用el-form-item添加prop属性

  <el-form :model="form" ref="form" :rules="rules" class="form">
    <el-form-item class="form-item" prop="username">
      <el-input placeholder="用户名/手机" v-model="form.username" @focus="clearRules('username')"></el-input>
    </el-form-item>

    <el-form-item class="form-item" prop="password">
      <el-input
        placeholder="密码"
        type="password"
        v-model="form.password"
        @focus="clearRules('password')"
      ></el-input>
    </el-form-item>

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

2.3 登录接口

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

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

    // 提交登录
    async handleLoginSubmit() {
      // console.log(this.form);
      // 对整个表单进行验证,如果输入合法再进行发送请求
      this.$refs.form.validate(async v => {
        // console.log(v);
        if (v) {
          // console.log(this.form);
          let res = await userLogin(this.form);
          console.log(res);
          if (res.data.token) {
            this.$message.success("登录成功");
            
          }
        } else {
          this.$message.error("请输入合法内容");
        }
      });
    },

 

3.总结

  • components/user中新建loginForm.vue表单组件
  • 使用Element-ui的表单组件绑定数据和验证表单
  • 调用登录接口

 

三  使用vuex/store管理数据

1.思路

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

  1. 在 store文件夹新建user.js
  2. 在store/user.js中实现登录,并保存数据到store的state中
  3. 在头部组件中显示用户信息

2.实现步骤

2.1新建状态文件

store文件夹新建user.js,并添加以下代码

// 用户管理
export const state = () => ({
    // 采用接口返回的数据结构
    userInfo: {
        token: "",
        user: {},
    },
}) 

export const mutations = {};

export const actions = {};

2.2实现登录

登录成功将数据放到 store/user.js 中统一管理

2.3顶部组件,展示用户信息

在头部组件展示store中保存的用户数据

判断token是否存在,存在则将用户数据显示出来:头像路径需要进行处理拼接基准路径

  <!-- 如果用户存在则展示用户信息,用户数据来自store -->
        <el-dropdown v-if="userInfo.token">
          <el-row type="flex" align="middle" class="el-dropdown-link">
            <nuxt-link to="#">
              <img :src="$axios.defaults.baseURL+ userInfo.user.defaultAvatar" />
              {{userInfo.user.nickname}}
            </nuxt-link>
            <i class="el-icon-caret-bottom el-icon--right"></i>
          </el-row>
          <el-dropdown-menu slot="dropdown">

 

四 状态持久化

1. 保存store到本地localStorage

现在用户已经保存到store了,但是还有一个问题,数据是保存在变量缓存中的,如果页面一刷新,那么数据就会不见了,这样是不合理的。

所以我们需要使用localStorage实现状态持久化

  • 概念就是每当 vuex 数据发生变化, 就存放到 localStorage 里面去

  • 每当页面刷新的时候, localStorage 数据恢复到 vuex 里面

另外由于nuxtjs是运行在服务器的,不能直接在store中使用浏览器的localStorage方法,可以直接调用一个插件来实现以上的所有功能。

 

2.思路

  1. 监听数据变化, 每当登录完毕,
  2. vuex 数据发生变化,就要将数据保存到浏览器 本地 (指用户浏览器localStorage)
  3. 页面打开时, 会尝试将之前保存过的数据恢复到 vuex 当中即可

找个插件帮忙vuex-persistedstate

 

3.实现缓存信息到本地

nuxtjsstore不能直接使用浏览器的lcoalStorage方法,

而且自己写数据同步功能比较麻烦,

所以我们需要依赖一个插件vuex-persistedstate,该插件会把本地存储的数据存储到store

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

3.1 安装插件

npm install --save vuex-persistedstate

3.2 引入

需要创建一个 localStorage 自定义插件用来引入第三方包

以前我们引入第三方的插件时, 可以直接在 main.js 入口文件

的 new Vue 根实例创建之前, 添加代码,

nuxt 的机制是自定义插件,存放在 plugins 文件夹, 然后用配置进行引入

在根目录plugins中新建文件localStorage.js,加入以下代码 :


import createPersistedState from 'vuex-persistedstate'

export default ({store}) => {
    window.onNuxtReady(() => {
        createPersistedState({
            key: "store", // 读取本地存储的数据到store
        })(store)
    })
}

3.3 导入插件

修改nuxt.config.js配置文件,在plugins配置项中新增一条数据 :

// 其他代码...

plugins: [
    // 其他代码...
    // 这里的引入,如果是普通字符串,就在服务端马上运行
    // 如果是要等到浏览器再运行的代码,可以将配置改为对象,并且路径作为src传进去
    // 如果只在浏览器加载的代码, 可以添加一个 属性 ssr: false
    { src: '@/plugins/localStorage', ssr: false }
],
      
// 其他代码...

 如果只在浏览器加载的代码, 可以添加一个 属性 ssr: false

修改完后 重新启动项目 npm run dev 就可以了

 

3.4 如果不使用插件也可以实现vuex 的持久化

在default.vue页面进行store数据的管理:

 mounted() {
    // 不使用插件 实现vuex持久化
    // 如果数据有变化,存放到localstorage
    // 如果页面进入,将localStorage数据重新拿回来
    // this.$store.subscribe 可以订阅 mutations
    // 任意一个 mutations触发。都会在之后执行这个 subscribe 订阅的回调
    this.$store.subscribe((mutation, state) => {
      localStorage.setItem("vuex", JSON.stringify(state));
    });

    // 如果页面进入,将localStorage 数据重新拿回来
    // 本来所有数据的改变通过mutations
    // this.$store有一个函数例外,replaceState 传入一个数据对象即可覆盖原来的数据
    const savedState = localStorage.getItem("vuex");
    if (savedState) {
      this.$store.replaceState(JSON.parse(savedState));
    }
  }

 

 

 

 4.总结

使用vuex-persistedstate 保存vuex到本地存储

  1. 安装
  2. 创建插件文件plugins/文件夹下面
  3. 在nuxt.config.js的plugins配置里面引入插件,注意设置ssr为false
  4. 重启项目即可

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值