vue2.x 仿饿了么app商家页面 项目总结

[原文地址 ](https://segmentfault.com/a/1190000010124638?utm_source=tag-newest)
                                <div class="post-topheader__info" data-username="moxiaojing" data-userslug="moxiaojing" data-useravatar="https://avatar-static.segmentfault.com/328/587/3285875860-593530bdc00d8_big64">


                                    <div class="article__author clearfix">
                                        <div class="article__authorleft">
                                            <a href="/u/moxiaojing">
                                                <img class="avatar-40" src="https://avatar-static.segmentfault.com/328/587/3285875860-593530bdc00d8_big64" alt="moxiaojing">
                                            </a>
                                        </div>
                                        <div class="article__authorright">
                                            <div class="article__authormeta">
                                            <a href="/u/moxiaojing" class="mr5"><strong>moxiaojing</strong></a>
                                    
                                            
                                                                                            <img src="https://cdn.segmentfault.com/v-5c8b4d77/global/img/rp.svg" class="mr5"><span style="color:#BF7158" class="mr10">103</span>

                                                                                            发布于
                                            <a href="/blog/moxiaojing">前端</a>
                                            
                                            
                                            <span class="hidden-xs">
                                                                                                                                                      <button type="button" class="btn btn-xs btn-success follow-article ml10" data-do="follow" data-type="blog" data-id="1200000009955255">关注专栏
                                                   </button>
                                                                                                                                               </span>
                                            </div>
                                            
                                            <span style="display: block">
                                                2017-07-10 发布
                                            </span>
                                        </div>
                                    </div>

                                    <h1 class="h1 post-topheader__info--title" id="articleTitle" data-id="1190000010124638">
                                        <a href="/a/1190000010124638"> 最新 vue2.x 仿饿了么app商家页面 项目总结</a>
                                    </h1>

                                    <div class="content__tech hidden-xs">
                                        <a href="" class="blog-type-common blog-type-0-before" target="_blank" data-content="
                                                                                    翻译自 
                                                                                    "></a>
                                        
                                        <ul class="taglist--inline inline-block article__title--tag mr10">
                                                                                                <li class="tagPopup mb5">
                                                    <a class="tag" href="/t/vue.js/blogs" data-toggle="popover" data-img="https://avatar-static.segmentfault.com/256/038/2560380373-565be73e6fe13_big64" data-placement="top" data-original-title="vue.js" data-id="1040000004003243">
                                                                                                                  vue.js
                                                    </a>
                                                </li>
                                                                                        </ul>

                                        <span>
                                            11.3k 次阅读
                                            &nbsp;·&nbsp;
                                            读完需要 48 分钟 
                                                                        </span>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div><!-- end .post-topheader -->

            <div class="visible-lg">
                <div class="side-widget">
                    <div class="stream__item-zan btn btn-default mt0 mb15 ml0 mr0 pt0 pb0 pl0 pr0 " id="side-widget-votes-btn">
                        <span class="stream__item-zan-icon"></span>
                        <span class="stream__item-zan-number" id="side-widget-votes-num">8</span>
                    </div>

                    <i class="fa fa-bookmark item " id="side-widget-bookmarks-btn"></i>
                    <i class="fa fa-weibo item"></i>
                    <i class="fa fa-weixin item" data-toggle="popover" data-placement="right" data-original-title="" title=""></i>
                    <i class="fa fa-twitter item"></i>
                    <i class="fa fa-facebook item"></i>
                    <i class="fa fa-arrow-up item hidden"></i>
                </div>
            </div>

            
            <div class="article fmt article__content" data-id="1190000010124638" data-license="cc">

最新vue2.x仿饿了么app 商家页面 项目总结

标签(空格分隔): vuejs


前言

仿饿了么app是基于vue2.x最新实战项目,用到的技术栈

vue2 + vue-router2 + vue-cli2 + vue-resource + stylus + flex布局 + es6 + eslint + webpack2 

页面相对简单,所以没有用到vuex, 它更适合对复杂的单页面进行状态管理

实现功能:

•    Goods、Ratings、Seller组件视图均可上下滚动
•    商品页 点击左侧menu,右侧list对应跳转到相应位置
•    点击list查看商品详情页,父子组件的通信
•    评论内容够可以筛选查看
•    购物车组件,包括添加删除商品及动效,购物控件与购物车组件之间非父子组件通信,点击购物车图标,展示选择的商品列表
•    商家实景图片可以左右滑动 
•    loaclStorage缓存商家信息(id、name)

项目地址:https://github.com/moxiaojing...

如果觉得对您有帮助,您可以在右上角给我个star支持一下,谢谢!

1-项目结构分析:

common/---- 文件夹存放的是通用的css和fonts
components/----文件夹用来存放我们的 Vue 组件
router/----文件夹存放的是vue-router相关配置(linkActiveClass,routes注册组件路由)
build/----文件是 webpack 的打包编译配置文件
config/----文件夹存放的是一些配置项,比如我们服务器访问的端口配置等
dist/----该文件夹一开始是不存在,在我们的项目经过 build 之后才会产出
prod.server.js----该文件是测试是模拟的服务器配置,用来运行dist里面的文件,在config/index.js中,build对象中添加一条端口设置port:9000,
App.vue----根组件,所有的子组件都将在这里被引用,eventHub空实例是用来组件间通信的中央数据总线作用,主要连接购买控件和购物车组件之间的数据通信
index.html----整个项目的入口文件,将会引用我们的根组件 App.vue
main.js----入口文件的 js 逻辑,在 webpack 打包之后将被注入到 index.html 中

2-各组件之间的关系:

独立组件
├──iconClassMap–图标组件(减,折,特,票,保)
├──split.vue–关于分割线组件
├──RatingSelect.vue–评价内容筛选组件" title="" data-original-title=“复制”>

├──APP.vue
│ ├──Header.vue–头部组件
│ │ ├──iconClassMap–图标组件(减,折,特,票,保)
│ │ ├──Star.vue–星星评分组件
│ ├──Goods.vue–商品组件
│ │ ├──iconClassMap–图标组件(减,折,特,票,保)
│ │ ├──Shopcart.vue–购物车组件,包括小球飞入购物车动画,使用this.$root.eventHub.$on(‘cart.add’, this.drop)接收,并给drop方法使用
│ │ ├──CartControl.vue–购买控件–选中数量返回给父组件goods,goods响应后,重新计算选中数量,并用this.$root.eventHub.$emit(‘name’,event.target)将数据发送给购物车组件,
│ │ ├──Foodinfo.vue–商品详情页
│ │ │ ├──RatingSelect.vue–评价内容筛选组件
│ ├──Ratings.vue–评论组件
│ │ ├──RatingSelect.vue–评价内容筛选组件
│ ├──Seller.vue–商家组件
│ │ ├──iconClassMap–图标组件(减,折,特,票,保)

独立组件
├──iconClassMap–图标组件(减,折,特,票,保)
├──split.vue–关于分割线组件
├──RatingSelect.vue–评价内容筛选组件

3-开发过程问题汇总:

3-1、better-scroll插件在移动端使用时需要设置click:true,否则移动端滑动无效

3-2、分开设置css样式:

  • 图标icon.css--文字图标样式,通过icommon.io网站 将svg图片转成文字图标样式

  • 公共base.css--处理设备像素比的一些样式,针对border-1px问题,不同设备像素比,显示的线条粗细不同

  • 工具mixin.css--设置border-1px样式和背景样式

3-2-1、这里着重解释一下border-1px的实现

当样式像素一定时,因手机有320px,640px等.各自的缩放比差异,所以设备显示像素就会有1Npx,2Npx.为保设计稿还原度,解决就是用media + scale.

  • 公式:设备上像素 = 样式像素 * 设备像素比

通过查询它的设备像素比 devicePixelRatio

在设备像素比为1.5倍时, round(1px 1.5 / 0.7) = 1px
在设备像素比为2倍时, round(1px 2 / 0.5) = 1px
" title="" data-original-title=“复制”>

屏幕宽度: 320px 480px 640px
设备像素: 1 1.5 2

通过查询它的设备像素比 devicePixelRatio

在设备像素比为1.5倍时, round(1px 1.5 / 0.7) = 1px
在设像素比为2倍时, round(1px 2 / 0.5) = 1px

@media(-webkit-min-device-pixel-ratio:1.5),(min-device-pixel-ratio:1.5)
.border-1px
&::after
-webkit-transform:scaleY(0.7)
transform:scaleY(0.7)

@media(-webkit-min-device-pixel-ratio:2),(min-device-pixel-ratio:2)
.border-1px
&::after
-webkit-transform:scaleY(0.5)
transform:scaleY(0.5)
" title="" data-original-title=“复制”>

// stylus语法
border-1px($color)
position:relative
&:after
content:’’
display:block
position:absolute
left:0
bottom:0
width:100%
border:1px solid $color

@media(-webkit-min-device-pixel-ratio:1.5),(min-device-pixel-ratio:1.5)
.border-1px
&::after
-webkit-transform:scaleY(0.7)
transform:scaleY(0.7)

@media(-webkit-min-device-pixel-ratio:2),(min-device-pixel-ratio:2)
.border-1px
&::after
-webkit-transform:scaleY(0.5)
transform:scaleY(0.5)

更多了解设备像素比devicePixelRatiohttp://www.zhangxinxu.com/wor...

3-3、sticky-footer布局

header组件的详情页采用sticky-footer布局,主要特点是如果内容不够长,页脚部分也会贴在视窗底部,内容足够长,就会将页脚推到内容底部,父级position:fixed,内容设为padding-bottom:64px,页脚相对定位,margin-top:-64px

3-4、要求自适应的布局

3-4-1、左侧宽度固定,右侧宽度自适应
// 左侧固定width:80px,右侧自适应
parent:
    display:fiexd;
child-left:
    flex:0 0 80px
child-right:
    flex:1
3-4-2、元素宽度自适应设备宽度,且元素要求等宽高样式

例如:商品详情页面的商品图片展示样式

// stylus语法
.img_header
    position:relative
    width:100% // width是 设备宽度
    height:0
    padding-top:100% // 高度设为0,使用padding撑开
    .img
        position:absolute //定位布局
        top:0
        left:0
        width:100%
        height:100%

3-5、背景模糊效果

filter:blur(10px),注意,所有在内的子元素也会模糊,包括文字,所以采用定位布局,背景单独占用一个层,ios有一个设置backdrop-filter:blur(10px),只会模糊背景,但不支持android

3-6、transition过渡

在购买控件中使用transition过渡效果,实现添加减少按钮的动效,和小球飞入购物车的动效(模仿贝塞尔曲线的效果)

vue2.x里面定义了transition过渡状态,
name - string, 用于自动生成 CSS 过渡类名。

fade-enter
fade-enter-active
fade-leave
fade-leave-active
" title="" data-original-title=“复制”>

例如:name: ‘fade’ 将自动拓展为.fade-enter,.fade-enter-active等。默认类名为 “v”

fade-enter
fade-enter-active
fade-leave
fade-leave-active

包括transition过渡的钩子函数

before-enter
before-leave
before-appear
enter
leave
appear
after-enter
after-leave
after-appear
enter-cancelled
leave-cancelled (v-show only)
appear-cancelled

详情请查看vue2.x-transition详解

3-7、seller组件:

3-7-1问题一:seller页面中商品商家实景图片横向滚动

解决方案:每个li要display:inline-block,因为width不会自动撑开父级ul,所以需要计算ul的width,(每一张图片的width+margin)*图片数量-一个margin,因为最后一张图片没有margin
同时new BScroll里面要设置scrollX: true,eventPassthrough: 'vertical',// 滚动方向横向

3-7-2问题二:打开seller页面,无法滚动

问题分析:出现这种现象是因为better-scroll插件是严格基于DOM的,数据是采用异步传输的,页面刚打开,DOM并没有被渲染,所以,要确保DOM渲染了,才能使用better-scroll,
解决方案:用到mounted钩子函数,同时搭配this.$nextTick()

3-7-3问题三:在seller页面,刷新后,无法滚动

问题分析:出现这种情况是因为mounted函数在整个生命周期中只会只行一次
解决方案:使用watch方法监控数据变化,并执行滚动函数 this._initScroll();this._initPicScroll();

3-8、缓存数据

使用window.localStorage保存和设置缓存信息,封装在store.js文件内

//将localStorage信息设置到页面中
export function loadFromLocal(id, key, defaults) {
let store = window.localStorage.store;
if (!store) { // 一开始是没有的,因为没有点击事件,所以显示默认数据
return defaults;
}
store = JSON.parse(store)[id]; // 将json格式–>String格式
// console.log(store); // {“isFavorite”:true}
if (!store) {
return defaults;
}
let ret = store[key];
return ret || defaults;
}
" title="" data-original-title=“复制”>

//将页面信息保存到localStorage里
export function saveToLocal(id, key, value) {
let store = window.localStorage.store; // 新定义一个key值_store_,存放要保存的数据对象
// store {
// store[id]: {
// key: value
// }
// }
if (!store) {
store = {};
store[id] = {};
} else {
store = JSON.parse(store); // String格式–> json格式
if (!store[id]) {
store[id] = {};
}
}
store[id][key] = value;
window.localStorage.store = JSON.stringify(store); // 将json格式转成String格式,存放到window.localStorage._store中
}

//将localStorage信息设置到页面中
export function loadFromLocal(id, key, defaults) {
let store = window.localStorage.store;
if (!store) { // 一开始是没有的,因为没有点击事件,所以显示默认数据
return defaults;
}
store = JSON.parse(store)[id]; // 将json格式–>String格式
// console.log(store); // {“isFavorite”:true}
if (!store) {
return defaults;
}
let ret = store[key];
return ret || defaults;
}

3-9、解析url,得到商家信息,包括id,name,在获取数据时,直接赋值,商家的id或name会被丢掉

使用window.localStorage.search获取url地址,并进行解析
封装在tools.js文件内

/方法一:
export function urlParse() {
let url = window.location.search;
let obj = {};
let reg = /[?&][?&amp;]+=[?&]+/g;
let arr = url.match(reg);
// [’?id=12345’, ‘&a=b’]
if (arr) {
arr.forEach((item) => {
let tempArr = item.substring(1).split(’=’);
// 因为tempArr是url中的参数,所以要用decode进行转化
let key = decodeURIComponent(tempArr[0]);
let val = decodeURIComponent(tempArr[1]);
obj[key] = val;
});
}
return obj;
};

/方法二:
export function urlParse() {
let urlArr = window.location.search.substr(1).split(’&’); // 截取掉?,并以&分开,存入数组
// console.log(urlArr); // [“id=1234”, “name=zpxf”]
let obj = {};
if (urlArr) {
urlArr.forEach((item) => {
let arr = item.split(’=’); // 每一项用=分开存入数组,arr[0]=key,arr[1]=value
// console.log(arr); // [id,1234] [name,zpxf]
let key = decodeURIComponent(arr[0]); // 对url解码
let val = decodeURIComponent(arr[1]);
obj[key] = val;
});
}
// console.log(obj); // {id: “1234”, name: “zpxf”}
return obj;
};
" title="" data-original-title=“复制”>

/**

/方法一:
export function urlParse() {
let url = window.location.search;
let obj = {};
let reg = /[?&][?&amp;]+=[?&]+/g;
let arr = url.match(reg);
// [’?id=12345’, ‘&a=b’]
if (arr) {
arr.forEach((item) => {
let tempArr = item.substring(1).split(’=’);
// 因为tempArr是url中的参数,所以要用decode进行转化
let key = decodeURIComponent(tempArr[0]);
let val = decodeURIComponent(tempArr[1]);
obj[key] = val;
});
}
return obj;
};

/方法二:
export function urlParse() {
let urlArr = window.location.search.substr(1).split(’&’); // 截取掉?,并以&分开,存入数组
// console.log(urlArr); // [“id=1234”, “name=zpxf”]
let obj = {};
if (urlArr) {
urlArr.forEach((item) => {
let arr = item.split(’=’); // 每一项用=分开存入数组,arr[0]=key,arr[1]=value
// console.log(arr); // [id,1234] [name,zpxf]
let key = decodeURIComponent(arr[0]); // 对url解码
let val = decodeURIComponent(arr[1]);
obj[key] = val;
});
}
// console.log(obj); // {id: “1234”, name: “zpxf”}
return obj;
};

我们需要将得到的id和name带到数据中,实际上在获取数据的时候,并没有带着id和name,这时就要用到es6语法中Object.assign(),官方解释为:可以把任意多个的源对象自身的可枚举属性拷贝给目标对象,然后返回目标对象。

//即将vm.seller属性和请求返回数据对象合并到空对象,然后赋值给vm.seller,这里加上this.seller即提供了一种可扩展的机制,倘若原来的属性中有预定义的其他属性。" title="" data-original-title=“复制”>

this.seller = Object.assign({}, this.seller, response.data);

//即将vm.seller属性和请求返回数据对象合并到空对象,然后赋值给vm.seller,这里加上this.seller即提供了一种可扩展的机制,倘若原来的属性中有预定义的其他属性。

3-10、goods,ratings,seller组件之间切换时会重新渲染

解决方案:在app.vue内使用keep-alive,保留各组件状态,避免重新渲染

<keep-alive>
    <router-view :seller="seller"></router-view>
</keep-alive>

4-项目总结

4-1、vue-router

使用<router-link>组件完成导航,<router-link>默认会被渲染成一个 <a> 标签,但必须使用to属性,指定连接


" title="" data-original-title=“复制”>

 <!-- 导航 -->
<router-link to="/home">home</router-link>
<router-link to="/about">about</router-link>

<!-- 路由出口 组件渲染容器 -->
<router-view></router-view>

// 挂载
new Vue({
el: ‘#app’,
template: ‘’,
router: router,
components: { App }
});

//或者另一种挂载
new Vue({
template: ‘’,
router: router,
components: { App }
}).$mount(#app);//手动挂载,#app" title="" data-original-title=“复制”>

import Vue from ‘vue’;
import Router from ‘vue-router’;
Vue.use(Resource);
// 定义每个路由对应一个组件
let router = new Router({ // 创建 router 实例,然后传 routes 配置
linkActiveClass: ‘active’,
routes: [{
path: ‘/Header’,
name: ‘Header’,
component: Header
},
{
path: ‘/Seller’,
name: ‘Seller’,
component: Seller
},
{
path: ‘/Goods’,
name: ‘Goods’,
component: Goods
},
{
path: ‘/Ratings’,
name: ‘Ratings’,
component: Ratings
}
]
});
export default router;
router.push(‘goods’);// 相当于页面初始化,显示goods的内容

// 挂载
new Vue({
el: ‘#app’,
template: ‘<App/>’,
router: router,
components: { App }
});

//或者另一种挂载
new Vue({
template: ‘<App/>’,
router: router,
components: { App }
}).$mount(#app);//手动挂载,#app

4-2、vue-resource

通过 this.$http.get来定义通过vue实例来发送get请求,然后通过then后面的回调函数将请求成功的数据接收,通过状态码来判断是否成功以及复制给vue的数据对象。由于这里是用的mock数据(模拟后台数据),所以用的模拟状态码。

同时,这里省略了errorcallback的定义,正常开发中需要进行定义,甚至可以利用vue-resource的inteceptor进行体验优化,比如定义请求时的loading动画界面。在vue中即可以提取出loading组件。

const ERR_OK = 0;//表示没有错误信息,即获取数据成功
this.$http.get('/api/seller').then((response) => {
  response = response.body;
  if (response.errno === ERR_OK) {
    this.seller = Object.assign({}, this.seller, response.data);
  }
});

4-3、Object.assign(target, source1, source2);

这是es6的语法,用于对象合并,将源对象(source)的所有可枚举属性,复制到目标对象(target)。

Object.assign方法的第一个参数是目标对象,后面的参数都是源对象。

注意,如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性。

var source1 = { b: 2, c: 2 };
var source2 = { c: 3 };

Object.assign(target, source1, source2);
target // {a:1, b:2, c:3}
" title="" data-original-title=“复制”>

var target = { a: 1, b: 1 };

var source1 = { b: 2, c: 2 };
var source2 = { c: 3 };

Object.assign(target, source1, source2);
target // {a:1, b:2, c:3}

另外需要注意的是Object.assign()方法只会拷贝源对象自身的并且可枚举的属性到目标身上。也就意味着继承属性和不可枚举属性是不能拷贝的,而且拷贝是对象的属性的引用而不是对象本身。

4-4、组件间通讯

vue是组件式开发,所以组件间通讯是必不可少的。vue提供了一种方式,即在子组件定义props来传递父组件的数据对象。

// 子组件 header.vue
props: {
seller: {
type: Object
}
}" title="" data-original-title=“复制”>

// 父组件
<v-header :seller=“seller”></v-header>

// 子组件 header.vue
props: {
seller: {
type: Object
}
}

如果是子组件想传递数据给父组件,需要派发自定义事件,使用$emit派发,
父组件使用v-on接收监控(v-on可以简写成@)

this. e m i t ( ′ i s C o n t e n t ′ , t h i s . o n l y C o n t e n t ) ; t h i s . emit(&#x27;isContent&#x27;, this.onlyContent); this. emit(isContent,this.onlyContent);this.emit(‘selRatings’, this.selectType);

// 父组件 foodInfo.vue 在子组件的模板标签里,使用v-on监控isContent传过来的数据

<v-ratingselect :ratings=“food.ratings” :select-type=“selectType” :only-content=“onlyContent” :desc=“desc” @selRatings=“filterRatings” @isContent=“iscontent”>
" title="" data-original-title=“复制”>


// 子组件 RatingSelect.vue,派发自定义事件isContent,将this.onlyContent数据传给父级

this. e m i t ( &lt; s p a n c l a s s = &quot; h l j s − s t r i n g &quot; &gt; ′ i s C o n t e n t ′ &lt; / s p a n &gt; , &lt; s p a n c l a s s = &quot; h l j s − k e y w o r d &quot; &gt; t h i s &lt; / s p a n &gt; . o n l y C o n t e n t ) ; &lt; s p a n c l a s s = &quot; h l j s − k e y w o r d &quot; &gt; t h i s &lt; / s p a n &gt; . emit(&lt;span class=&quot;hljs-string&quot;&gt;&#x27;isContent&#x27;&lt;/span&gt;, &lt;span class=&quot;hljs-keyword&quot;&gt;this&lt;/span&gt;.onlyContent); &lt;span class=&quot;hljs-keyword&quot;&gt;this&lt;/span&gt;. emit(<spanclass="hljsstring">isContent</span>,<spanclass="hljskeyword">this</span>.onlyContent);<spanclass="hljskeyword">this</span>.emit(‘selRatings’, this.selectType);

// 父组件 foodInfo.vue 在子组件的模板标签里,使用v-on监控isContent传过来的数据

<v-ratingselect :ratings=“food.ratings” :select-type=“selectType” :only-content=“onlyContent” :desc=“desc” @selRatings=“filterRatings” @isContent=“iscontent”></v-ratingselect>

非父子组件之间通信,vue官方锐减使用vueX,但是这里相较简单,所以采用的是利用给一个空实例eventHub,作为两个组件的中央数据总线,使用this.$root.eventHub.$emit来派发自定义事件,使用this.$root.eventHub.$on来监控
这里特别说明$root,官方解释:表示当前组建树的根实例,如果根实例没有父实例,次实例将会是自己

//foodInfo.vue组件派发自定义事件cart.add,传递信息event.target
this. r o o t . e v e n t H u b . root.eventHub. root.eventHub.emit(‘cart.add’, event.target); // 传输点击的目标元素

//Shopcart.vue组件监控cart.add
created() {
// 获取按钮组件的点击的元素,用在drop方法里
this. r o o t . e v e n t H u b . root.eventHub. root.eventHub.on(‘cart.add’, this.drop);
},
methods:{
drop(element){
//to do …
}
}" title="" data-original-title=“复制”>

//main.js
new Vue({
// el: ‘#app’,
router,
template: ‘<App/>’,
components: {
App
},
data: {
eventHub: new Vue() // 给data添加一个 名字为eventHub 的空vue实例,用来传输非父子组件的数据
}
}).$mount(’#app’); // 手动挂载,#app

//foodInfo.vue组件派发自定义事件cart.add,传递信息event.target
this. r o o t . e v e n t H u b . root.eventHub. root.eventHub.emit(‘cart.add’, event.target); // 传输点击的目标元素

//Shopcart.vue组件监控cart.add
created() {
// 获取按钮组件的点击的元素,用在drop方法里
this. r o o t . e v e n t H u b . root.eventHub. root.eventHub.on(‘cart.add’, this.drop);
},
methods:{
drop(element){
//to do …
}
}

4-5、组件提取管理

将相同样式或功能的区块单独提出来,作为一个组件。

另外组件中用到的图片等资源就近维护,即可以考虑在组件文件夹中新建images文件夹。

抽离组件遵循原则:
要尽量遵循单一职责原则,复用性更高,不要设置额外的margin等影响布局的东西

5-css预处理器--stylus

全局安装,安装之前你需要你安装 nodejs

$ npm install stylus -g

index.styl是stylus文件的入口文件,里面使用@import 引入各种styl文件

@import './mixin.styl'
@import './base.styl'
@import './icon.styl'

在入口文件main.js中全局引用index.styl

import 'common/stylus/index.styl';

border-1px($color)
position:relative
&:after
content:’’
display:block
position:absolute
left:0
bottom:0
width:100%
border:1px solid $color
@media(-webkit-min-device-pixel-ratio:1.5),(min-device-pixel-ratio:1.5)
.border-1px
&::after
-webkit-transform:scaleY(0.7)
transform:scaleY(0.7)
@media(-webkit-min-device-pixel-ratio:2),(min-device-pixel-ratio:2)
.border-1px
&::after
-webkit-transform:scaleY(0.5)
transform:scaleY(0.5)
" title="" data-original-title=“复制”>

// 使用stylus可以快速且保证兼容的实现border-1px:
//mixin.styl

border-1px($color)
position:relative
&:after
content:’’
display:block
position:absolute
left:0
bottom:0
width:100%
border:1px solid $color
@media(-webkit-min-device-pixel-ratio:1.5),(min-device-pixel-ratio:1.5)
.border-1px
&::after
-webkit-transform:scaleY(0.7)
transform:scaleY(0.7)
@media(-webkit-min-device-pixel-ratio:2),(min-device-pixel-ratio:2)
.border-1px
&::after
-webkit-transform:scaleY(0.5)
transform:scaleY(0.5)

6-打开app应用,默认显示goods内容

想要达到这种目的,有两种方法,一种是利用重定向,另一种是利用vue-router的导航式编程。

6-1、重定向

//在router的index.js文件中设置,要多写一个对象,指向目标组件
routes: [
    {
      path: '/',
      redirect: '/Goods',// 重定向
      name: 'Goods',
      component: Goods
    },
    {
      path: '/Goods',
      name: 'Goods',
      component: Goods
    },
    {
      path: '/Header',
      name: 'Header',
      component: Header
    },
    {
      path: '/Seller',
      name: 'Seller',
      component: Seller
    },
    {
      path: '/Ratings',
      name: 'Ratings',
      component: Ratings
    }
  ]

6-2、导航式编程

router.push('/Goods');

7-关于eslint

eslint 是一个js代码风格检查器,配合vue-cli脚手架中的热更新,可以很方便的定位和提示错误。在公司多人协作开发时可以确保代码风格保持一致,可以很方便的阅读他人的代码。

刚使用时,会不太习惯,但是坚持下来,自己写的代码越来越整齐规范,越来越漂亮,自己会有很大的满足感。对自己,对他人都是一件非常有益的事!

8-关于其他

8-1、vue2相较vue1有很多地方改动

比如

  • v-for的书写格式,多出:key值,而且必须写

  • transition书写格式不在是在元素标签上写,而是作为一个标签<transition></transition>将目标元素包起来,过渡状态变为4种状态

  • v-el 和 v-ref 都弃用,改为使用ref属性为元素或组件添加标记,通过$refs获取

具体详细内容,请参看官网从vue1.x迁移

8-2、项目运行

安装依赖
npm install

本地开发,开启服务器,浏览器访问http://localhost:8080
npm run dev

构建生产
npm run build

运行打包文件
node prod.server.js

会看到 Listening at http://localhost:9000 在浏览器中打开即可
" title="" data-original-title=“复制”>

克隆项目到本地
git clone https://github.com/JerryYgh/m-eleme.git

安装依赖
npm install

本地开发,开启服务器,浏览器访问http://localhost:8080
npm run dev

构建生产
npm run build

运行打包文件
node prod.server.js

会看到 Listening at http://localhost:9000 在浏览器中打开即可

8-3、手机测试网页技巧

将localhost换成自己的ip,Windows在命令行执行ipconfig查看,mac执行ifconfig查看。

然后复制地址栏地址,进入草料二维码,然后生成二维码,然后用手机扫一扫就可以查看了,前提是,你手机和电脑必须在同一个局域网。

9-学习参考

            </div>
                                            
            <div class="clearfix mt10">
                <ul class="article-operation list-inline pull-left mt15"><li><a target="_blank" href="https://creativecommons.org/licenses/by-nc-nd/4.0/"><img class="mb5" src="https://cdn.segmentfault.com/v-5c8b4d77/global/img/creativecommons-cc.svg" height="20"></a></li><li class="dropdown js__content-ops hidden-xs" data-module="article" data-id="1190000010124638" data-typetext="文章"><a href="javascript:void(0);" class="dropdown-toggle text-muted" data-toggle="dropdown"><i class="fa fa-ellipsis-h" aria-hidden="true"></i></a><ul class="dropdown-menu dropdown-menu-left"><li><a href="#911" data-toggle="modal" data-target="#911" data-action="report">举报</a></li></ul></li></ul>
                <div class="pull-right mt-10 hidden-xs">
                    <div class="widget-share__full" data-text="最新 vue2.x 仿饿了么app商家页面 项目总结" data-url="https://segmentfault.com/a/1190000010124638" data-shorturl="http://sfau.lt/b5QD2M"><div class="widget-share-network sharer-0" style="display: block;"><ul class="sn-inline"><li data-network="weibo"><a href="javascript:void(0);" class="entypo-weibo icon-sn-weibo share-1" data-toggle="tooltip" data-placement="top" title="" data-original-title="分享至新浪微博">新浪微博</a></li><li data-network="wechart"><a href="javascript:void(0);" class="entypo-wechart icon-sn-weixin share-2" data-toggle="tooltip" data-placement="top" title="" data-original-title="分享至微信">微信</a></li><li data-network="twitter"><a href="javascript:void(0);" class="entypo-twitter icon-sn-twitter share-3" data-toggle="tooltip" data-placement="top" title="" data-original-title="分享至 Twitter">Twitter</a></li><li data-network="facebook"><a href="javascript:void(0);" class="entypo-facebook icon-sn-facebook share-4" data-toggle="tooltip" data-placement="top" title="" data-original-title="分享至 Facebook">Facebook</a></li></ul></div><a type="button" class="btn btn-sm shareMore btn-sn-more" data-toggle="popover" data-placement="top" data-url="https://segmentfault.com/a/1190000010124638" data-shorturl="http://sfau.lt/b5QD2M"><span class="icon-sn-dotted" data-original-title="" title=""></span><strong class="visible-xs-inline">•••</strong></a></div>


                </div>
            </div>
            <div class="mt10 text-center mb30"><button type="button" id="mainLike" data-id="1190000010124638" class="btn btn-success btn-lg mr15 "><span id="mainLikeText">赞</span>&nbsp;&nbsp;<span class="seprator">|</span>&nbsp;&nbsp;
                            <span id="mainLikeNum">8 </span></button><button type="button" id="mainBookmark" data-type="article" data-id="1190000010124638" class="btn btn-default btn-lg "><span id="mainBookmarkText">收藏</span>&nbsp;&nbsp;<span class="seprator">|</span>&nbsp;&nbsp;<span id="mainBookmarkNum">58</span></button></div>                
                            <script type="text/javascript">
                OA_show(3);
            </script><div style="text-align: center; line-height: 0; background: #EEE"><a href="https://sponsor.segmentfault.com/ck.php?oaparams=2__bannerid=106__zoneid=3__cb=ca561c89b9__oadest=https%3A%2F%2Fcloud.baidu.com%2Fcampaign%2Fpurchase-2019%2Findex.html%3Ftrack%3Dcp%3Adsp%7Cpf%3Apc%7Cpp%3Achui-sifou-huodong-19caigouji-BCC-wenzhangxiangqingyecipinghengfu-190313%7Cpu%3Awenzhangxiangqingyecipinghengfu-tupian%7Cci%3A2019cgj%7Ckw%3A2107392" target="_blank"><img src="https://sponsor-static.segmentfault.com/6cae8e65e680114942c06542805c262e.png" width="728" height="90" alt="" title="" border="0"></a><div id="beacon_ca561c89b9" style="position: absolute; left: 0px; top: 0px; visibility: hidden;"><img src="https://sponsor.segmentfault.com/lg.php?bannerid=106&amp;campaignid=33&amp;zoneid=3&amp;loc=https%3A%2F%2Fsegmentfault.com%2Fa%2F1190000010124638%3Futm_source%3Dtag-newest&amp;referer=https%3A%2F%2Fwww.baidu.com%2Flink%3Furl%3DgO7UsA_Q5oAGHPW8WiI5DsGDO3nYaXgPbQMUwS_Aw4ygzKWJN65oePuXnOBhM2hbrOzetGAnvlN_IhxyuPPOSenLyVbPJB30-Zg_z0G8BWe%26wd%3D%26eqid%3Db192ef3b00025858000000055c8fae38&amp;cb=ca561c89b9" width="0" height="0" alt="" style="width: 0px; height: 0px;"></div></div>


            <h4 class="pt20 mb15 mt0 border-top">你可能感兴趣的</h4>

            
            <div class="mb15 block">
                <script type="text/javascript">
                    OA_show(4);
                </script><div id="beacon_986174355f" style="position: absolute; left: 0px; top: 0px; visibility: hidden;"><img src="https://sponsor.segmentfault.com/lg.php?bannerid=0&amp;campaignid=0&amp;zoneid=4&amp;loc=https%3A%2F%2Fsegmentfault.com%2Fa%2F1190000010124638%3Futm_source%3Dtag-newest&amp;referer=https%3A%2F%2Fwww.baidu.com%2Flink%3Furl%3DgO7UsA_Q5oAGHPW8WiI5DsGDO3nYaXgPbQMUwS_Aw4ygzKWJN65oePuXnOBhM2hbrOzetGAnvlN_IhxyuPPOSenLyVbPJB30-Zg_z0G8BWe%26wd%3D%26eqid%3Db192ef3b00025858000000055c8fae38&amp;cb=986174355f" width="0" height="0" alt="" style="width: 0px; height: 0px;"></div>

            </div>

                            <div id="paradigm-article-related"><div class="recommend-post mb30"><ul class="widget-links"><li><a href="http://segmentfault.com/a/1190000012917213" title="[vue插件]基于vue2.x的电商图片放大镜插件" target="_blank">[vue插件]基于vue2.x的电商图片放大镜插件</a><span class="text-muted">小包子</span><a class="tag" taget="_blank" href="/t/vue.js">vue.js</a><a class="tag" taget="_blank" href="/t/javascript">javascript</a></li><li><a href="http://segmentfault.com/a/1190000008045579" title="VUE高仿饿了么app" target="_blank">VUE高仿饿了么app</a><span class="text-muted">lea_</span><a class="tag" taget="_blank" href="/t/vue.js">vue.js</a></li><li><a href="http://segmentfault.com/a/1190000010030848" title="vuejs开发H5页面总结" target="_blank">vuejs开发H5页面总结</a><span class="text-muted">晚风轻拂</span><a class="tag" taget="_blank" href="/t/html5">html5</a><a class="tag" taget="_blank" href="/t/javascript">javascript</a><a class="tag" taget="_blank" href="/t/vue.js">vue.js</a></li><li><a href="http://segmentfault.com/a/1190000009334240" title="项目资源和目录设计和mock模拟数据" target="_blank">项目资源和目录设计和mock模拟数据</a><span class="text-muted">线上猛如虎</span><a class="tag" taget="_blank" href="/t/vue.js">vue.js</a></li><li><a href="http://segmentfault.com/a/1190000010226370" title="分享一个vue的生成头像组件" target="_blank">分享一个vue的生成头像组件</a><span class="text-muted">AshleyLv</span><a class="tag" taget="_blank" href="/t/vue.js">vue.js</a><a class="tag" taget="_blank" href="/t/%E7%BB%84%E4%BB%B6%E8%AE%BE%E8%AE%A1">组件设计</a><a class="tag" taget="_blank" href="/t/javascript">javascript</a></li><li><a href="http://segmentfault.com/a/1190000012070824" title="Vuex" target="_blank">Vuex</a><span class="text-muted">DraWarrior</span><a class="tag" taget="_blank" href="/t/vue.js">vue.js</a><a class="tag" taget="_blank" href="/t/vuex">vuex</a></li><li><a href="http://segmentfault.com/a/1190000012510725" title="vue 过渡 动画" target="_blank">vue 过渡 动画</a><span class="text-muted">charles</span><a class="tag" taget="_blank" href="/t/vue.js">vue.js</a></li><li><a href="http://segmentfault.com/a/1190000008611570" title="基于requirejs的vue2项目 (一)" target="_blank">基于requirejs的vue2项目 (一)</a><span class="text-muted">heruiwoniou</span><a class="tag" taget="_blank" href="/t/javascript">javascript</a><a class="tag" taget="_blank" href="/t/vue.js">vue.js</a><a class="tag" taget="_blank" href="/t/requirejs">requirejs</a><a class="tag" taget="_blank" href="/t/node.js">node.js</a></li></ul></div></div>

            
    <div class="comments--news comments--default comments--article 
" data-id="1190000010124638" data-user-id="" data-author-id="1030000009493058 " data-is-admin="null" id="goToReplyArea">
                <div class="mb10 clearfix">
            <strong class="comments-stat pull-left mr10">3 条评论</strong>

                                                <div class="btn-group btn-group-xs pull-right comments-sort btn-group-menu" role="menu">
                    <a href="javascript:;" class="btn btn-default active" data-sort="default">默认排序</a>
                    <a href="javascript:;" class="btn btn-default" data-sort="desc">时间排序</a>
                </div>
                        </div>
            <div class="comments-container">
                            <div class="comments-list">
            <div class="comments-item" data-id="1050000010125667">
        <div class="pull-left">
            <a href="/u/captain_58db88b483779" target="_blank"><img class="avatar-32 " src="https://avatar-static.segmentfault.com/934/487/93448781-59c4ea96d1c4f_big64" alt=""></a>
        </div>
        <div class="comments-content">
            <div class="comment-trigger">
                <div class="pull-right comment-option">
                                            <a href="#911" class="ml10" data-toggle="modal" data-target="#911" data-action="report" data-action-text="举报" data-module="comment" data-id="1050000010125667" data-typetext="评论" data-placement="top" title="举报"><span class="glyphicon glyphicon-flag" aria-hidden="true"></span></a>
                                        </div>
                <strong><a target="_blank" href="/u/captain_58db88b483779">Captain</a></strong>
                <span class="comments-isAuthor hide"></span>
                <span class="comments-date">  ·  2017年07月10日</span>
            </div>

            <div class="fmt mb10"><p>这是慕课网课程吧 老铁 代码跟github上一样样的</p></div>

            <form action="/api/comment/1050000010125667/edit">
                <div class="form-group">
                    <textarea class="editTextarea mono form-control mb10 hidden" rows="1" name="text" style="height: 28px; overflow: hidden; word-wrap: break-word;">这是慕课网课程吧 老铁 代码跟github上一样样的</textarea>
                </div>
            </form>

            <p class="comment-ops not-reply">
                <span class="comments-zan ">
                    <i class="fa fa-thumbs-up mr4" aria-hidden="true"></i>
                    <span class="comments-zan-text">赞</span>
                    <span class="comments-zan-value">+2</span>
                </span>
                
                <span class="ml15 comments-reply-btn">回复</span>

                <span class="pull-right editBtns hidden">
                  <button class="btn btn-link btn-xs cancel" type="button">取消</button>
                  <button class="btn btn-primary btn-xs edit ml10" type="button">保存</button>
                </span>
            </p>

            <div class="reply-list reply-list--empty">

                
                <div class="reply-item reply-item--ops" data-obj="obj">
                    <a class="reply-inner-btn" href="javascript:;">添加回复</a>
                    
                </div>
            </div>


        </div>
    </div>
            <div class="comments-item" data-id="1050000012407126">
        <div class="pull-left">
            <a href="/u/hujian_5a30b9e12bac0" target="_blank"><img class="avatar-32 " src="https://cdn.segmentfault.com/v-5c8b4d77/global/img/user-64.png" alt=""></a>
        </div>
        <div class="comments-content">
            <div class="comment-trigger">
                <div class="pull-right comment-option">
                                            <a href="#911" class="ml10" data-toggle="modal" data-target="#911" data-action="report" data-action-text="举报" data-module="comment" data-id="1050000012407126" data-typetext="评论" data-placement="top" title="举报"><span class="glyphicon glyphicon-flag" aria-hidden="true"></span></a>
                                        </div>
                <strong><a target="_blank" href="/u/hujian_5a30b9e12bac0">护肩</a></strong>
                <span class="comments-isAuthor hide"></span>
                <span class="comments-date">  ·  2017年12月13日</span>
            </div>

            <div class="fmt mb10"><p>大神厉害.<br>我购物车小球过渡动画实现不了,跟你代码没什么区别,尝试很久了解决不了.    方便给予下指导吗?谢谢</p></div>

            <form action="/api/comment/1050000012407126/edit">
                <div class="form-group">
                    <textarea class="editTextarea mono form-control mb10 hidden" rows="1" name="text" style="height: 28px; overflow: hidden; word-wrap: break-word;">大神厉害.

我购物车小球过渡动画实现不了,跟你代码没什么区别,尝试很久了解决不了. 方便给予下指导吗?谢谢

            <p class="comment-ops not-reply">
                <span class="comments-zan ">
                    <i class="fa fa-thumbs-up mr4" aria-hidden="true"></i>
                    <span class="comments-zan-text">赞</span>
                    <span class="comments-zan-value"></span>
                </span>
                
                <span class="ml15 comments-reply-btn">回复</span>

                <span class="pull-right editBtns hidden">
                  <button class="btn btn-link btn-xs cancel" type="button">取消</button>
                  <button class="btn btn-primary btn-xs edit ml10" type="button">保存</button>
                </span>
            </p>

            <div class="reply-list reply-list--empty">

                
                <div class="reply-item reply-item--ops" data-obj="obj">
                    <a class="reply-inner-btn" href="javascript:;">添加回复</a>
                    
                </div>
            </div>


        </div>
    </div>
            <div class="comments-item" data-id="1050000012844814">
        <div class="pull-left">
            <a href="/u/gaolengdeyaonanshen" target="_blank"><img class="avatar-32 " src="https://avatar-static.segmentfault.com/179/319/179319979-59f1ed70961d3_big64" alt=""></a>
        </div>
        <div class="comments-content">
            <div class="comment-trigger">
                <div class="pull-right comment-option">
                                            <a href="#911" class="ml10" data-toggle="modal" data-target="#911" data-action="report" data-action-text="举报" data-module="comment" data-id="1050000012844814" data-typetext="评论" data-placement="top" title="举报"><span class="glyphicon glyphicon-flag" aria-hidden="true"></span></a>
                                        </div>
                <strong><a target="_blank" href="/u/gaolengdeyaonanshen">高冷的尧男神</a></strong>
                <span class="comments-isAuthor hide"></span>
                <span class="comments-date">  ·  2018年01月15日</span>
            </div>

            <div class="fmt mb10"><p>打包会出现跨域错误是怎么回事啊</p></div>

            <form action="/api/comment/1050000012844814/edit">
                <div class="form-group">
                    <textarea class="editTextarea mono form-control mb10 hidden" rows="1" name="text" style="height: 28px; overflow: hidden; word-wrap: break-word;">打包会出现跨域错误是怎么回事啊</textarea>
                </div>
            </form>

            <p class="comment-ops not-reply">
                <span class="comments-zan ">
                    <i class="fa fa-thumbs-up mr4" aria-hidden="true"></i>
                    <span class="comments-zan-text">赞</span>
                    <span class="comments-zan-value"></span>
                </span>
                
                <span class="ml15 comments-reply-btn">回复</span>

                <span class="pull-right editBtns hidden">
                  <button class="btn btn-link btn-xs cancel" type="button">取消</button>
                  <button class="btn btn-primary btn-xs edit ml10" type="button">保存</button>
                </span>
            </p>

            <div class="reply-list reply-list--empty">

                
                <div class="reply-item reply-item--ops" data-obj="obj">
                    <a class="reply-inner-btn" href="javascript:;">添加回复</a>
                    
                </div>
            </div>


        </div>
    </div>
        </div>
<div class="comments-loading hide">载入中...</div>
    <div class="comments-more hide"><a href="javascript:;">显示更多评论</a></div>


                                <div class="comments-box" id="goToReplyEditor">
            <div class="pull-left">
                <img class="avatar-32 " src="https://cdn.segmentfault.com/v-5c8b4d77/global/img/user-128.png" alt="">
            </div>
            <div class="comments-box-content">
                <form action="/api/article/1190000010124638/comments/add">
                    <div class="form-group mb0">
                        <textarea name="text" rows="3" class="form-control" placeholder="文明社会,理性评论"></textarea>
                        <div class="mt15 text-right">
                            <button type="button" class="hide"></button>
                            <button class=" btn btn-primary" type="button">发布评论</button>
                        </div>
                    </div>
                </form>
            </div>
        </div>
                                                    </div>
</div>


                                
            
            

        </div><!-- /.main -->


        <div class="col-md-3 side hidden-sm hidden-xs mt30" style="height: 16123px;">
                                            
            <div class="mb25 hidden-md hidden-sm hidden-xs">
<img src="https://static.segmentfault.com/sponsor/20190319.png" alt="Planets" usemap="#gridsMap" width="255" height="136">
<map name="gridsMap" id="gridsMap"><area shape="rect" target="_blank" onmouseover="SFGridAd.d(this)" onmouseout="SFGridAd.e(this)" onclick="SFGridAd.c(1750000018316831)" coords="102,68,153,85" href="https://www.fundebug.com/?utm_source=sf_lattice_ad" stitle="一行代码搞定BUG监控"><area shape="rect" target="_blank" onmouseover="SFGridAd.d(this)" onmouseout="SFGridAd.e(this)" onclick="SFGridAd.c(1750000018414920)" coords="68,102,119,119" href="https://fapiao.easyapi.com/" stitle="EasyAPI发票管理,让您的产品网站、电商平台立支持开具电子发票功能"><area shape="rect" target="_blank" onmouseover="SFGridAd.d(this)" onmouseout="SFGridAd.e(this)" onclick="SFGridAd.c(1750000018473522)" coords="0,102,51,119" href="http://www.h5ds.com/" stitle="手机H5页面自动生成工具,可导出HTML代码"><area shape="rect" target="_blank" onmouseover="SFGridAd.d(this)" onmouseout="SFGridAd.e(this)" onclick="SFGridAd.c(1750000018502421)" coords="221,0,255,34" href="https://www.3tee.cn/index.html?source=segmentfault" stitle="纯浏览器视频会议,兼容微信小程序,快速嵌入,浙江大华股份等都在用"><area shape="rect" target="_blank" onmouseover="SFGridAd.d(this)" onmouseout="SFGridAd.e(this)" onclick="SFGridAd.c(1750000018514150)" coords="204,102,221,119" href="https://bz.zzzmh.cn/" stitle="极简壁纸 - 高清美图桌面壁纸网站"><area shape="rect" target="_blank" onmouseover="SFGridAd.d(this)" onmouseout="SFGridAd.e(this)" onclick="SFGridAd.c(1750000018548220)" coords="34,34,102,51" href="https://www.kuibuke.com/exam" stitle="刷遍bat面试题,大厂offer不用愁"></map>
<div style="text-align: center;"><a style="text-align:center; color:#9E9E9E; font-size:12px" href="/sponsor">想在上方展示你的广告?</a></div>
        <script async="" src="https://static.segmentfault.com/sponsor/20190319.js"></script>
</div>

                            <style>
                .job-recommend-area a:not(:last-of-type) {margin-bottom:10px; display: block}
                .job-recommend-area a:hover {text-decoration: none;}
            </style>
            <div class="hidden-md">
                <div class="job-recommend">
                  <h3 class="job-title">推广链接</h3>
                  <div class="job-recommend-area">
                                            <script type="text/javascript">
                        OA_show(7);
                        OA_show(9);
                        OA_show(10);
                        OA_show(15);
                        OA_show(16);
                    </script><a href="https://sponsor.segmentfault.com/ck.php?oaparams=2__bannerid=56__zoneid=7__cb=42dfa6e10b__oadest=https%3A%2F%2Fsegmentfault.com%2Fls%2F1650000011318558" target="_blank"><strong>大神的PHP 进阶之路</strong><br>

亿级 PV 项目的架构梳理,性能提升实战


iView 实战系列课程

[限时优惠] 知名开源组件库作者讲授

Vue 技术栈开发实战

iView 核心开发者带你掌握 Vue 精髓

Java 微服务实践课

上千人学习过的微服务实栈课

                  </div>
                </div>
                <style>
                .job-recommend {margin-bottom: 30px;}
                .job-title {
                    font-size: 14px;
                    color: #017E66;
                    font-weight: 500;
                    background: #BFE6D7;
                    margin: 0;
                    padding-top: 6px;
                    padding-bottom: 6px;
                    text-align: center;
                }
                .job-recommend-area {
                  padding: 13px;
                  border: 3px solid #EBF7F3;
                  border-top: none;
                }
                </style>
                
                                </div>

                            
            <div class="hidden-md ad-should-be-fixed stuckMenu" style="display: none; position: relative; top: 0px;">
                <div class="mb25 block">
                    <script type="text/javascript">
                        OA_show(1);
                    </script><script async="" src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>

width="255" height="213" vspace="0" hspace="0" scrolling="no" allowfullscreen="true" id="aswift_1">

                </div>
            </div>
            <div class="post-nav hidden-xs side-outline hidden-sm" style="display: none; position: sticky; top: 238px; margin-top: 0px;">
                <div class="panel panel-default widget-outline">
                    <div class="panel-heading">目录</div>
                    <div class="panel-body">
                        <div class="nav-body" style="overflow: scroll; top: 0px; height: 444px;">
                            <div class="highlight-title" style="top: 0px; height: 0px; display: none;"></div>
                            <ul class="articleIndex"><li class=""><a href="#articleHeader0">最新vue2.x仿饿了么app 商家页面 项目总结</a></li><li style="list-style:none;"><ul><li class=""><a href="#articleHeader1">前言</a></li><li style="list-style:none;"><ul><li class=""><a href="#articleHeader2">实现功能:</a></li></ul></li></ul></li><li style="list-style:none;"><ul><li class=""><a href="#articleHeader3">1-项目结构分析:</a></li><li class=""><a href="#articleHeader4">2-各组件之间的关系:</a></li><li class=""><a href="#articleHeader5">3-开发过程问题汇总:</a></li><li style="list-style:none;"><ul><li class=""><a href="#articleHeader6">3-1、better-scroll插件在移动端使用时需要设置click:true,否则移动端滑动无效</a></li><li class=""><a href="#articleHeader7">3-2、分开设置css样式:</a></li><li class=""><a href="#articleHeader8">3-3、sticky-footer布局</a></li><li class=""><a href="#articleHeader9">3-4、要求自适应的布局</a></li><li class=""><a href="#articleHeader10">3-5、背景模糊效果</a></li><li class=""><a href="#articleHeader11">3-6、transition过渡</a></li><li class=""><a href="#articleHeader12">3-7、seller组件:</a></li><li class=""><a href="#articleHeader13">3-8、缓存数据</a></li><li class=""><a href="#articleHeader14">3-9、解析url,得到商家信息,包括id,name,在获取数据时,直接赋值,商家的id或name会被丢掉</a></li><li class=""><a href="#articleHeader15">3-10、goods,ratings,seller组件之间切换时会重新渲染</a></li></ul></li></ul></li><li style="list-style:none;"><ul><li><a href="#articleHeader16">4-项目总结</a></li><li style="list-style:none;"><ul><li class=""><a href="#articleHeader17">4-1、vue-router</a></li><li class=""><a href="#articleHeader18">4-2、vue-resource</a></li><li class=""><a href="#articleHeader19">4-3、Object.assign(target, source1, source2);</a></li><li class=""><a href="#articleHeader20">4-4、组件间通讯</a></li><li class=""><a href="#articleHeader21">4-5、组件提取管理</a></li></ul></li></ul></li><li style="list-style:none;"><ul><li class=""><a href="#articleHeader22">5-css预处理器--stylus</a></li><li class=""><a href="#articleHeader23">6-打开app应用,默认显示goods内容</a></li><li style="list-style:none;"><ul><li class=""><a href="#articleHeader24">6-1、重定向</a></li><li class=""><a href="#articleHeader25">6-2、导航式编程</a></li></ul></li></ul></li><li style="list-style:none;"><ul><li class=""><a href="#articleHeader26">7-关于eslint</a></li><li class=""><a href="#articleHeader27">8-关于其他</a></li><li class=""><a href="#articleHeader28">8-1、vue2相较vue1有很多地方改动</a></li><li class=""><a href="#articleHeader29">8-2、项目运行</a></li><li class=""><a href="#articleHeader30">8-3、手机测试网页技巧</a></li><li class=""><a href="#articleHeader31">9-学习参考</a></li></ul></li></ul>
                        </div>
                    </div>
                </div>
            </div>

            
        </div><!-- /.side -->
    </div>
</div>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值