/ele

Vue.js 2.0 仿饿了么Web APP

Primary LanguageVue

ele

Vue.js 仿饿了么Web App

技术栈

  • vue
  • vuex
  • vue-router
  • vue-resource
  • webpack
  • eslint
  • better-scroll
  • stylus
  • postCss

Build Setup

# install dependencies
npm install

# serve with hot reload at localhost:8080
npm run dev

# build for production with minification
npm run build

# build for production and view the bundle analyzer report
npm run build --report

Tips & 坑:

router-view

vue1.0升至2.0+后,v-link改为<router-view></router-view>,入口js文件的设置也跟随变化,需要按照官网配置router.vuejs.org, 不仅把这些.vue .js文件的配置改了,还需要在package.json中的dependencies内,把vue和vue-router的版本也改为最新;

移动端像素

在手机等移动端物理像素有别于逻辑像素,具体的比例根据不同设备的设备像素比不同而不同;

一个在开发过程中使用手机浏览页面的方法:

  • 使用ipconfig查看自己PC局域网IP;
  • 将浏览器url中的localhost改为局域网IP;
  • 复制链接至草料网生成二维码;
  • 使用同在一个局域网的手机扫码访问即可!

实现移动端一像素边框的方法:利用min-device-pixel-ratio媒体功能实现真正的1像素

vue-resource

使用vue-resource时注意this.$http.get(url).then((res) => {})中回调函数then()中获取到的json内容在res.body,data中。 在使用ajax的get方法获取数据来填充app.vue内seller等对象之前,seller等对象还是空对象,所以在用seller内的数据渲染时,需要加v-if判断seller等对象是否有值, 否则会报错。

sticky footers

sticky footers,即粘性页脚布局,在遇到下面两个布局的时候需要用到:

  • 在内容未撑满页面时,footer固定在底部
  • 在内容超出页面高度时,footer随着页面的变大而往下移动,也保持在页面底部。

一种兼容性最佳的解决方案(负margin布局)

思路:

一般情况下,一个网页分为header、content、footer;

  • 将头部和内容装入一个容器wrapper-main,再将wrapper-main封装到wrapper中;
  • 将wrapper的min-height设为100%,wrapper-main的padding-bottom设为footer的高度;
  • 将footer的margin-top设为负的自身的高度;

这样就达到了当wrapper的高度为100%时,footer固定在视口的底部,当其高度大于100%时,footer则一直在wrapper后面的效果;

<div class="wrapper clearfix">
  <div class="wrapper-main">
    <header>头部</header>
    <div class="content">页面内容</div>  
</div>
</div>
<footer>页脚</footer>
.wrapper{
  min-height: 100%;
}
.wrapper-main{
  padding-bottom: 50px;
}
footer{
  position: relative;
  height: 50px;
  margin-top: -50px;
  clear: both;
}
.clearfix:after {
  display: block;
  content: '';
  clear: both;
  height: 0;
  visibility: hidden
}

第二种:flex布局

思路

讲header和content包装在一个wrapper-main内,再将footer和wrapper-main包装在display为flex的一个wrapper内。

<div class="wrapper">
  <div class="wrapper-main">
    <header>头部</header>
    <div class="content">页面内容</div>
  </div>
  <footer>页脚</footer>
</div>
.wrapper{
  display: flex;
  flex-direction: column;
  min-height: 100%;
}
.wrapper-main{
  flex: 1;
}
footer{
  flex: 0;
}

vue过渡效果

vue2+已经将过渡效果升级为transition 的封装组件,具体使用:

<transition name="fade">
  <p>hello</p>
</transition>
.fade-enter-active, .fade-leave-active {
  transition: opacity .5s
}
.fade-enter, .fade-leave-to /* .fade-leave-active in below version 2.1.8 */ {
  opacity: 0
}

官方文档

好的编程习惯

写css时尽量用class名而非标签名,在渲染性能上,class优于标签,尤其在层级嵌套较深时。

Vue 获取 DOM 对象的接口—— vm.$refs

在vue 1.0中使用v-el定义element,2.0 升级为 ref

vm.$nextTick( [callback] )

vm.$nextTick( [callback] )在修改数据之后立即使用这个方法,获取更新后的 DOM。

new Vue({
 methods: {
   example: function () {
     // 修改数据
     this.message = 'changed'
     // DOM 还没有更新
     this.$nextTick(function () {
       // DOM 现在更新了
       // `this` 绑定到当前实例
       this.doSomething();
     })
   }
 }
})

左边栏固定宽度,右侧自动适应

方法之一:使用flex布局

<div class="goods">
  <div class="menu"></div>
  <div class="content"></div>
</div>


<style>
  .goods{
    display: flex;
    height: 400px;
  }
  .menu{
    background: #4FB3A4;
    flex: 0 0 100px;
    /*flex: none | [ <'flex-grow'> <'flex-shrink'> <'flex-basis'> 默认 0 1 auto]*/
    /*flex-grow:定义项目的放大比例,默认为0*/
    /*flex-shrink:定义了项目的缩小比例,默认为1*/
    /*flex-basis:定义了在分配多余空间之前,项目占据的主轴空间(main size)*/
  }
  .content{
    flex: 1;
    background: yellow;
  }
</style>

更多方法参考我的一篇总结:左侧定宽,右侧自适应与双飞翼布局

v-for使用索引

v-for 遍历数组时的参数顺序已经变更,当包含 index 时,之前遍历数组时的参数顺序是 (index, value),现在是 (value, index)。来和 JavaScript 的原生数组方法 (例如 forEachmap) 保持一致。

右侧滚动时根据滚动位置实时计算左侧菜单active的值

首先遍历获取每个li标签的clientHeight值,依次叠加并存入数组listHeight,之后给右侧ul添加scroll事件,获取滚动的值后,利用vue的计算属性计算当前滚动的值在listHeight的区间,从而通过该区间确定左侧菜单栏对应的active类的位置

绑定 Class

动态地切换 class可以通过v-bind绑定class,可以使用对象语法(传入一个对象,通过判断对象属性值是否为true来切换class)、数组语法(同理):

:class="{'hightLight': totalCount>0}"

v-bind:class="{ active: isActive, 'text-danger': hasError }">
data: {
  isActive: true,
  hasError: false
}

ES6 多行字符串 连接字符串

在ES6之前,拼接字符串需要使用+,在ES6中只需使用反引号配合${ 变量 }即可;

// 旧版
alert("你好,\n 我叫\n Olive");
// ES6
alert(`你好
我叫
olive`);

// 旧版
let name = 'cat';
console.log('你好,' + name + '!');
// ES6
console.log( `你好,${name}!` );

子组件和父组件之间通信

父组件good.vue --- 子组件food.vue

  • 首先父组件内通过import引入子组件
  • 通过components注册组件
  • 将子组件名作为标签名实现在父组件内使用子组件
  • 子组件内通过props引入父组件数据
props() {
  food: {
    type: Object
  }
}
  • 父组件通过在子组件标签内使用v-bind传入数据food
<food :food="food"></food>

父组件可以调用子组件方法,反之则不行

编程规范

组件的方法如果是私有的,命名时最好在前面加上_,如:"_show",公有则不加

调用方法

使用 ref 为子组件指定一个引用 ID,然后在父组件中使用this.$ref.id.show()即可使用子组件的方法。

事件修饰符

Vue.js 为 v-on 提供了事件修饰符,使用@.stop阻止冒泡 官方文档