第14课:开发进行时之用户中心

第14课:开发进行时之用户中心

每一个带有登录的网站,都会有用户中心。在用户中心中,不仅仅是对用户信息进行展示,实际上还有一系列的操作也属于这一模块,本文我们就来整理一下网站的用户中心。

大家已经见过了各种各样的用户中心,其最核心的内容就是对于用户信息资料的展示与修改,对于不同的网站而言,用户信息所包含的内容也都不一致。我们来一点一点的拆分这些内容。

用户的基础信息不过就是昵称、头像、生日、地址等等这些信息,关于昵称地址之类的文本内容修改,相信大家都已经掌握了,在这里我就不多说了。基础信息这块,我把头像的修改提出来进行讲解,告诉大家如何使用 Vue.js 中的 axios.js 来完成头像的上传功能。除此之外,因为很多网站在设计的时候,UI 给大家的日历样式都是各种各样的,而网上的日历插件一般都是基于 jQuery 的,所以在此给大家拓展一个 Vue.js 制作日历的方法。

图片上传

头像上传,一般有两种方式。

(1)base64

这个方法非常简单,只需要将本地图片转换为 base64,然后通过一般的请求发送到服务器就可以了。这个方法适合于小图,并且不兼容低版本的 IE 浏览器,所以具有局限性。

(2)表单提交。

想必之前你在项目中已经使用过表单提交文件,对于表单提交的原理就不做解释了。我们来看看在 Vue.js 中是如何实现的。

HTML 部分,我们都是使用一个 input 来实现的,把它的 type 设置为 file,但是我们并不想让用户看见这个 input,一般的做法是在外层设置一个元素,将 input 通过 CSS 控制让其不显示出来,然后通过点击它的父元素来触发事件。

在 input 标签中还可以添加 accept 来规定能够通过文件上传进行提交的文件类型。如果不限制图像的格式,可以写为 accept="image/*"。代码如下。

<input class="file_submit" name="file" type="file" accept="image/png,image/gif,image/jpeg" @change="submitImg()"/>

JavaScript 代码如下。

submitImg(e){
          var file = e.target.files[0];     // 我们的input对象    
          var param = new FormData(); //创建form对象
          param.append('file',file,file.name);//通过append添加数据
          var config = {
            headers:{'Content-Type':'multipart/form-data'}
          };  //添加请求头,以表单提交
          this.axios.post('请求接口',param,config)
          .then(response=>{
            console.log(response.data);
          })        
}

很多网站对于上传的图片大小会有限制 ,如果你的项目也有限制,可以通过 e.files[0].size / 1024 来进行判断,得出来的单位是 kb。

签到日历

这里介绍的日历和大家平时使用的日历存在比较大的区别,不是样式或者功能的区别,而是实现日历的方式。

首先来给大家讲解在 Vue.js 中,我们如何在不操作 DOM 的情况下完成日历,在之前的章节中我就一直强调一个问题,Vue.js 中数据是最重要的,我们这里的日历其实就是制造日历的数据,然后渲染到日历中。

日历大概长下图的样子,当然这是我在小程序中做得日历,方法也是一样的。

我们首先定义一个变量来存放日期数组,然后需要获取当前的年月,判断是否闰年,然后判断当月的第一天是星期几,然后写一个循环往数组中添加空字段,如星期一就添加一个,星期六就添加六个。添加完空字段之后就根据前面获取的月判断这个月有多少天,然后往其中循环添加每一天。如果你要在日历中展示年月这些信息,那么你也需要在 data 中定义对应的变量,你还可以定义一个 nowDay 来标记今天。代码如下。

creatDate:function(){
  var nowDate = new Date()//js获取当前事件
  var nowYear = nowDate.getFullYear()//获取当前年份
  var nowMonth = nowDate.getMonth()//获取当前月份
  var nowDay = nowDate.getDate()//获取当前是几号
  var firstDate = nowDate.setDate(1)//设置本月第一天
  firstDate = new Date(firstDate)//格式化时间
  var nowWeek = firstDate.getDay()//获取本月第一天是星期几
  var weekList = [];
  var dayList = []
  for (var i = 0; i < nowWeek;i++){
    dayList.push('')
  }
  var isDub = (nowYear % 4 == 0) && (nowYear % 100 != 0 || nowYear % 400 == 0)
  var monthList = [31, 27 + isDub,31,30,31,30,31,31,30,31,30,31]
  for (var i = 0; i < monthList[nowMonth];i++){
    dayList.push(i+1)
  }
  this.dateList=dayList;
  this.year=nowYear;
  this.month=nowMonth;
  this.nowDay=nowDay;
},

而我们的 HTML 结构则是这样:

<div class='bg'>
    <div class='header_bg'>
        <image src="../../img/headerBg.jpg" class='header_img'></image>
        <div class='header_content_box'>
            <div>累积签到</div>
        </div>
    </div>
    <div class='year_month'>{{year}}年{{month+1}}月</div>
    <div class='date_head'>
        <div v-for="item in weeks" class='weeks'>
            {{item}}
        </div>
    </div>
    <div class='date_box'>
        <div v-for="item in dateList" class="day" :class="{'now_day':item==nowDay}">
            {{item}}
        </div>
    </div>
    <div class='submit_btn'>签到</div>
    <div class='count_box'>累积签到50天丨累积获得500积分</div>
</div>

然后再加上我们的 CSS 样式:

.day{
    width: 107px;
    height: 107px;
    text-align: center;
    display: inline-block;
    line-height: 107px;
    font-size: 36px;
}
lose_day{
    color: #fff
}
.weeks{
    width: 107px;
    height: 95px;
    text-align: center;
    display: inline-block;
    line-height: 95px;
}
.now_day{
    line-height: 107px;
    width: 107px;
    height: 107px;
    text-align: center;
    display: inline-block;
    background-color: #04babe;
    color: white;
    border-radius: 50%;
}
.header_bg{
    width: 750px;
    height: 237px;
    position: relative;
}
.year_month{
    display: inline-block;
    width: 750px;
    height: 95px;
    line-height: 95px;
    text-align: center;
    background-color: white;
    margin-top: 10px;
}
.header_content_box{
    text-align: center;
    margin: 0 auto;
    z-index: 9;
}
.header_img{
    position: absolute;
    top: 0;
    left: 0;
    width: 750px;
    height: 237px;
}
.bg{
    background-color: #f2f2f2;
    height: 100vh;
}
.count_box{
    margin-top: 30px;
    width: 750px;
    height: 80px;
    text-align: center;
    font-size: 24px;
}
.date_head{
    font-size: 36px;
    margin-top: 10px;
    background-color: white;
    width: 750px;
}
.date_box{
    width: 750px;
    height: auto;
    background-color: white;
}
.submit_btn{
    margin: 20px auto 0;
    width: 220px;
    height: 60px;
    background-color: #13b7f6;
    border-radius: 10px;
    line-height: 60px;
    text-align: center;
    color: white;
}

这样我们的日历就完成了,当然这只是完成了日历的渲染,你需要签到肯定就需要给你返回一个日期,好传送给后台,或者说你想做一个可以点击选中哪一天的日历,很简单,你只需要在每一个日历的 item 上绑定一个单机事件,然后将 item 传递进去,代码如下。

clickDay:function (day) {
     alert('今天是'+this.year+'-'+this.month+'-'+day)
},

当然这里你需要对时间进行各种处理判断,转换为标准的时间格式。

这个日历的思路是我写了几套日历组件中最简单的一种,也是实现最方便的一种,只需要少量的代码就可以完成。

在这里,为大家提供了最简单的思路,如果你想要做一个有月份选择的日历,可以选择上一个月下一个月,也是非常的简单,逻辑与上面的都一样,你只需要将当前月进行修改,然后继续处理后面的逻辑就可以了。根据上面的逻辑,你可以随便修改为你想要的效果,是不是代码非常的简洁,比你之前使用 jQuery 要好用得多?

在之前的文章中,我们都没有实际的去与后台进行交互。接下来,就以实际的例子与后台进行交互,走一遍交互的流程。

我在网上随便找了一个网站,然后获取了它的接口,今天就用来做教程使用。

注册

网站注册是使用的手机号码,在用户输入框失去焦点的时候有一个检测帐号是否存在的接口,是一个 Get请求,代码如下。

axios.get('https://sevingapi.seving.cn/v1/user/isreg?username=18100805031')//这是请求接口,参数为username,就是你的手机号码
   .then(function(res){
   // 响应成功回调
   console.log(res)
     })
   .catch(function(err){//网络响应错误
    // 响应错误回调
      alert('网络错误')
   })

console 打印出来的内容为:{"success":false,"message":"用户未注册","data":"18100805031","code":0},这里的 success 不清楚是表示的什么。

在检测了帐号未被注册的情况下,你填写完资料就进行注册请求(如果你测试该接口,只修改用户名,密码,还有 code 验证码就可以了,其他数据都不改变),代码如下:

var data={
    username:'18100805031',
    userpwd:'lzh1994',
    rolecode:'simple',
    code:'014166',
    regtype:'phone',
    recommen_code:'',
    city_code:'chengdu',
    org_code:''
}
axios.post('https://sevingapi.seving.cn/v1/user/reg',data)
        .then(function(res){
         // 响应成功回调
        console.log(res)
        })
        .catch(function(err){//网络响应错误
          // 响应错误回调
          alert('网络错误')
        })

上面的参数为在网络请求中监测到的参数,也是我填写或者选则的内容,当你发送请求之后,它会给你返回这样的返回值:

{"success":false,"data":"Exception","message":"验证码错误或已失效,请重新获取","code":0}

当然,这是我在失败的情况下取出来的,如果成功了它就直接跳转到登录页面了。

当注册成功之后,你就可以前往登录了。接下来就是登录接口了,代码如下。

var data={
    username:'18100805031',
    userpwd:'lzh1994'
}
axios.post('https://sevingapi.seving.cn/v1/user/login',data)
        .then(function(res){
         // 响应成功回调
        console.log(res)
        })
        .catch(function(err){//网络响应错误
          // 响应错误回调
          alert('网络错误')
        })

在你登录成功之后,后台会给你反馈,如下。

{"success":true,"message":"登录成功","data":{'token':'DU_p5znQ4YxDTWN0x5qqteCz0-jcX1gR_1518180132'},"code":0}

现在,拥有这个 token 之后,你就可以去请求这个网站的各类接口,token 就是你的通行证,接下来就去请求我们的用户信息,代码如下。

axios.get('https://sevingapi.seving.cn/v1/user/center?token=DU_p5znQ4YxDTWN0x5qqteCz0-jcX1gR_1518180132')
        .then(function(res){
         // 响应成功回调
        console.log(res)
        })
        .catch(function(err){//网络响应错误
          // 响应错误回调
          alert('网络错误')
        })

然后后台就会反馈你想要的数据,如下。

{
    "success": true,
    "message": "请求成功",
    "data": {
        "id": 1434345,
        "username": "18100805031",
        "useremail": "599901155@qq.com",
        "userphone": 18100805031,
        "nickname": "18100805031",
        "avater": "",
        "birthday": "2018-02-09",
        "msg_count": "1",
        "is_got_gifts": 0,
        "role": "simple",
        "isvip": 0,
        "viptype": null,
        "viprate": null,
        "isexpire": 1,
        "vipname": null,
        "city": "成都",
        "org_code": null,
        "org_name": null,
        "isGotVoucherByInviteCode": 0
    },
    "code": 10
}

这样你就获得了用户信息数据,便可以展示在页面上了。

上面所测试的接口,大家都可以进行测试,根据说明带上参数就 OK 了。

小结

纸上得来终觉浅,绝知此事要躬行。

教程到这里基本上除了打包之外的内容都讲得差不多了,在开篇中我说过,请你跟着我的教程写 Demo。写了Demo,你就会发现,往往有很多地方会和想想中的不一样,并不是看一次教程就会了,必须要大量的实践才能获得真正的技术。如果你在动手操作的过程中遇见了任何问题,你都可以在读者圈留言,我会为你一一解答。

上一篇
下一篇
目录