前端小白也能开发vue电商项目(1) 注册与登录

image
   作为前端的初学者,学一个前端框架是必不可少的。因为对于新手而言,VUE相较于REACT更容易上手,所以作者选择
了VUE。如果你正好也想学一个框架,那你走运了哦。跟着作者一起来发开发一个简单的电商项目,来学习VUE吧!

这是一个基于 vue & axios & mock & token & stylus & Cube-UI的电商项目demo,面向 vue 初学者,场景虽简单,但五脏俱全。涵盖非常多的vue及其相关技术的基本操作。有详细的注释,帮助大家快速上手 vue 。且我整理了一些在vue开发过程中,有可能会用到的技术文章,希望大家能在这些前辈们身上有所收获。

当然如果您觉得这篇文章or这个项目对您的学习有所帮助,请不吝点个star鼓励一下,当然如果存在问题,也非常希望您能跟我留言,一起学习,共同进步。

Github地址

image

项目技术栈

  • 前台:vue & vue-router & vuex & vue-cli(webpack) & Cube-UI
  • 后台:mock(用mock写模拟api)
  • 前后台交互:axios
  • 单点登录:token

学习VUE项目开发推荐阅读

此处有引用大佬赢弱小金鱼的博客文章

  1. vue-cli 生成项目主体框架
  2. vue 全家桶
  3. axios前后台交互

    vue 和 node 的交互还是主要采用 ajax 来进行,此处就介绍一个主流交互工具 axios,当然别的工具例如 vue-resource、jquery 都可以。但是 vue-resource 不维护了,jquery如果只是为了 ajax 就引入又太庞大,所以我个人是比较推荐axios
    - axios全攻略-大佬小金鱼写的

  4. token
  5. 模拟后端mock

    Mock.js 是一款模拟数据生成器,旨在帮助前端攻城师独立于后端进行开发,帮助编写单元测试。提供了以下模拟功能:根据数据模板生成模拟数据,模拟 Ajax 请求,生成并返回模拟数据,基于 HTML 模板生成模拟数据

  6. 来自滴滴的CUBE-UI

    随着 vue 的不断发展,社区越来越活跃,因此产生了许多组件库。由于滴滴的这个组件没有停止更新和维护,特别适合开发上线项目,所以我们这里选择Cube-UI。
    - Cube-UI文档


正文部分

  学了那么多文章,一定进步不少吧。让我们来进行实战开发,进行应用。一起来吧,先苦后甜!

项目结构

image

引入Cube-UI并使用

 npm install cube-ui --save

安装后会自动出现cube-ui.js

import Vue from 'vue'
import Cube from 'cube-ui'

Vue.use(Cube)

下面我们来使用它

我们来写注册页面

<template>
  <div>
      <img class="headerimg" src="https://www.baidu.com/img/bd_logo1.png" alt="">
    <cube-form
      :model="model"
      :schema="schema"
      @submit="submitHandler"
    ></cube-form>
  </div>
</template>
<script>
export default {
    data(){
        return{
            model:{//数据源
                username:'',
                password:''
            },
            schema:{//生成表单依赖的模式
                fields:[//子配置项 模式用于定义表单中的各个字段,可以选择是否分组。 无分组
                //用户名配置
                    {
                        type:'input',//字段类型
                        modelKey:'username',//在表单的 model 数据源对象中所对应的 key 名字
                        label:'用户名',//字段的标签值
                        props:{
                            placeholder: '请输入用户名',
                        },
                        rules:{
                            //校验规则
                            required: true,
                            type: 'string',
                            min: 3,
                            max: 15,
                        },
                        trigger: 'blur',//如果设置为 'blur' 那么则会在离焦后校验
                        messages:{
                            required: '用户名不能为空',
                            min: '用户名不能少于三个字符',
                            max: '用户名不能超过十五个字符',
                        }
                    },
                    //密码配置
                    {
                        type:'input',//字段类型
                        modelKey:'password',//在表单的 model 数据源对象中所对应的 key 名字
                        label:'密码',//字段的标签值
                        props:{
                            placeholder: '请输入密码',
                            type:'password',
                            eye:{
                                open: false,
                            }
                        },
                        rules:{
                            required:true,
                        },
                        trigger: 'blur',
                    },
                    {
                        type:'submit',
                        label: '注册'
                    }
                ]
            }
        }
    },

这个是注册页面的UI代码,我们引用组件中的cube-form表单,对它输入的值进行规则限定与验证,如果还不懂可以看看前面作者发的cube-ui文档哦,里面有详细介绍,也可以去GitHub下载demo,自己操作试试。 登陆页面也类似,我就不赘述啦~

用mock写模拟api

作为一个前端开发人员,在后端没有提供接口的情况下,自己编写模拟接口,对项目功能进行测试是十分重要的一项技能。拥有这项技能,将不会影响整个项目的开发进度。下面我们一起来编写。

我在vue.config.js对vue的配置文件中写啦,注册与登陆的接口,并编写了模拟数据,代码如下:

module.exports = {
  configureWebpack: {
    devServer: {
      port: 8080, //端口号
      open: true, //自动打开浏览器
      //mock 接口编写的地方 //假数据 //每次做更改配置文件时,都必须重启项目才会生效
      before(app) {
        //     app.get('请求地址',(req,res) =>{
        //         res.json({
        //             xinxi
        //         })
        // })
        //注册接口
        //用户信息池
        let userpoor = [{
            username: 'xxyang',
            password: '123456'
          },
          {
            username: 'liuqiangdong',
            password: '888888'
          }
        ]
        //注册接口
        app.get('/api/register', (req, res) => {
          const {
            username,
            password
          } = req.query
          const userlength = userpoor.filter(v => v.username == username).length //过滤 查找是否存在用户名
          if (userlength > 0) {
            res.json({
              success: false,
              message: '用户名已存在'
            })
          } else {
            res.json({
              success: true,
              message: '注册成功'
            })
          }
        })
        //登陆接口
        let tokenkey = 'xdclass'
        app.get('/api/login', (req, res) => {
          const {
            username,
            password
          } = req.query
          if (username == 'xxyang' && password == '123456' || username == 'liudongqiang' && password == '123456') {
            res.json({
              code: 0,
              message: '登陆成功',
              token: tokenkey + '-' + username + '-' + (new Date().getTime() + 60 * 60 * 1000) //token过期时间1个小时
            })
          } else {
            res.json({
              code: 1,
              message: '账号或密码错误'
            })
          }
        })
      }
    }
  },

  css: {
    loaderOptions: {
      stylus: {
        'resolve url': true,
        'import': [
          './src/theme'
        ]
      }
    }
  },

  pluginOptions: {
    'cube-ui': {
      postCompile: true,
      theme: true
    }
  }
}

以上代码中作者有详细注释,烦请不懂的话自行看一下。我解释下这一句代码:

const userlength = userpoor.filter(v => v.username == username).length //过滤 查找是否存在用户名

用filter过滤方法将输入的用户账号和已有的账号进行对比,如果相同则会返回true。这时就会获得userpoor的这条用户账号,此时长度大于零,所以输出false,提示用户已存在。

用token加密并储存密码

不知各位小伙伴知不知道,每年都要大量用户的信息泄露,例如CSDN以前被黑客攻击泄露了,几百万条用户信息,而且用户密码是明文的。这个时间爆发,让CSDN受到了,很大的影响。可想而知,对密码进行加密是十分重要的。token可以对密码进行加密,下面请看这个demo密码加密后的图片:

image

如图所示对密码进行了加密,而且加了头部xdclass进一步简单加密。而且我们储存在本地浏览器中了,避免在短时间内要多次登陆。下面我们来看代码吧。

登陆接口

 //登陆接口
        let tokenkey = 'xdclass'
        app.get('/api/login', (req, res) => {
          const {
            username,
            password
          } = req.query
          if (username == 'xxyang' && password == '123456' || username == 'liudongqiang' && password == '123456') {
            res.json({
              code: 0,
              message: '登陆成功',
              token: tokenkey + '-' + username + '-' + (new Date().getTime() + 60 * 60 * 1000) //token过期时间1个小时
            })
          } else {
            res.json({
              code: 1,
              message: '账号或密码错误'
            })
          }
        })

这里我们对token进行了头部加密,和设置了token的有效时间为一个小时,一个小时内,用户不用重新登陆。

用VUEX将token储存在本地

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    token: ''
  },
  mutations: {
    //设置vuex的token
    settoken(state,token){
      state.token=token
    }
  },
  actions: {
  },
  modules: {
  },
  getters:{

  }
})

调用API返回并储存token

methods: {
        async submitHandler(e) {
            e.preventDefault()
            try{
                const result = await this.$http.get('/api/login',{params:this.model})
                // console.log(result.data.token)
                if(result.code == '0'){
                    // alert(result.data.message)
                    this.$store.commit('settoken', result.token)
                    window.localStorage.setItem('token', result.token)
                    this.$router.replace({path:'/botnav/index'})
                }else{
                    alert(result.message)
                }
            }catch(err){
                console.log(err)
            }
        },

判断账号密码是否正确,如果正确本地保存token,并且跳转路由到首页。

用axios进行拦截

前面有提到axios是用来进行前后台交互的,起一个中间件的作用,为服务器端处理了一些事情,可以减轻服务器的压力。我们之前有给token设置了一个有效时间,过期了怎么办,改进行什么操作呢,这时候我们的axios出现啦!

我们用axios去对http进行全局拦截,并把token放在头部,每次请求有返回的都是先经过拦截器的。如果登陆过期,需要重新登陆并清空vuex和localstorage 的token,而且会跳转到login页面。话不多说,我们上代码:

import axios from 'axios'
import store from './store'
import router from './router'


//http 全局拦截
//token 要放在我们请求的header上面带回去给反馈

export default function sexAxios() {
    axios.interceptors.request.use(
        config => {
            if(store.state.token){
                config.headers.token = store.state.token
            }
            return config
        }
    )
        //每次请求有返回的都是先经过拦截器的
    axios.interceptors.response.use(
        response => {
            if(response.status == 200){
                const data = response.data
                if(data.code == -1){
                    //登陆过期 需要重新登陆 清空vuex和localstorage 的token
                    store.commit('settoken','')
                    localStorage.removeItem('token')
                    //跳转到login页面
                    router.replace({path:'/login'})
                }
                return data
            }
            return response
        }
    )
}

这里作者就不做过多解释,业务逻辑理清楚啦,有问题的小伙伴可以给我留言或者私信。


写在后面

引用小金鱼的一句话,当然纸上学来终觉浅,绝知此事要躬行。学完理论就需要去实践,大家看完之后一定要自己去操作一下,不然似懂非懂,第二天就忘啦。在此作者再次附上GitHub的地址vue-jingdong (不要吝惜你的小星星哦)。这是一个系列文章,未完待续,期待与你一起学习。如果对你有帮助的话,不妨送上你的star,送人玫瑰,手留余香,谢谢!

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,504评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,434评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,089评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,378评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,472评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,506评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,519评论 3 413
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,292评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,738评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,022评论 2 329
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,194评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,873评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,536评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,162评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,413评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,075评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,080评论 2 352

推荐阅读更多精彩内容

  • 此文项目代码:https://github.com/bei-yang/I-want-to-be-an-archit...
    LM林慕阅读 366评论 0 2
  • 基于Vue的一些资料 内容 UI组件 开发框架 实用库 服务端 辅助工具 应用实例 Demo示例 element★...
    尝了又尝阅读 1,146评论 0 1
  • 好种子开花: 昨天的种子实践日记得到两个同修的赞赏,哇塞好开心啊,随喜赞叹她们的慷慨大方,愿金钱可以千倍万倍的回流...
    田圆0618阅读 212评论 0 2
  • 避免沉迷任务的及时反馈 无数脑科学的研究发现,“反馈”是决定我们能否坚持做一件事情的重要因素。比如,使用电脑时,我...
    鷇音bird阅读 175评论 0 0
  • 这里没有玫瑰花 有阳光有雨水有草地 可是却没有人种玫瑰花 你看到的是百花齐放 蜜蜂忙碌采蜜 我却看到残骸遍地 苍蝇...
    剪窗姑娘阅读 415评论 2 5