eHungry 仿饿了么

  • git 操作

git checkout -b dev        // 创建新分支 dev

git push origin dev        // 代码推送到 dev

------------------------------- 代码合并到主分支 ------------------------------

git checkout master

git merge dev

  • 安装 stylus 依赖包

npm install stylus stylus-loader --save-dev

common/stylus/mixins.styl -------- 复用样式代码

    1. $green = #02a774;
    2. $yellow = #F5A100;
    3. $bc = #e4e4e4;
    4. // 一像素下边框
    5. bottom-border-1px($color)
    6. position relative
    7. border none
    8. &:after
    9. content ''
    10. position absolute
    11. left 0
    12. bottom 0
    13. width 100%
    14. height 1px
    15. background-color $color
    16. transform scaleY(0.5)
    17. // 一像素上边框
    18. top-border-1px($color)
    19. position relative
    20. &::before
    21. content ''
    22. position absolute
    23. z-index 200
    24. left 0
    25. top 0
    26. width 100%
    27. height 1px
    28. background-color $color
    29. //根据像素比缩放1px像素边框
    30. @media only screen and (-webkit-device-pixel-ratio: 2 )
    31. .border-1px
    32. &::before
    33. transform scaleY(.5)
    34. @media only screen and (-webkit-device-pixel-ratio: 3 )
    35. .border-1px
    36. &::before
    37. transform scaleY(.333333)
    38. //根据像素比来使用 2x图 3x图
    39. bg-image($url)
    40. background-image: url($url + "@2x.png")
    41. @media (-webkit-min-device-pixel-ratio: 3),(min-device-pixel-ratio: 3)
    42. background-image: url($url + "@3x.png")
    43. //清除浮动
    44. clearFix()
    45. *zoom 1
    46. &::after
    47. content ''
    48. display block
    49. clear both
  • 入口文件配置 main.js
    1. import Vue from "vue"
      import App from "./App.vue"
    2.  
    3. new Vue({
    4. el: "#app",
    5. /*
    6. components: {App},
    7. template: "<App/>"
    8. */
    9. /* 或者
    10. render: function (createElement){createElement(App)}
    11. */
    12. render: h=>h(App)
    13. })
  • 路由器 router 配置 ---- 记得在 main.js 中加入 router 

npm install vue-router --save

    1. import Vue from "vue"
    2. import App from "./App.vue"
    3.  
    4. import Home from "../pages/Home"
    5. import Search from "../pages/Search"
    6. import Order from "../pages/Order"
    7. import Personal from "../pages/Personal"
    8.  
    9. Vue.use(VueRouter)
    10. new VueRouter({
    11. mode: "history", // 去掉 #
    12. routes: [
    13. {path: "/home", component: Home},
    14. {path: "/search", component: Search},
    15. {path: "/order", component: Order},
    16. {path: "/personal", component: Personal},
    17. {path: "/", redirect: "/home"}
    18. ]
    19. })
  • 代理 /config/index.js ---- 改完配置要重启

dev:{

proxyTable: {    // 更强大的代理

"api" :{    // 代理 /api 开头的请求

target: "http://localhost:5000",    // 代理目标的基础路径

changeOrigin: true,    // 支持跨域

pathRewrite: {    // 重写路径: 去掉开头的 /api

"^/api": ""

}

},

"reqBaidu" :{    // 代理 /baidu 开头的请求

target: "http://localhost:5000",    // 代理目标的基础路径

changeOrigin: true,    // 支持跨域

pathRewrite: {    // 重写路径: 去掉开头的 /baidu

"^/baidu": ""

}

}

}

}

  • /src/api/ajax.js

import axios from "ajax"

export default function ajax(url, data={}, method="GET"){

return new Promise((resolve, reject)=>{

let promise = null

if(method==="GET"){

// params 指的是 query 请求字符串

promise = axios.get(url, {params: data})

}else if(method==="POST"){

promise = axios.post(url, data)

}

// promise.then(response=>resolve(response.data)).catch(err=>reject(err))

promise.then(response=>resolve(response.data)).catch(err=>alert(err))    // 外部无需多个 try catch 处理 reject

})

}

  • /src/api/request.js -------- 参考接口文档,请求后台数据

import ajax from "./ajax"

// BASE = "http://localhost:5000"

const BASE = "/api"    // proxTable 代理 /api 开头的请求

export function requestAddress(longitudelatitude){

// 根据 纬度,经度 获取店铺位置

return ajax(`/position/${longitude},${latitude}`);

}

export const requestCategory = ()=>ajax("/index_category");    // 获取商品分类

export const requestShops = (longitude, latitude)=>ajax("/shops", {latitude, longitude});    // 获取店

  • Vuex.Store

npm install vuex --save

/src/vuex/store/index.js

    1. import Vue from "vue";
    2. import Vuex from "vuex";
    3.  
    4. import state from "./state"
    5. import mutations from "./mutations"
    6. import actions from "./actions"
    7. import getters from "./getters"
    8.  
    9. Vue.use(Vuex);
    10. export default new Vuex.Store({
    11. state,
    12. mutations,
    13. actions,
    14. getters
    15. })

/src/vuex/store/state.js

    1. export default {
    2. isLoginRegister: false,
    3.  
    4. longitude: "116.36867",
    5. latitude: "40.10038",
    6.  
    7. position: {},
    8. categorysArr: [],
    9. shops: []
    10. }

/src/vuex/store/actions.js

    1. import {
    2. TOLOGINREGISTER,
    3. SAVE_POSITION,
    4. SAVE_CATEGORY,
    5. SAVE_SHOPS
    6. } from "./mutation-type"
    7.  
    8. import {requestPosition, requestCategory, requestShops} from "../../api"
    9.  
    10. export default {
    11. toLoginRegister({commit}, to){
    12. commit(TOLOGINREGISTER, to);
    13. },
    14. async getPosition({commit, state}){
    15. const {longitude, latitude} = state
    16. const result = await requestPosition(longitude, latitude)
    17. if(result.code === 0){
    18. commit(SAVE_POSITION, result.data)
    19. }
    20. },
    21. async getCategorys({commit}){
    22. const result = await requestCategory()
    23. if(result.code === 0){
    24. commit(SAVE_CATEGORY, result.data)
    25. }
    26. },
    27. async getShops({commit, state}){
    28. const {longitude, latitude} = state
    29. const result = await requestShops(longitude, latitude)
    30. if(result.code === 0){
    31. commit(SAVE_SHOPS, result.data)
    32. }
    33. }
    34. }

/src/vuex/store/mutations.js

    1. import {
    2. TOLOGINREGISTER,
    3. SAVE_POSITION,
    4. SAVE_CATEGORY,
    5. SAVE_SHOPS
    6. } from "./mutation-type"
    7.  
    8. export default {
    9. [TOLOGINREGISTER] (state, to) {
    10. state.isLoginRegister = to
    11. },
    12.  
    13. [SAVE_POSITION] (state, position) {
    14. state.position = position
    15. },
    16.  
    17. [SAVE_CATEGORY] (state, categorysArr) {
    18. state.categorysArr = categorysArr
    19. },
    20.  
    21. [SAVE_SHOPS] (state, shops) {
    22. state.shops = shops
    23. }
    24. }

/src/vuex/store/mutations-type.js

    1. export const TOLOGINREGISTER = "toLoginRegister"
    2.  
    3. export const SAVE_POSITION = "save_position"
    4. export const SAVE_CATEGORY = "save_category"
    5. export const SAVE_SHOPS = "save_shops"

/src/vuex/store/getter.js

  • 路由元信息 - 状态数据共享

/src/router/router.js

    1. import Vue from "vue";
    2. import VueRouter from "vue-router";
    3.  
    4. import Home from "../pages/Home/Home"
    5. import Search from "../pages/Search/Search"
    6. import Order from "../pages/Order/Order"
    7. import Personal from "../pages/Personal/Personal"
    8. import LoginRegister from "../pages/LoginRegister/LoginRegister"
    9.  
    10. Vue.use(VueRouter);
    11. export default new VueRouter({
    12. mode: "history",
    13. routes: [
    14. {path:"/home", component: Home, meta:{showFooter: true}},
    15. {path:"/search", component: Search, meta:{showFooter: true}},
    16. {path:"/order", component: Order, meta:{showFooter: true}},
    17. {path:"/personal", component: Personal, meta:{showFooter: true}},
    18.  
    19. {path:"/login_register", component: LoginRegister},
    20. {path:"/", redirect: "/home"},
    21. ]
    22. })
  • /src/App.vue
    1. <template>
    2. <div>
    3. <router-view></router-view>
    4. <FooterNav v-show="$route.meta.showFooter"></FooterNav>
    5. </div>
    6. </template>
    7. ...
    1. watch: {
    2. categorysArr () {
    3. // 在下次 DOM 更新后,再执行回调
    4. this.$nextTick(()=>{
    5. const mySwiper = new Swiper('.swiper-container', {
    6. loop: true, // 循环模式选项
    7. pagination: { // 如果需要分页器
    8. el: '.swiper-pagination',
    9. },
    10. })
    11. })
    12. }
    13. },

图片验证码点击,重新请求

改变 img 的 src,每次都必须赋新的值

this.$refs.captcha.src = "http://localhost:5000/captcha?curTime="+Data.now

容联-云通讯

Account SID

Auth Token

Rest URL 都一样

测试号码必须填

SMS 普通短信 sms_utilt.js 配置

MMS 彩信

-----------------------------------------------------------------------------------------

cookie 分两类

会话 cookie - 保存在浏览器运行时内存中,关闭浏览器后,数据清除 - 会话的标识

持久化 cookie - 保存在浏览器管理的文件中,关闭浏览器后,数据还在

session 会话 - 保存在服务器端,用于存储数据的容器 ---------- session 依赖于 cookie,浏览器可以禁用 cookie

会话: 浏览器的打开到关闭,整个过程是一个会话

session 对象保存在服务器存储数据的容器

一旦产生这个对象,服务器会自动向浏览器返回一个响应 cookie,用来保存 sessioin 的ID - connect.sid = sessionID

在服务器通过 request.session 获取到 session

session 如果有: 找到对应的 session 对象

session 如果不存在: 创建新的 session 对象

第一次登录,会将 user_id 存入 session

刷新浏览器, user_id 还是可以从 浏览器获取的

但是 session 通常与 cookie 进行连用

  • 会话 cookie ---- 关闭浏览器,则数据清空
  • 持久化 cookie ---- 关闭浏览器,数据还在

-------------------------------------------------------------------------------------

  • mini-ui

npm install --save mint-ui

npm install --save-dev babel-     // 实现按需打包

/src/mock/data.json

处理后台接口还不可使用的情况,拦截 ajax ,返回 模拟数据

/src/mock/mockServer.js -------- 使用 mockjs 来 mock 模拟数据接口

import Mock from "mockjs"

import data from "./data.json" -------- 内部会自动解析 JSON 对象 成 js 对象

// mock 三个接口,开始监视改变, 特别的是这个代码不会向外暴露什么

Mock.mock("/goods", {code: 0, data: data.goods})

Mock.mock("/ratings", {code: 0, data: data.ratings})

Mock.mock("/info", {code: 0, data: data.info})

/src/main.js

import "./mock/mockServer"        // 保证 mockjs 被打包执行,从而组件可以使用

4

4

  • Vuex.Store 模块化

管理的状态

{home:???, user:???, shop:???}

/vuex/store/modules/

home.js

  • 1

/src/vuex/store/index.js

import home from "./modules/home"

import user from "./modules/user"

import shop from "./modules/shop"

export default new Vuex.Store({

modules: {

home,

user,

shop

}

})

npm install --save better-scroll

new BScroll(".wrapper", {})

    1. mounted () {
    2. this.$nextTick(()=>{
    3. if(!this.bScroll){
    4. this.bScroll = new BScroll(".header_nav", {
    5. click: true,
    6. scrollX: true
    7. })
    8. }else{
    9. this.bScroll.refresh()
    10. }
    11. })
    12. }
  • ...mapGetter(["xxx"])

模块化 时,无论写在模块内还是公共 getter,都是一样的,

只是在编写 getter 时,注意不能重名,和 state 的指向

  • 单例对象

某种类型的实例对象只存在一个

在轮播图 逻辑的元素,在控制外层元素时,只能用 v-show 而不能用 v-if

  • moment 自定义过滤器 - 日期处理 /src/filters/index.js

import Vue from 'vue'

import moment from "moment"

Vue.filter('data-format', funtion(vue, formatStr="YYYY-MM-DD HH:mm:ss"){

return moment().format(formatStr)

})

  • 优化 router ---- 路由懒加载效果

1. 使用 import 函数: 被引入的模块单独打包 (生成有一个单独的一个 js 文件)

2. 配置的 component 是“返回 import() 得到的模块的函数”, 只有当请求对应的 path 才会执行函数,得到组件

  • 图片懒加载 vue-lazyload ---- 其实 mint-ui 内置了这个库
  • main.js

---- 内部会指定一个指令 lazy

  • 在组件中 <img v-lazy="food.image"/>
  • 构建打包app

1. 无 # 哈希路由 ---- 配置 404 页面, 将 404 页面指向 目标页面 index.html ---- 单页面应用

在页面刷新,就会向后台请求路由,而路由是前台路由

将服务器进行 中间件拦截 - 将前台路由请求 返回 public 页面

2. 使用 /#/ 哈希路由 ---- 始终会被当成前台路由处理,而不会当成后台路由处理

  • 将 store 保存到 Vue 上 ---- 很实用
  • 导航守卫

是 vue-router 提供的 下面 2 个方面的功能

  • 监视路由跳转
  • 控制路由跳转

应用

在跳转到界面之前,对用户进行检查限制

在界面离开之前进行收尾工作

分类

全局守卫 ---- 针对任意路由跳转

/src/router/index.js

    1. import Vue from "vue";
    2. import VueRouter from "vue-router";
    3.  
    4. // import Home from "../pages/Home/Home"
    5. import Shop from "../pages/Shop/Shop"
    6. import Goods from "../pages/Shop/Goods/Goods"
    7. import Ratings from "../pages/Shop/Ratings/Ratings"
    8. import Info from "../pages/Shop/Info/Info"
    9.  
    10. // import Search from "../pages/Search/Search"
    11. // import Order from "../pages/Order/Order"
    12. // import Personal from "../pages/Personal/Personal"
    13. import LoginRegister from "../pages/LoginRegister/LoginRegister"
    14.  
    15. const Home = ()=>import("../pages/Home/Home")
    16. const Search = ()=>import("../pages/Search/Search")
    17. const Order = ()=>import("../pages/Order/Order")
    18. const Personal = ()=>import("../pages/Personal/Personal")
    19.  
    20. Vue.use(VueRouter);
    21. const router = new VueRouter({
    22. mode: "history",
    23. routes: [
    24. {path:"/home", component: Home, meta:{showFooter: true}},
    25. {
    26. path:"/shop",
    27. component: Shop,
    28. children: [
    29. {path:"/shop/goods", component: Goods},
    30. {path:"/shop/ratings", component: Ratings},
    31. {path:"/shop/info", component: Info},
    32. {path:"/shop", redirect: "/shop/goods"},
    33. ]
    34. },
    35.  
    36. {path:"/search", component: Search, meta:{showFooter: true}},
    37. {path:"/order", component: Order, meta:{showFooter: true}},
    38. {path:"/personal", component: Personal, meta:{showFooter: true}},
    39.  
    40. {path:"/login_register", component: LoginRegister},
    41.  
    42. {path:"/", redirect: "/home"},
    43. ]
    44. })
    45.  
    46. /*************************************************/
    47. const paths = ["/login_register"]
    48. router.beforeEach((to, from, next)=>{ // 设置全局守卫
    49. const path = to.path
    50. if(paths.indexOf(path)>=0){
    51. if(Vue.store.state.user.userInfo._id){ // 在 main.js 中保存 store
    52. return next("/personal")
    53. }
    54. }
    55. next() // 其他路由请求,放行
    56. })
    57. /*************************************************/
    58.  
    59. export default router
  • 全局前置守卫: 在准备跳转到某个路由组件之前 (在开发中用的较多)

router.beforeEach((to, from, next)=>{

})

to ---- 目标路由

from ---- 当前路由

next ---- 函数

next() ---- 执行下一个守卫回调,如果没有,就跳转到目标路由

next(false) ---- 不继续执行,跳转流程在此处中断,不会跳转到目标路由组件

next(path) ---- 跳转到指定的另一个路由

next() ---- 传入的回调函数会在组件对象创建后对象,即延后执行回调 - 且将组件对象传入回调函数 即 this

  • 全局后置守卫: 在跳转到某个路由组件之后

router.afterEach((to, from)=>{

})

组件守卫 ----

beforeRouteEner(){        // 在跳转到当前组件之前,无法访问这个组件的组件对象  this

}

beforeRouteUpdate(){        // 在当前组件显示更新前调用,可以访问 this

}

beforeRouteLeave(){        // 在当前组件离开前调用,可以访问 this

}

  • 构建打包

  • 配置前台路由 - 404 页面

/src/router/index.js

在数组最后,配置{path: "/*", NotFound}

vue_eHungry 饿了么的更多相关文章

  1. 解析ListView联动的实现--仿饿了么点餐界面

    一.博客的由来 大神王丰蛋哥 之前一篇博客仿饿了点餐界面2个ListView联动(http://www.cnblogs.com/wangfengdange/p/5886064.html) 主要实现了2 ...

  2. IOS-小项目(饿了么 网络部分 简单实现)

    在介绍小项目之前,在此说明一下此代码并非本人所写,我只是随笔的整理者. 在介绍之前先展现一下效果图. 看过效果图大家应该很熟悉了,就是饿了么的一个界面而已,值得注意的是,实现时并没有采用本地连接,而是 ...

  3. 饿了么基于Vue2.0的通用组件开发之路(分享会记录)

    Element:一套通用组件库的开发之路 Element 是由饿了么UED设计.饿了么大前端开发的一套基于 Vue 2.0 的桌面端组件库.今天我们要分享的就是开发 Element 的一些心得. 官网 ...

  4. 用vue2 +vue-router2 + es6 +webpack 高仿饿了么app(干货满满)

    #高仿饿了么app商家详情 (vue2 +vue-router2 + es6 +webpack )   ##demo [demo 地址](http://liangxiaojuan.github.io/ ...

  5. java中的单例模式(懒汉式+饿汉式)

    什么是单例模式: 单例模式既只能在自己本类中创建有且唯一的一个实例(姑且不考虑映射的情况)通过方法将该实例对外公开 第一种:单例模式-懒汉式 既调用getInstance()方法返回实例之前判断有没有 ...

  6. 仿饿了点餐界面2个ListView联动

    如图是效果图 是仿饿了的点餐界面 1.点击左侧的ListView,通过在在适配器中设置Item来改变颜色,再通过notifyDataSetInvalidated来刷新并用lv_home.setSele ...

  7. C++的单例模式与线程安全单例模式(懒汉/饿汉)

    1 教科书里的单例模式 我们都很清楚一个简单的单例模式该怎样去实现:构造函数声明为private或protect防止被外部函数实例化,内部保存一个private static的类指针保存唯一的实例,实 ...

  8. 这交互炸了:饿了么是怎么让Image变成详情页的

    这交互炸了:饿了么是怎么让Image变成详情页的 晚上叫外卖,打开饿了么,发现推了一个版本,更新以后,点开了个鸡腿,哇,交互炫炸了. 本文同步自wing的地方酒馆 不过还是有槽点.我是无意中才发现可以 ...

  9. (转)Singleton 单例模式(懒汉方式和饿汉方式)

    原文地址:http://www.cnblogs.com/kkgreen/archive/2011/09/05/2166868.html 单例模式的概念: 单例模式的意思就是只有一个实例.单例模式确保某 ...

随机推荐

  1. Git Gerrit使用

    Git Gerrit 操作都用 git bash操作: 如果想用 cmd 或者 PowerShell,系统环境变量 Path 添加 Git 安装路径,如: C:\Program Files (x86) ...

  2. SQL Server数据库读写分离提高并发性

    在一些大型的网站或者应用中,单台的SQL Server 服务器可能难以支撑非常大的访问压力.很多人在这时候,第一个想到的就是一个解决性能问题的利器——负载均衡.遗憾的是,SQL Server 的所有版 ...

  3. Nginx故障排错及一个网站小实例

    Nginx访问403错误: 1.没有首页文件 2.没有权限 例:chmod  700 /application/nginx/html/index.html 3.nginx.conf配置文件和首页文件不 ...

  4. js中的简单数据类型和复杂数据类型的存储

    基本类型存储的是值而复杂数据类型也叫引用类型存储的是对象的地址如0x00001而在栈中存的是变量数值和函数参数 堆中存的是对象和数组 堆栈空间分配 栈(操作系统):由操作系统自动分配释放 ,存放函数的 ...

  5. DeepLearning.ai学习笔记(五)序列模型 -- week2 序列模型和注意力机制

    一.基础模型 假设要翻译下面这句话: "简将要在9月访问中国" 正确的翻译结果应该是: "Jane is visiting China in September" ...

  6. java控台输入

    import java.util.Scanner;//访问util包的Scanner(控台输入) public class HelloWorld {public static void main(St ...

  7. laravel whereDoesntHave

    select * from `feeds` where not exists (select * from `black_lists` where `feeds`.`user_id` = `black ...

  8. kettle使用文件导入到Postgresql出现如下几种问题的总结

    1.kettle使用文件导入到Postgresql出现如下几种问题的总结: kettle使用文件导入到Postgresql出现如下几种问题的总结: .第一种错误,报错如ERROR: extra dat ...

  9. 11 个超棒的 jQuery 分步指引插件

    当一个网站或者一个Web应用推出新功能时,为了让用户了解你的站点(或应用)如何操作,往往都会在站点(应用)中添加一个分步指引的效果.然而这样的效果,对于不懂原生JS的同学来说,是件很头痛的事情. 下面 ...

  10. 在.NET开发中的单元测试工具之(1)——NUnit

    NUnit介绍 NUnit是一个专门针对于.NET来写的单元测试框架,它是xUnit体系中的一员,在xUnit体系中还有针对Java的JUnit和针对C++的CPPUnit,在开始的时候NUnit和x ...