移动端web开发初探之vuejs的简单实战

前端小老虎      2022-02-16     674

关键词:

这段时间在做的东西,是北邮人论坛APP的注册页。这个注册页是内嵌的网页,因为打算安卓和IOS平台同时使用。因此实际上就是在做移动端的web开发了。
在这过程中遇到了不少有意思的东西。

DEMO的github地址在这里

内容提要:

  • meta标签
  • Vuejs的简单实战
  • CSS移动端全屏背景
  • CSS移动端动画初探

meta标签

这点与在PC端写前端有着很大的区别,移动端的meta标签简直多。我就说说我所用到的标签。
<!-- 1、如果支持Google Chrome Frame:GCF,则使用GCF渲染;2、如果系统安装ie8或以上版本,则使用最高版本ie渲染;3、否则,这个设定可以忽略。 -->
<meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">
<!-- 对视窗缩放等级进行限制,使其适应移动端屏幕大小 -->
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- 当把这个网页添加到主屏幕时的标题(仅限IOS) -->
<meta name="apple-mobile-web-app-title" content="北邮人论坛注册">
<!-- 添加到主屏幕后全屏显示 -->
<meta name="apple-touch-fullscreen" content="yes" />

尤其是第二个meta标签,是移动端适配非常重要的一句话。

整体布局

整体的布局大致是4-5页横向布局。第一页是用来填写注册信息的。后面的几页是用来选择关注的版面的。

注册信息页

关注版面页

整体架构

前端采用的架构大致是这样:
  • 滑动切换页面的效果来自swiper.js
  • 页面内容的渲染采用Vue.js
  • 页面布局和样式采用纯css,部分效果采用css3
  • ajax部分采用vue-resource

后端支撑的框架来自php的laravel,当然,这不是本文的重点,仅提及一下。

是的这次的开发中,已经看不到jquery的身影了——这也是前端以后发展后的结果——慢慢地脱离jquery的依赖。不过jquery给前端带来的改变和发展是无人能替代的。

swiper.js的应用

引入swiper.js来进行页面的切换效果纯粹是因为这次开发的周期要求比较短,要考虑效果和兼容性兼备的情况下,我就偷懒找了一个动画库。

不过这个动画库的效果我还是算比较满意的。而整体来说使用也相当方便。尤其是,swiper.js是可以不依赖jquery的。

使用起来也比较方便。我简要说说用法。

首先需要在页面顶部的head标签里加入swiperjs的css文件:

<link rel="stylesheet" href="css/swiper.min.css')">

然后在页面底部可以引入和写下相应的js:

<script src="{{ asset('js/swiper.min.js') }}"></script>
  <!-- Initialize Swiper -->
<script>
  var swiper = new Swiper('.swiper-container', {
    pagination: '.swiper-pagination',
    paginationType: 'progress',
    noSwipingClass: 'swiper-no-swiping',
    allowSwipeToNext: true,
    allowSwipeToPrev: true,
  }); 
</script>

解释一下,创建一个swiper的对象,然后这对象的容器是class叫做swiper-container的一个html元素。对其的配置是:

  • pagination: ‘.swiper-pagination’, 显示页码
  • paginationType: ‘progress’, 页码显示格式为进度条,可以参见顶部蓝白色的进度条
  • noSwipingClass: ‘swiper-no-swiping’, 不允许进行触摸滑动的元素的class名称
  • allowSwipeToNext: true, 允许向后滑动
  • allowSwipeToPrev: true, 允许向前滑动

相应的HTML代码可以如下:

<!-- swiper生效的容器 -->
<div class="swiper-contanier">
  <div class="swiper-wrapper">
    <!-- 具体滑动的页面 -->
    <div class="swiper-slide"></div>
    <div class="swiper-slide"></div>
    <div class="swiper-slide"></div>
    <div class="swiper-slide"></div>
  </div>
</div>
<!-- 进度条 -->
<div class="swiper-pagination"></div>

有些页面是不能直接让用户通过触摸来前后滑动的,而必须通过点击按钮触发。比如第一页注册页,这个页面就是必须填写完信息然后点击下一步进行验证后然后才可以滑动到后面的内容。所以只要将这个页面所在的class里加上swiper-no-swiping这个class就可以实现无法触摸滑动切换页面了。

然后我们可以通过swiper.slideNext(bool,time)这个方法来进行手动控制向后翻页的动作以及控制动画的时长。这个内容会在vue里说到。

Vue.js的简单实战

由于本次的开发只是在原有的北邮人开放平台的项目的基础上加入一个快速注册的功能,所以Vue.js的引入并不是为了将整个项目重构,而只是为了尝试一下脱离jquery的情况下对于开发来说不同的体验是什么,能学到什么。

关于Vue.js的用法、特性什么的不是本文的重点,题外话就不说了。说说本次实现思路。因为我的Vuejs实际上也只是算入门级别,只能说会用但是还没到能驾驭的程度。

首先整个页面包在class叫做swiper-contanier的元素中。因为这个元素包括了滑动所需的所有东西,我们实际上可以简单的把它看成是一个SPA(Single Page Application),用一个Vue的实例就可以接管整个页面了(这么说是不负责的,因为实际上Vue是组件化的思想)。

先创建一个基本的Vue的示例,并将其和swiper-container绑定起来:

var vm = new Vue({
  el: ".swiper-contanier", // 将这个实例与html元素绑定起来
  data: {}, // 所需要变动、关注的数据,也是vue的核心
  ready: function(){}, // vue提供的钩子,用于在vue渲染视图完成后立即触发
  methods: {} // 方法,用于操作、更新、改变数据而改变视图
})

注册页实现

上面所说,我们的页面是构建在一个Vue的实例上的。因此不同类型的两种页面如何用一个实例来接管呢?在这里我的实现方式是用两类数据来分别表示。

我们分析一下注册页:

实际上注册页的中间部分是重复的元素,他们都是input标签+显示文字标签(对,尤其注意这里并不是用placeholder实现的)。效果:

所以这中间的部分实际上可以看成是一个列表,可以用Vue的v-for来渲染。列表里所不同的只是显示的文字不同以及input框的类型不同(有text类型的,有password类型的),所以用数据绑定的方式我们可以将这个页面的数据格式安排如下:

data: {
  main: [
    {"name":"username","info":"用户名(以英文开头+英文数字)","type":"text"},
    {"name":"passwd","info":"设置密码","type":"password"},
    {"name":"passwd_confirm","info":"在输入一遍密码","type":"password"},
    {"name":"gwno","info":"校园网账户(默认是学号)","type":"text"},
    {"name":"gwpwd","info":"校园网密码(默认是身份证后六位)","type":"password"},
  ],
}

同时我们创建一个便于和前端视图进行双向绑定的数据对象userInfo:

data: {
  main: [...],
  userInfo: {
    username: "",
    passwd: "",
    passwd_confirm: "",
    gwno: "",
    gwpwd: ""
  }
}

而在前端的话我们就可以用这个数据来进行视图渲染:

<ul class="user-info">
  <li v-for="item in main" style="position: relative;">
    <!-- input输入框 -->
    <!-- 此处用了v-model将数据和视图进行了双向绑定 -->
    <input class="effect" type="{{item.type}}" v-model="userInfo[item.name]">
    <!-- 提示信息 -->
    <label>
      <span>{{item.info}}</span>
    </label>
    <!-- input框的底下的线条 -->
    <span class="focus-border cube"></span>
  </li> 
</ul>

<a href="#"><button>下一步</button></a>

于是一个输入的列表就很容易做出来了。然后既然是表单,就需要验证。而此处做的验证实际上有这么几点:

  • 用户名是否合法/重复?
  • 两次输入的密码是否相同?
  • 校园网账户的密码是否正确?

其中只有第二点两次密码输入是否相同可以用前端直接判断,而第一、三点都是需要通过ajax的方式向后台发送验证请求的。为了能够体现和辨别错误与否,我们在main下的每个条例里加入了一个error属性,并规定如下三种状态:

  • true,代表有错误,提示错误
  • false,代表正确,提示正确
  • normal,代表默认,显示默认值

于是我们可以在method下写一些方法来进行判断。

checkUserId: function(msg){
  if (msg !== ""){
    this.$http.post('url'+msg,function(data){
      if (data.success){
        this.main[0].error = false;
      } else{
        this.main[0].error = true;
      }
    })
  } else{
      this.main[0].error = "normal";
  }
},
checkUserPwd: function(){
    if (this.userInfo.passwd_confirm !== ""){
        this.userInfo.passwd == this.userInfo.passwd_confirm && this.userInfo.passwd_confirm != "" ? this.main[2].error = false : this.main[2].error = true;
    }
},

当然这个只是一个引入的功能,我们再聚合一下:

check: function(msg,i){
  var index = i;
  this.userInfo[msg] != "" ? this.main[index].effect = true : this.main[index].effect = false;
  switch (msg){
    case "username":
      this.checkUserId(this.userInfo[msg]);                                      
      break;
    case "passwd":                                                                 
      this.userInfo.passwd !== "" ? this.main[1].error = false : this.main[1].error = "normal";       
      this.checkUserPwd();                                                       
      break;                                                                     
    case "passwd_confirm":
      this.checkUserPwd();                                                       
      break;
    case "gwno":
      this.userInfo.gwno !== "" ? this.main[3].error = false : this.main[3].error = "normal";     
      break;
    case "gwpwd":
      this.userInfo.gwno !== "" ? this.main[4].error = false : this.main[4].error = "normal";     
      break; 
  }     
}

这样通过一个check的method我们就可以将整个表单的验证的方法容纳进来了。(此处对于校园网账号的验证会放到提交表单的函数中)。为了能在视图中体现正确、错误、正常的不同形态,我们需要对前端的一些结构进行一些修改。我们需要给main下的每个条例加入错误信息,也即errorInfo。

所以至此整个main的结构是这样:

main: [
  {"name":"","info":"","type":"","error":"","errorInfo":""},
  ...
]

然后我们需要加入提交验证的部分:

submitReg: function(){
  var flag = 0;
  // 用于判断表单是否都是正确的
  this.main.map(function(obj){
    obj.error == false ? flag += 1 : flag +=0;
  })
  if (flag == 5){
    this.$http.post('url',this.userInfo)
    .then(function(res){
      if (res.success){
        swiper.slideNext(false,300); // 验证正确就可以进入下一页
      } else{
        this.main[4].error = true;
      }
    })
  }
},

将视图部分修改如下:

<ul class="user-info">
  <li v-for="item in main" style="position: relative;">
    <!-- 绑定blur事件 -->
    <input @blur="check(item.name,$index)" class="effect" type="{{item.type}}" v-model="userInfo[item.name]">
    <!-- 根据error类型切换不同的标签显示 -->
    <label>
      <!-- 此处用到了v-show的方法 -->
      <span v-show="item.error == 'normal'">{{item.info}}</span>
      <span style="color: red;" v-show="item.error == true">{{item.errorInfo}}</span>
      <span v-show="item.error == false">{{item.info}}√</span>
    </label>
    <span class="focus-border cube"></span>
  </li>
</ul>
<!-- 点击下一步的同时提交表单信息 -->
<a href="#"><button @click="submitReg">下一步</button></a>

至此,整个注册页的布局和功能性的部分都已经做完了。不过这只是一块比较简单的部分,我们用到了vuejs的的v-for进行列表渲染,用到了v-model进行数据的双向绑定,用到了method进行一些数据的处理,用到了v-show进行条件显示,一个基本的页面下我们已经能尝试这么多vue的特性了。而相比于jquery的dom操作,我觉得vue在此处最好的地方在于,表单的提交很方便。由于双向绑定了数据,只需要后台把数据格式规定好给我,我按照后端的数据结构整理一下我前端的数据结构然后就可以直接提交给后端了。而且省去了很多dom操作的地方。

不过除了vue的部分,我还想来说说两个东西,跟css有关:

  • 全屏背景
  • 输入框文字提升效果,并涉及到移动端动画效果的处理

全屏背景
不仅仅是简单的background-size: cover那么简单了,还需要进行小小的处理。先说说我希望实现的效果吧。我希望的效果是整个背景能够填充整个页面,并且在页面元素上下滚动的情况下,背景固定而不随着元素滚动。

放到往常我可能会这么写:

body,html{
  height: 100%;
}

body{
  background: url(bg.png) center 0 no-repeat;
  background-size: cover;
}

但是这样的话在移动端会出现比较严重的后果,那就是一旦页面元素的高度大于整个页面后,滚动页面元素的时候,背景也会随之而动。而且背景会被撑开。这不是我所希望的。

这里用到一个小技巧,用上:before的方法。

body:before {
  content: "";
  position: fixed;
  z-index: -1;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  background: url(bg.png) center 0 no-repeat;
  background-size: cover;
}

这个用上before的伪元素的方法是一个很有奇效的小技巧。大家不妨可以试试。这样的话在移动端也能完美实现背景固定而且显示全屏。

移动端动画简单初探
在做PC端的web的动画效果的时候,由于PC端的性能足够,所以在写一些效果的时候往往没有考虑到性能的问题。这次在开发的时候就遇到了动画效果实现上不小的问题。大家先来看看这两个动画的比较:上面一个动画和下面一个动画:

第一个:
https://codepen.io/molunerfinn/pen/zBGrxx

第二个:
https://codepen.io/molunerfinn/pen/oLXjKz

会发现这两个东西的效果相差甚大。实际上,二者实现的最终效果是一致的,都是让小球按一条口型路线运动。但是为何显示上来说,第一个这么流畅,而第二个有明显卡顿呢?

这里涉及到很多东西,不光光是重绘(repaint),还有软硬件性能上面的问题。感兴趣的话可以参考这些文章:

在移动端上的效果如果没有优化的话,实际上大致就是第二种的效果——让人看起来有所卡顿。简单来说,在移动端,有些效果是由浏览器来渲染的——那么这些效果如果比较复杂,而移动端的浏览器性能又不太足够的情况下,效果就比较卡顿。有些效果可以由GPU来渲染,那么这些效果渲染起来就相对来说比较流畅。而我们还可以人为触发GPU硬件渲染,通过 transform的translate3d属性就能实现硬件渲染从而俗称硬件加速。

举个简单例子。如果让一个元素从(0,0)->(100px,0),正常思路是left: 0->left: 100px,然后再用transition属性进行过渡。不过这样的话在移动端上效果就很感人,因为涉及到性能问题。但是如果我们用另外一种方式: transform: translate3d(100px,0,0)的话,就可以让这个动画效果由GPU去渲染,那么这样的话,在移动端的效果也是完全可以接受的流畅。

实际上,能够触发GPU渲染的动作有opacity,transform,transition,animation等等。但是像top,left,color,size等属性的变化则不会触发GPU渲染。

本文中描述的实例,是当焦点集中到input框的时候,文本上移并且有颜色变化。本来想实现的是文本大小还有变化。但是由于上面说的情况,涉及到size变化的时候,效果就会大打折扣。无奈之下我只能砍掉这个效果了。而实现文本上移实际上就是采用了transform的translate3d的方式,将其往上移动,并配合transition进行了一下过渡处理罢了。

具体的CSS实现大致如下:

input:focus ~ label,.trans {                                                                 
  color: #fff;                                                                                 
  transition: 0.3s;                                                                            
  -webkit-transform: translate3d(0, -20px, 0);                                                 
  -moz-transform: translate3d(0, -20px, 0);                                                    
  -ms-transform: translate3d(0, -20px, 0);                                                     
  transform: translate3d(0, -20px, 0);                                                         
}

实际上也不难不是么?

关注版面页的实现

实际上从注册页的实现中已经可以瞅见关注版面页实现的方法了。实际上关注版面页不过也是列表的渲染,在数据里定义好相应的属性就行了。然后用一个picked的属性来看看是否被选中即可。最后完成注册的时候,将所有选中的列表组装成相应的数组提交到后台就行了。因为注册页里这些方法已经说过了,所以就不再赘述了。

总结

简单总结一下,这次移动端的开发中学习到的东西。
  • Vuejs的简单使用,从DOM操作->数据绑定
  • 全屏背景的实现
  • 流畅动画效果的实现

实际上,兼容性方面还有不少的东西需要诉说,不过限制于篇幅以及本文的主要内容并不是在纠结移动端的兼容性的所以并没有在兼容性方面进行记录。

在排版上我还是没有用上比较流行的flex,对于Vue还没有使用组件化开发的思路。这些都是需要改进的部分。不过这次的开发过程中经过美工的指点,将我之前写页面的时候注意不到的很多细节部分,比如线条尺寸,元素间隔,颜色搭配等东西给指了出来,这些东西都不是简简单单就实现的。总之,有时间的话,我想我可以将设计方面的知识融入到我的前端开发中,想必能让我的作品更加地符合审美和用户的体验吧~

DEMO的github地址在这里

文章作者: Molunerfinn
文章链接: https://molunerfinn.com/vuejs-1/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 MARKSZのBlog!

vuejs+es6开发移动端app实战项目笔记

一、什么是MVVM框架MV*包括MVC、MVP、MVVMMVVM框架由Model、View、ViewModel构成。Model指的是数据,在前端对应的是JavaScript对象。View指的是视图,在前端对应的是DOMViewModel观察Model和View的变化来做更新,实现了数据的双向绑定。前端MVVM... 查看详情

学习vue.js之vue移动端框架到底哪家强

...uejs.org/Weex2016年4月21日,阿里巴巴在Qcon大会上宣布跨平台移动开发工具Weex开放内测邀请。Weex是一套简单易用的跨平台开发方案,能以web的开发体验构建高性能、可扩展的native应用,为了做到这些,Weex与Vue合作,使用Vue作为上层... 查看详情

移动web开发之flex布局(代码片段)

...与flex布局传统布局兼容性好布局繁琐局限性,不能再移动端很好的布局flex弹性布局操作方便,布局极为简单,移动端应用很广泛PC端浏览器支持情况较差IE11或更低版本,不支持或仅部分支持建议:1.如果是PC... 查看详情

移动web开发之flex布局(代码片段)

...与flex布局传统布局兼容性好布局繁琐局限性,不能再移动端很好的布局flex弹性布局操作方便,布局极为简单,移动端应用很广泛PC端浏览器支持情况较差IE11或更低版本,不支持或仅部分支持建议:1.如果是PC... 查看详情

web前端之移动端课程开发之06.bootstrap(代码片段)

...平板手机端栅格布局完整的类库jQuery插件不同的使用场景移动设备优先Bootstrap3 查看详情

web前端之移动端课程开发之06.bootstrap(代码片段)

...平板手机端栅格布局完整的类库jQuery插件不同的使用场景移动设备优先Bootstrap3 查看详情

html5移动web开发实战pdf扫描版?

《HTML5移动Web开发实战》提供了应对这一挑战的解决方案。通过阅读本书,你将了解如何有效地利用最新的HTML5的那些针对移动网站的功能,横跨多个移动平台。全书共分10章,从移动Web、设备端配置和优化,变互、响应式设计、... 查看详情

精讲前端实战项目之移动端网易云首页(附源码)(代码片段)

...习一些实战项目。今天这个就是一个很好的实战例子——移动端网易云首页,刚开始就做一些简单的静态网页。本人会用到很多标签,如果忘记了可以查 查看详情

精讲前端实战项目之移动端网易云首页(附源码)(代码片段)

...习一些实战项目。今天这个就是一个很好的实战例子——移动端网易云首页,刚开始就做一些简单的静态网页。本人会用到很多标签,如果忘记了可以查 查看详情

从零搭建移动h5开发项目实战(代码片段)

从零搭建移动H5开发项目实战前端H5的前世今身在Pc的时代,前端技术无疑统治了大多数用户的交互界面!而在移动为王的今天,NA开发在早期占领了大多数用户的交互界面,后来逐渐的前端H5开发找到了自己的技术优势,慢慢的... 查看详情

从零搭建移动h5开发项目实战(代码片段)

从零搭建移动H5开发项目实战前端H5的前世今身在Pc的时代,前端技术无疑统治了大多数用户的交互界面!而在移动为王的今天,NA开发在早期占领了大多数用户的交互界面,后来逐渐的前端H5开发找到了自己的技术优势,慢慢的... 查看详情

html5+mui+hbuilder之初探情人

...++和Java。当诺基亚的倒闭成为按键机时代衰落的标志时,移动APP的开发也如破堤之洪。爆炸式的崛起了。小弟不才,反映略慢,加上观念陈旧,(C++程序猿的通病——认为前端=低端&移动端=前端),因此并没有打好移动APP的... 查看详情

html5移动端布局实战开发课程

参考技术A⑴5做移动端开发有什么优势HTML5的前景是非抄常好的,企袭业现在安卓、iOS开发人员都在学习HTML5混合开发,节约成本、一专多能是未来很多企业用人趋势!HTML5工程师在今后的工作中与Android、iOS工程师对接的几率非常... 查看详情

移动端web开发框架

一、目前移动端布局方法两个基本规则:移动优先,设计初期就要考虑设计的页面如何多终端显示。渐进增强,充分发挥硬件设备的最大功能。三个常用方法:   1)css3-media Query(最简单,最基本)   &n... 查看详情

web开发需要学习啥?

...段目标:1.熟练掌握HTML5、CSS3、Less、Sass、响应书布局、移动端开发。2.熟练运用HTML+CSS特性完成页面布局。4.熟练应用CSS3技术,动画、弹性盒模型设计。5.熟练完成移动端页面的设计。6.熟练运用所学知识仿制任意Web网站。7.能综... 查看详情

java初探之登录再探

...ler中,我们实现了对数据的简单校验,但事实上,在实际开发中,我们不可能使用这么繁琐的校验代码。校验过程,交给javax.validation.Valid 查看详情

云原生之docker实战使用dokcer部署web端vscode

...务器的容器化版本。2.VisualStudioCodeServer是一项可以在远程开发机器(如台式电脑或虚拟机(VM))上运行的服务。它允 查看详情

使用layui框架实战之栅格系统和菜单评分组件运用心得(代码片段)

...易用,界面简单美观。目标对象是对前端不太了解的后端开发人员,它也适用于后端开发人员。(1)Layui是一个轻量级框架,简单而美观。适用于后端模式的开发,对服务器页面有很好的效果。(2)Layui是后端开发人员的最佳UI... 查看详情