基于vue.js,仿饿了么外卖实战。
第一次使用vue-resource
处处理后台数据,这次修改了一下,使用了axios。
npm i stylus --save
npm i stylus-loader --save
分为头部和内容区域,头部使用组件:
<template>
<div id="app">
<v-header></v-header>
</div>
</template>
<script>
import header from './components/header/header';
export default {
components: {
'v-header': header
}
};
</script>
内容区域使用flex
布局三等分,style部分如下:
#app
.tab
display flex
width 100%
height 40px
line-height 40px
.tab-item
flex 1
text-align center
使用vue-router
创建单页应用:
<div class="tab">
<div class="tab-item active">
<router-link to="/goods">商品</router-link>
</div>
<div class="tab-item">
<router-link to="/ratings">评论</router-link>
</div>
<div class="tab-item">
<router-link to="/seller">商家</router-link>
</div>
</div>
<router-view></router-view>
在main.js
引入:
// import goods from '../src/components/goods/goods';
// 为了让自己写的更少,在webpack.base.conf.js中加入下面这行代码
'components': resolve(__dirname, '../src/components')
// 在main.js中可以简写为:
import goods from 'components/goods/goods';
我们知道,点击的router-link,vue会自动给它增加class: router-link-active
,为了写的更少,我们在main.js
中配置:
linkActiveClass: 'active'
这样我们在写样式时,直接用.active
就可以了!
概括如下:如果页面内容不够长的时候,页脚块粘贴在视窗底部;如果内容足够长时,页脚块会被内容向下推送。具体介绍看这篇文章:https://www.w3cplus.com/css3/css-secrets/sticky-footers.html
better-scroll is a plugin which is aimed at solving scrolling circumstances on the mobile side (PC supported already).
- 先安装:
npm i better-scroll --save
- 引入:
import BScroll from 'better-scroll';
- 在
menu-wrapper
中加入ref="menuWrapper"
methods: {
_initScroll() {
this.menuScroll = new BScroll(this.$refs.menuWrapper, {});
this.foodsScroll = new BScroll(this.$refs.foodsWrapper, {});
}
}
CLI tool to aid in migration from Vue 1.x to 2.0. It scans files for Vue-specific code and provides detailed warnings when deprecated patterns are found. It cannot reliably catch every deprecation, but should get you 80% of the way there.
这个工具可以很好的解决Vue 1.x to 2.0之间的问题,下面是我遇到的问题:
1. Replace "vue-router": "^3.0.1" with "vue-router": "^2.0.0", then run: npm install
Line 20: package.json
Reason: If you are using pre-2.0
Vue Router through NPM, you have to update it in your package.json file
More info: http://vuejs.org/guide/migration-vue-router.html#
2. Replace this.$dispatch('cart.add', event.target) to use a global event bus or vuex (see link below for implementation details)
Line 34: src/components/cartcontrol/cartcontrol.vue
Reason: $dispatch and $broadcast
have been removed because the pattern doesn't scale well
More info: http://vuejs.org/guide/migration.html#dispatch-and-broadcast
我们可以看到,它很好的告诉了我们解决方案。
在子组件ratingselect.vue
中使用了@click="select(2, $event)"
和@click="toggleContent"
这两个点击事件。使用vue.$emit
通知父组件。
methods: {
select(type, event) {
if (!event._constructed) {
return;
}
// 通知父组件
this.$emit('select', type);
},
toggleContent(event) {
if (!event._constructed) {
return;
}
this.image = !this.image;
this.$emit('toggle');
}
},
在父组件中我们使用这样的方式绑定:
<ratingselect @select="selectRating" @toggle="toggleContent"></ratingselect>
selectRating(type) {
this.selectType = type;
this.$nextTick(() => {
this.scroll.refresh();
});
},
toggleContent() {
this.onlyContent = !this.onlyContent;
this.image = !this.image;
this.$nextTick(() => {
this.scroll.refresh();
});
}
这样就实现了父子组件间的通信。
<div class="time">{{rating.rateTime | formatDate}}</div>
filters: {
formatDate(time) {
let date = new Date(time);
return formatDate(date, 'yyyy-MM-DD hh:mm');
}
}
引入:加入花括号的原因是使用的不是export default
import {formatDate} from '../../common/js/date';
主要用于保留组件状态或避免重新渲染。
<keep-alive>
<router-view :seller="seller"></router-view>
</keep-alive>
在package.json
中,我们有
"build": "node build/build.js"
我们在终端运行npm run build
,运行完毕后,我们可以在目录中看到多了一个dist
文件夹。这就是我们打包好的。
根目录下新增一个文件,命名为data.json
,代码内容模拟后台数据,data.json文件
基于vue2.0,在webpack.dev.conf.js
中加入如下代码:
// 在const portfinder = require('portfinder')下新增
// 使用 npm i express --save 安装express
const express = require('express');
const app = express();
const appData = require('../data.json');
const seller = appData.seller;
const goods = appData.goods;
const ratings = appData.ratings;
const apiRoutes = express.Router();
app.use('/api', apiRoutes);
找到devServer
,并写入如下代码:
before(app) {
app.get('/api/seller', (req, res) => {
res.json({
errno: 0,
data: seller
});
//接口返回json数据,上面配置的数据seller就赋值给data请求后调用
}),
app.get('/api/goods', (req, res) => {
res.json({
errno: 0,
data: goods
});
}),
app.get('/api/ratings', (req, res) => {
res.json({
errno: 0,
data: ratings
});
})
}
使用localhost:8080/api/seller
查看json数据。