├── .eslintignore ├── .gitignore ├── README.md ├── babel.config.js ├── package.json ├── public ├── favicon.ico └── index.html ├── screenshots ├── alipay.jpg ├── app_pay.gif ├── cart.gif ├── clearCart.gif ├── comment.gif ├── index3.gif ├── location.gif ├── makeOrder.gif ├── other.gif ├── scan_pay.gif └── weChat.jpg ├── src ├── App.vue ├── api │ ├── index.js │ ├── location.js │ ├── order.js │ ├── request.js │ ├── restaurant.js │ ├── upload.js │ └── user.js ├── assets │ ├── default-avatar.png │ ├── friend_img.png │ ├── home-active.png │ ├── home.png │ ├── index-active.png │ ├── index.png │ ├── loading.gif │ ├── logo.png │ ├── my.png │ ├── nothing.png │ ├── order-active.png │ ├── order.png │ ├── pay_adv.png │ ├── restaurant.jpg │ ├── shoploading.png │ ├── skeleton_restaurant.jpg │ ├── star24_half@2x.png │ ├── star24_off@2x.png │ ├── star24_on@2x.png │ ├── user-banner.png │ └── 我的收藏.jpg ├── components │ ├── addressInfo.vue │ ├── alertTip.vue │ ├── bottom.vue │ ├── head.vue │ ├── littleCart.vue │ ├── loading.vue │ ├── search.vue │ ├── selector.vue │ └── star.vue ├── config.js ├── main.js ├── plugins │ └── qrcode.js ├── router │ └── index.js ├── stores │ ├── index.js │ ├── modules │ │ ├── address.js │ │ ├── cart.js │ │ └── restaurant.js │ └── mutation-types.js ├── style │ ├── common.scss │ └── mixin.scss ├── utils │ └── auth.js └── views │ ├── 404 │ └── error.vue │ ├── Index │ ├── Index.vue │ └── nav.vue │ ├── cart │ └── cart.vue │ ├── category │ └── category.vue │ ├── confirm_order │ ├── children │ │ ├── address.vue │ │ └── children │ │ │ └── add_address.vue │ └── confirm_order.vue │ ├── home │ ├── children │ │ ├── address.vue │ │ ├── collection.vue │ │ ├── comment.vue │ │ ├── footprint.vue │ │ ├── friend.vue │ │ └── thank_record.vue │ └── home.vue │ ├── index │ └── nearby_shops.vue │ ├── location │ └── location.vue │ ├── login │ └── login.vue │ ├── order │ ├── comment.vue │ ├── order.vue │ ├── order_detail.vue │ └── star.vue │ ├── pay │ ├── pay.vue │ └── scan.vue │ ├── search │ └── search.vue │ └── store │ ├── comment │ └── comment.vue │ ├── menu │ ├── bottom.vue │ └── menu.vue │ ├── seller │ └── seller.vue │ ├── store.vue │ └── store_detail.vue └── vue.config.js /.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules/* 2 | src/plugins/* -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | # local env files 6 | .env.local 7 | .env.*.local 8 | 9 | # Log files 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | 14 | # Editor directories and files 15 | .idea 16 | .vscode 17 | *.suo 18 | *.ntvs* 19 | *.njsproj 20 | *.sln 21 | *.sw? 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## 更新(2019/6/5) ## 2 | 项目已经发布一年多的时间,vue-cli已经升级到3.0,很多依赖也都更新了导致项目跑不起来,这里简单的把项目升级到vue-cli3版本,接下来准备发布小程序版本的,感谢大家的支持。 3 | 4 | ## 关于 ## 5 | 2019届大三学生,前段时间一直想一个人单独开发一个较为完整的项目,在众多应用中,考虑之后选择了美团外卖来模仿,这段时间就利用课余时间进行开发,前端用vue+vuex+vue-router+axios,因为需要用到定位和支付等功能,需要后端配合,而且想要做真正数据交互,所以用express(基于nodejs的框架)做后台,数据库用NOSQL的mongodb。 前端项目包含20多个路由,涉及到vue文件有40个,功能设计登录,定位,浏览商品,加购物车,下订单,支付(支持微信和支付宝的扫码支付和调起app支付),评价,个人信息更改,是一个较为完整的项目。 6 | 7 | ### 注意:此项目为个人开发实践练习,不作为任何商业用途 8 | 9 | 10 | 11 | ## 社区地址 12 |   掘金地址:>[https://juejin.im/post/5aca46e2f265da238c3af4ca](https://juejin.im/post/5aca46e2f265da238c3af4ca) 13 | 14 |   思否地址:>[https://segmentfault.com/a/1190000014267516?utm_source=index-hottest](https://segmentfault.com/a/1190000014267516?utm_source=index-hottest) 15 | ## 功能 ## 16 | - 登录/注销 17 | - IP定位 18 | - 搜索地址 19 | - 获取商店(计算当前位置和商店的距离) 20 | - 加购物车 21 | - 下订单 22 | - 支付(支持微信和支付宝的扫码支付和调起app支付) 23 | - 评价 24 | - 头像上传(用了七牛云存储) 25 | - 图片懒加载 26 | 27 | 28 | ## 技术栈 ## 29 | - Webpack-cli搭建项目 30 | - Vue全家桶(vue+vuex+vue-router) 31 | - CSS预处理器SCSS 32 | - axios与后端进行请求数据 33 | - 七牛云存储图片 34 | - 支付宝和微信支付 35 | - 使用better-scroll滚动 36 | - Express搭建后端服务 37 | - Mongoose对MongoDB进行便捷操作 38 | - 使用Charles抓取数据 39 | 40 | 41 | ## 效果演示 42 | ### 主界面 ### 43 | ![主界面](screenshots/index3.gif) 44 | ### 定位和搜索 ### 45 | ![定位](screenshots/location.gif) 46 | ### 扫码支付 ### 47 | ![扫码支付](screenshots/scan_pay.gif) 48 | ### APP支付 ### 49 | ![调用APP支付](screenshots/app_pay.gif) 50 | ### 我的购物车 ### 51 | ![购物车](screenshots/cart.gif) 52 | ### 清除购物车 ### 53 | ![清除购物车](screenshots/clearCart.gif) 54 | ### 评论 ### 55 | ![评论](screenshots/comment.gif) 56 | ### 其它 ### 57 | ![其它](screenshots/other.gif) 58 | ### 还有一些其它功能就不放图了哈 ### 59 | 60 | ## 线上地址 ## 61 | http://39.108.3.12 62 | 请用谷歌浏览器然后开启移动端浏览,如果要调用APP支付就需要用手机自带浏览器打开,然后支付时选择调起APP支付 63 | 64 | ## 说明 65 |    后端项目地址:>[GitHub:https://github.com/zwStar/meituan-backend](https://github.com/zwStar/meituan-backend) 66 | 67 | ## 未完待续 ## 68 | 还有商家管理PC端还没写完,等写完再开源出来 69 | 70 | ## 项目部署 71 | 72 | 阿里云 CentOS 7.4 64位 73 | 74 | ## 项目运行 75 | 76 | ``` 77 | 项目运行之前,请确保系统已经安装以下应用 78 | 1、node 79 | 2、mongodb 80 | ``` 81 | 82 | ``` 83 | git clone https://github.com/zwStar/vue-meituan.git 84 | 85 | cd vue-meituan 86 | 87 | npm install 88 | 89 | npm run serve 90 | 91 | 访问: http://localhost:8080 (确保后端项目服务已开启) 92 | 93 | ``` 94 | 95 | # 项目布局 96 | 97 | ``` 98 | . 99 | ├── api 后端接口 100 | ├── config.js 运行配置 101 | ├── assets 静态资源 102 | ├── components 全局组件 103 | ├── router 路由 104 | ├── store vuex 105 | ├── styles 全局样式 106 | ├── views 页面 107 | ├── App.vue 入口页面 108 | ├── main.js 入口 109 | ├── .babelrc babel-loader 配置 110 | ├── .gitignore git 忽略项 111 | ├── favicon.ico favicon图标 112 | ├── index.html html模板 113 | └── package.json package.json 114 | . 115 | 116 | ``` 117 | 118 | 119 | ## 写在最后 ## 120 | 因为还是学生,平时最多也是和同学一起开发,并没有参与过真正的企业团队开发,所以应该有很多地方做的不是很好,欢迎各位大佬们给我提一些意见。 121 | 122 | 如果有问题,您可以在 Issues 中提问哈。 123 | 如果您对这个项目感兴趣,请Star支持下,谢谢! 124 | # License 125 | MIT 126 | 127 | # 打赏 128 | 如果觉得这个项目对你有帮忙,可以请我喝杯奶茶哈 129 | 130 | 微信: 131 | 132 | 微信 133 | 支付宝: 134 | 135 | 支付宝 136 | 137 | 138 | 139 | 140 | 141 | 142 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/app' 4 | ], 5 | plugins: [ 6 | [ 7 | 'component', 8 | { 9 | 'libraryName': 'mint-ui', 10 | 'style': true 11 | } 12 | ] 13 | ] 14 | }; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-meituan", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve", 7 | "build": "vue-cli-service build", 8 | "lint": "vue-cli-service lint" 9 | }, 10 | "dependencies": { 11 | "axios": "^0.18.0", 12 | "better-scroll": "^1.15.2", 13 | "core-js": "^2.6.5", 14 | "fastclick": "^1.0.6", 15 | "mint-ui": "^2.2.13", 16 | "vue": "^2.6.10", 17 | "vue-router": "^3.0.6", 18 | "vuex": "^3.1.1" 19 | }, 20 | "devDependencies": { 21 | "@vue/cli-plugin-babel": "^3.8.0", 22 | "@vue/cli-plugin-eslint": "^3.8.0", 23 | "@vue/cli-service": "^3.8.0", 24 | "babel-eslint": "^10.0.1", 25 | "babel-plugin-component": "^1.1.1", 26 | "eslint": "^5.16.0", 27 | "eslint-plugin-vue": "^5.0.0", 28 | "node-sass": "^4.12.0", 29 | "sass-loader": "^7.1.0", 30 | "vue-template-compiler": "^2.6.10" 31 | }, 32 | "eslintConfig": { 33 | "root": true, 34 | "env": { 35 | "node": true 36 | }, 37 | "extends": [ 38 | "plugin:vue/essential", 39 | "eslint:recommended" 40 | ], 41 | "rules": { 42 | "no-console": 2, 43 | "no-debugger": 2 44 | }, 45 | "parserOptions": { 46 | "parser": "babel-eslint" 47 | } 48 | }, 49 | "postcss": { 50 | "plugins": { 51 | "autoprefixer": {} 52 | } 53 | }, 54 | "browserslist": [ 55 | "> 1%", 56 | "last 2 versions" 57 | ] 58 | } 59 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/null0509/vue-meituan/054f229b5078638fc31fbbcb22f21bca32c11e7e/public/favicon.ico -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | vue-meituan 9 | 10 | 11 | 14 |
15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /screenshots/alipay.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/null0509/vue-meituan/054f229b5078638fc31fbbcb22f21bca32c11e7e/screenshots/alipay.jpg -------------------------------------------------------------------------------- /screenshots/app_pay.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/null0509/vue-meituan/054f229b5078638fc31fbbcb22f21bca32c11e7e/screenshots/app_pay.gif -------------------------------------------------------------------------------- /screenshots/cart.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/null0509/vue-meituan/054f229b5078638fc31fbbcb22f21bca32c11e7e/screenshots/cart.gif -------------------------------------------------------------------------------- /screenshots/clearCart.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/null0509/vue-meituan/054f229b5078638fc31fbbcb22f21bca32c11e7e/screenshots/clearCart.gif -------------------------------------------------------------------------------- /screenshots/comment.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/null0509/vue-meituan/054f229b5078638fc31fbbcb22f21bca32c11e7e/screenshots/comment.gif -------------------------------------------------------------------------------- /screenshots/index3.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/null0509/vue-meituan/054f229b5078638fc31fbbcb22f21bca32c11e7e/screenshots/index3.gif -------------------------------------------------------------------------------- /screenshots/location.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/null0509/vue-meituan/054f229b5078638fc31fbbcb22f21bca32c11e7e/screenshots/location.gif -------------------------------------------------------------------------------- /screenshots/makeOrder.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/null0509/vue-meituan/054f229b5078638fc31fbbcb22f21bca32c11e7e/screenshots/makeOrder.gif -------------------------------------------------------------------------------- /screenshots/other.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/null0509/vue-meituan/054f229b5078638fc31fbbcb22f21bca32c11e7e/screenshots/other.gif -------------------------------------------------------------------------------- /screenshots/scan_pay.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/null0509/vue-meituan/054f229b5078638fc31fbbcb22f21bca32c11e7e/screenshots/scan_pay.gif -------------------------------------------------------------------------------- /screenshots/weChat.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/null0509/vue-meituan/054f229b5078638fc31fbbcb22f21bca32c11e7e/screenshots/weChat.jpg -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 22 | 23 | 30 | -------------------------------------------------------------------------------- /src/api/index.js: -------------------------------------------------------------------------------- 1 | import config from '../config' 2 | import router from '@/router' 3 | import {removeInfo} from '@/utils/auth' 4 | 5 | const baseURL = config.baseURL; 6 | const axios = require('axios').create({ 7 | baseURL: baseURL, //api请求的baseURL 8 | timeout: 0, 9 | withCredentials: true, // 允许跨域 cookie 10 | headers: {'X-Requested-With': 'XMLHttpRequest'}, 11 | maxContentLength: 2000, 12 | transformResponse: [function (data) { 13 | try { 14 | data = JSON.parse(data); 15 | } catch (e) { 16 | data = {}; 17 | } 18 | if (data.status === 403) { 19 | removeInfo(); 20 | router.push('/login'); 21 | } 22 | return data; 23 | }] 24 | }) 25 | 26 | 27 | // get 28 | export const _get = (req) => { 29 | return axios.get(req.url, {params: req.data}) 30 | } 31 | 32 | // post 33 | export const _post = (req) => { 34 | return axios({method: 'post', url: `/${req.url}`, data: req.data}) 35 | } 36 | 37 | //patch 38 | export const _put = (req) => { 39 | return axios({method: 'put', url: `/${req.url}`, data: req.data}) 40 | } 41 | 42 | //delete 43 | export const _delete = (req) => { 44 | return axios({method: 'delete', url: `/${req.url}`, data: req.data}) 45 | } 46 | 47 | //post and no withCredentials 48 | export const _postNoWithCredentials = (req) => { 49 | return axios({method: 'post', url: `/${req.url}`, data: req.data,withCredentials:false}) 50 | } 51 | -------------------------------------------------------------------------------- /src/api/location.js: -------------------------------------------------------------------------------- 1 | import {_get} from './index' 2 | 3 | //定位搜索建议 4 | export const suggestion = (data) =>{ 5 | let req = { 6 | data:data 7 | }; 8 | req.url = 'v1/suggestion' 9 | return _get(req); 10 | } 11 | 12 | //定位当前位置 13 | export const location = (data) =>{ 14 | let req = { 15 | data 16 | } 17 | req.url = 'v1/location' 18 | return _get(req) 19 | } 20 | -------------------------------------------------------------------------------- /src/api/order.js: -------------------------------------------------------------------------------- 1 | import {_get, _post} from './index' 2 | 3 | //提交订单 4 | export const submitOrder = (data) => { 5 | let req = { 6 | data, 7 | url: 'v1/order' 8 | }; 9 | return _post(req); 10 | } 11 | 12 | //准备支付 13 | export const initPay = (data) => { 14 | let req = { 15 | data, 16 | url: 'v1/pay' 17 | } 18 | return _post(req); 19 | } 20 | 21 | //获取订单信息 22 | export const orderInfo = (data) => { 23 | let req = { 24 | url: `v1/order/${data.order_id}` 25 | } 26 | return _get(req); 27 | } 28 | 29 | //获取我的订单 30 | export const orders = (data) => { 31 | let req = { 32 | data, 33 | url: 'v1/orders' 34 | } 35 | return _get(req); 36 | } 37 | 38 | //订单评论 39 | export const makeComment = (data) => { 40 | let req = { 41 | data, 42 | url: 'v1/comment' 43 | } 44 | return _post(req) 45 | } 46 | 47 | 48 | //请求支付 49 | export const requestPay = (data) => { 50 | let req = { 51 | data, 52 | url: '/https://pay.ispay.cn/core/api/request/pay/' 53 | } 54 | return _post(req) 55 | } 56 | 57 | //监听扫码支付状态 58 | export const listenStatus = (data) => { 59 | let req = { 60 | data, 61 | url: 'v1/listen_status' 62 | } 63 | return _get(req) 64 | } 65 | 66 | -------------------------------------------------------------------------------- /src/api/request.js: -------------------------------------------------------------------------------- 1 | import {_get, _post, _put} from './index' 2 | 3 | export const sendLogin = (data) => { 4 | let req = { 5 | data 6 | }; 7 | req.url = 'admin/login' 8 | return _post(req); 9 | } 10 | //获取某个商家具体信息 11 | export const getRestaurant = (data) => { 12 | let req = { 13 | data 14 | }; 15 | req.url = 'v1/restaurant' 16 | return _get(req); 17 | } 18 | //获取一定数量的商家 19 | export const getRestaurants = (data) => { 20 | let req = { 21 | data 22 | }; 23 | req.url = 'v1/restaurants' 24 | return _get(req); 25 | } 26 | 27 | //新增收货地址 28 | export const addAddress = (data) => { 29 | let req = { 30 | data 31 | }; 32 | req.url = 'admin/address' 33 | return _post(req); 34 | }; 35 | 36 | //获取收货地址 37 | export const getAddress = (data) => { 38 | let req = {data}; 39 | req.url = 'admin/address' 40 | return _get(req); 41 | }; 42 | 43 | //添加进购物车 44 | export const addShoppingCart = (data) => { 45 | let req = { 46 | data 47 | }; 48 | req.url = 'v1/cart' 49 | return _post(req); 50 | } 51 | 52 | //从购物车减少商品数量 53 | export const reduceShoppingCart = (data) => { 54 | let req = { 55 | data 56 | }; 57 | req.url = 'v1/cart' 58 | return _put(req); 59 | } 60 | 61 | //获取订单 62 | export const getOrder = (data) => { 63 | let req = { 64 | data 65 | }; 66 | req.url = 'v1/order' 67 | return _get(req); 68 | } 69 | -------------------------------------------------------------------------------- /src/api/restaurant.js: -------------------------------------------------------------------------------- 1 | import {_get, _put} from './index' 2 | 3 | //获取一定数量的商家 4 | export const getRestaurants = (data) => { 5 | let req = { 6 | data: data, 7 | url: 'v1/restaurants' 8 | }; 9 | return _get(req); 10 | } 11 | 12 | 13 | //获取某个商家具体信息 14 | export const getRestaurant = (data) => { 15 | let req = { 16 | url: `v1/restaurant/${data.restaurant_id}` 17 | }; 18 | return _get(req); 19 | } 20 | 21 | //获取食物 22 | export const getFoods = (data) => { 23 | let req = { 24 | url: `v1/food/${data.restaurant_id}` 25 | }; 26 | return _get(req); 27 | } 28 | 29 | //从购物车减少商品数量 30 | export const reduceShoppingCart = (data) => { 31 | let req = { 32 | data, 33 | url: 'v1/cart' 34 | }; 35 | return _put(req); 36 | } 37 | 38 | //输入关键词搜索餐馆 39 | export const searchRestaurant = (data) => { 40 | let req = { 41 | data, 42 | url: 'v1/search/restaurant' 43 | } 44 | return _get(req); 45 | } 46 | 47 | //获取评论 48 | export const restaurantComment = (data) => { 49 | let req = { 50 | data, 51 | url: 'v1/comment' 52 | }; 53 | return _get(req); 54 | } 55 | 56 | -------------------------------------------------------------------------------- /src/api/upload.js: -------------------------------------------------------------------------------- 1 | import {_get, _postNoWithCredentials} from './index' 2 | //获取七牛云上次凭证 3 | export const uploadToken = (data) => { 4 | let req = { 5 | data, 6 | url: 'service/uploadtoken' 7 | }; 8 | return _get(req); 9 | } 10 | 11 | //上传 12 | export const upload = (data) => { 13 | let formData = new FormData(); 14 | Object.keys(data).forEach(key => { 15 | formData.append(key, data[key]) 16 | }) 17 | let req = { 18 | data: formData, 19 | url: '/upload-z2.qiniup.com/' 20 | } 21 | return _postNoWithCredentials(req); 22 | } 23 | -------------------------------------------------------------------------------- /src/api/user.js: -------------------------------------------------------------------------------- 1 | import {_get, _post, _delete} from './index' 2 | 3 | //获取用户所有地址 4 | export const getAllAddress = (data) => { 5 | let req = { 6 | data, 7 | url: 'admin/all_address' 8 | }; 9 | return _get(req); 10 | } 11 | 12 | //获取指定收货地址 13 | export const getAddress = (data) => { 14 | let req = { 15 | data, 16 | url: 'admin/address' 17 | } 18 | return _get(req) 19 | } 20 | 21 | //添加收获地址 22 | export const add_address = (data) => { 23 | let req = { 24 | data, 25 | url: 'admin/address' 26 | } 27 | return _post(req); 28 | } 29 | 30 | export const updateAddress = (data) =>{ 31 | let req = { 32 | data, 33 | url: 'admin/update_address' 34 | } 35 | return _post(req) 36 | } 37 | 38 | //删除收货地址 39 | export const deleteAddress = (data) => { 40 | let req = { 41 | data, 42 | url: 'admin/address' 43 | } 44 | return _delete(req) 45 | } 46 | 47 | //登录 48 | export const login = (data) => { 49 | let req = { 50 | data, 51 | url: 'admin/user_login' 52 | } 53 | return _post(req); 54 | } 55 | 56 | //获取用户信息 57 | export const userInfo = (data) => { 58 | let req = { 59 | data, 60 | url: 'admin/user_info' 61 | } 62 | return _get(req); 63 | } 64 | 65 | //改变用户头像 66 | export const changeAvatar = (data) => { 67 | let req = { 68 | data, 69 | url: 'admin/change_avatar' 70 | } 71 | return _post(req) 72 | } 73 | 74 | //获取我的评论 75 | export const comment = (data) => { 76 | let req = { 77 | data, 78 | url: 'v1/my_comment' 79 | } 80 | return _get(req); 81 | } 82 | 83 | export const deleteComment = (data) => { 84 | let req = { 85 | data, 86 | url: 'v1/comment' 87 | } 88 | return _delete(req); 89 | } 90 | 91 | -------------------------------------------------------------------------------- /src/assets/default-avatar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/null0509/vue-meituan/054f229b5078638fc31fbbcb22f21bca32c11e7e/src/assets/default-avatar.png -------------------------------------------------------------------------------- /src/assets/friend_img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/null0509/vue-meituan/054f229b5078638fc31fbbcb22f21bca32c11e7e/src/assets/friend_img.png -------------------------------------------------------------------------------- /src/assets/home-active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/null0509/vue-meituan/054f229b5078638fc31fbbcb22f21bca32c11e7e/src/assets/home-active.png -------------------------------------------------------------------------------- /src/assets/home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/null0509/vue-meituan/054f229b5078638fc31fbbcb22f21bca32c11e7e/src/assets/home.png -------------------------------------------------------------------------------- /src/assets/index-active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/null0509/vue-meituan/054f229b5078638fc31fbbcb22f21bca32c11e7e/src/assets/index-active.png -------------------------------------------------------------------------------- /src/assets/index.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/null0509/vue-meituan/054f229b5078638fc31fbbcb22f21bca32c11e7e/src/assets/index.png -------------------------------------------------------------------------------- /src/assets/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/null0509/vue-meituan/054f229b5078638fc31fbbcb22f21bca32c11e7e/src/assets/loading.gif -------------------------------------------------------------------------------- /src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/null0509/vue-meituan/054f229b5078638fc31fbbcb22f21bca32c11e7e/src/assets/logo.png -------------------------------------------------------------------------------- /src/assets/my.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/null0509/vue-meituan/054f229b5078638fc31fbbcb22f21bca32c11e7e/src/assets/my.png -------------------------------------------------------------------------------- /src/assets/nothing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/null0509/vue-meituan/054f229b5078638fc31fbbcb22f21bca32c11e7e/src/assets/nothing.png -------------------------------------------------------------------------------- /src/assets/order-active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/null0509/vue-meituan/054f229b5078638fc31fbbcb22f21bca32c11e7e/src/assets/order-active.png -------------------------------------------------------------------------------- /src/assets/order.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/null0509/vue-meituan/054f229b5078638fc31fbbcb22f21bca32c11e7e/src/assets/order.png -------------------------------------------------------------------------------- /src/assets/pay_adv.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/null0509/vue-meituan/054f229b5078638fc31fbbcb22f21bca32c11e7e/src/assets/pay_adv.png -------------------------------------------------------------------------------- /src/assets/restaurant.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/null0509/vue-meituan/054f229b5078638fc31fbbcb22f21bca32c11e7e/src/assets/restaurant.jpg -------------------------------------------------------------------------------- /src/assets/shoploading.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/null0509/vue-meituan/054f229b5078638fc31fbbcb22f21bca32c11e7e/src/assets/shoploading.png -------------------------------------------------------------------------------- /src/assets/skeleton_restaurant.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/null0509/vue-meituan/054f229b5078638fc31fbbcb22f21bca32c11e7e/src/assets/skeleton_restaurant.jpg -------------------------------------------------------------------------------- /src/assets/star24_half@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/null0509/vue-meituan/054f229b5078638fc31fbbcb22f21bca32c11e7e/src/assets/star24_half@2x.png -------------------------------------------------------------------------------- /src/assets/star24_off@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/null0509/vue-meituan/054f229b5078638fc31fbbcb22f21bca32c11e7e/src/assets/star24_off@2x.png -------------------------------------------------------------------------------- /src/assets/star24_on@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/null0509/vue-meituan/054f229b5078638fc31fbbcb22f21bca32c11e7e/src/assets/star24_on@2x.png -------------------------------------------------------------------------------- /src/assets/user-banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/null0509/vue-meituan/054f229b5078638fc31fbbcb22f21bca32c11e7e/src/assets/user-banner.png -------------------------------------------------------------------------------- /src/assets/我的收藏.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/null0509/vue-meituan/054f229b5078638fc31fbbcb22f21bca32c11e7e/src/assets/我的收藏.jpg -------------------------------------------------------------------------------- /src/components/addressInfo.vue: -------------------------------------------------------------------------------- 1 | 49 | 50 | 66 | 67 | 155 | -------------------------------------------------------------------------------- /src/components/alertTip.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 19 | 20 | 59 | -------------------------------------------------------------------------------- /src/components/bottom.vue: -------------------------------------------------------------------------------- 1 | 2 | 32 | 33 | 45 | 46 | 81 | -------------------------------------------------------------------------------- /src/components/head.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 48 | 49 | 78 | -------------------------------------------------------------------------------- /src/components/littleCart.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 25 | 26 | 56 | -------------------------------------------------------------------------------- /src/components/loading.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 9 | 10 | 29 | -------------------------------------------------------------------------------- /src/components/search.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 33 | 34 | 79 | -------------------------------------------------------------------------------- /src/components/selector.vue: -------------------------------------------------------------------------------- 1 | 12 | 50 | 51 | 95 | -------------------------------------------------------------------------------- /src/components/star.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 30 | 31 | 56 | -------------------------------------------------------------------------------- /src/config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | baseURL: 'http://39.108.3.12:3000', //后端地址 3 | // baseURL: 'http://127.0.0.1:3000', 4 | domain: 'http://p3d0ne50u.bkt.clouddn.com/', //七牛云存储地址 5 | } 6 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | // The Vue build version to load with the `import` command 2 | // (runtime-only or standalone) has been set in webpack.base.conf with an alias. 3 | import Vue from 'vue' 4 | import App from './App' 5 | import router from './router' 6 | import store from './stores' 7 | 8 | import Head from '@/components/head' 9 | import Bottom from '@/components/bottom' 10 | import Star from '@/components/star' 11 | import AlertTip from '@/components/alertTip' 12 | import Loading from '@/components/loading' 13 | import FastClick from 'fastclick' 14 | 15 | //全局注册组件 16 | Vue.component('v-head', Head); 17 | Vue.component('v-bottom', Bottom); 18 | Vue.component('v-star', Star); 19 | Vue.component('alert-tip', AlertTip); 20 | Vue.component('v-loading',Loading); 21 | 22 | Vue.config.productionTip = false 23 | 24 | if ('addEventListener' in document) { 25 | document.addEventListener('DOMContentLoaded', function() { 26 | FastClick.attach(document.body); 27 | }, false); 28 | } 29 | 30 | 31 | /* eslint-disable no-new */ 32 | new Vue({ 33 | router, 34 | store, 35 | render: h => h(App), 36 | }).$mount('#app') 37 | -------------------------------------------------------------------------------- /src/router/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Router from 'vue-router' 3 | 4 | Vue.use(Router) 5 | 6 | export default new Router({ 7 | routes: [ 8 | { 9 | path: '/', 10 | redirect: '/index' 11 | }, 12 | { 13 | path: '/index', 14 | name: '首页', 15 | component: r => require.ensure([], () => r(require('@/views/index/index')), 'Index'), 16 | meta: {keepAlive: true}, 17 | }, 18 | { 19 | path: '/category', 20 | name: '分类', 21 | component: r => require.ensure([], () => r(require('@/views/category/category'), 'CATEGORY')) 22 | }, 23 | { 24 | path: '/order', 25 | name: '我的订单', 26 | component: r => require.ensure([], () => r(require('@/views/order/order'), 'Order')), 27 | children: [ 28 | { 29 | path: 'comment', 30 | name: '作评价', 31 | component: r => require.ensure([], () => r(require('@/views/order/comment'), 'MakeComment')) 32 | } 33 | ] 34 | }, 35 | { 36 | path: '/search', 37 | name: '搜索商家', 38 | component: r => require.ensure([], () => r(require('@/views/search/search')), 'Search') 39 | }, 40 | { 41 | path: '/location', 42 | name: '定位', 43 | component: r => require.ensure([], () => r(require('@/views/location/location'), 'Location')) 44 | }, 45 | { 46 | path: '/add_address', 47 | name: '添加地址', 48 | component: r => require.ensure([], () => r(require('@/views/confirm_order/children/children/add_address'), 'Add_Address')), 49 | children: [ 50 | { 51 | path: 'location', 52 | name: '地址定位', 53 | component: r => require.ensure([], () => r(require('@/views/location/location'), 'Location')) 54 | } 55 | ] 56 | }, 57 | { 58 | path: '/home', 59 | name: '我的', 60 | component: r => require.ensure([], () => r(require('@/views/home/home'), 'Home')), 61 | keepAlive: true, 62 | children: [ 63 | { 64 | path: 'address', 65 | name: '我的收获地址', 66 | component: r => require.ensure([], () => r(require('@/views/home/children/address'), 'MyAddress')) 67 | }, 68 | { 69 | path: 'collection', 70 | name: '我的收藏', 71 | component: r => require.ensure([], () => r(require('@/views/home/children/collection'), 'Collection')) 72 | }, 73 | { 74 | path: 'thank', 75 | name: '答谢记录', 76 | component: r => require.ensure([], () => r(require('@/views/home/children/thank_record'), 'ThankRecord')) 77 | }, 78 | { 79 | path: 'footprint', 80 | name: '我的足迹', 81 | component: r => require.ensure([], () => r(require('@/views/home/children/footprint'), 'FootPrint')) 82 | }, 83 | { 84 | path: 'friend', 85 | name: '我的好友', 86 | component: r => require.ensure([], () => r(require('@/views/home/children/friend'), 'Friend')) 87 | }, 88 | { 89 | path: 'comment', 90 | name: '我的评论', 91 | component: r => require.ensure([], () => r(require('@/views/home/children/comment'), 'MyComment')) 92 | } 93 | ] 94 | }, 95 | { 96 | path: '/login', 97 | name: '登录', 98 | component: r => require.ensure([], () => r(require('@/views/login/login'), 'Login')) 99 | }, 100 | { 101 | path: '/confirm_order', 102 | name: '确认订单', 103 | component: r => require.ensure([], () => r(require('@/views/confirm_order/confirm_order'), 'ConfirmOrder')), 104 | children: [{ 105 | path: 'address', 106 | name: '订单收货地址', 107 | component: r => require.ensure([], () => r(require('@/views/confirm_order/children/address'), 'Address')) 108 | }] 109 | }, 110 | { 111 | path: '/store', 112 | component: r => require.ensure([], () => r(require('@/views/store/store'), 'Store')), 113 | children: [ 114 | { 115 | path: 'menu', 116 | name: '菜单', 117 | component: r => require.ensure([], () => r(require('@/views/store/menu/menu'), 'Menu')) 118 | }, 119 | { 120 | path: 'comment', 121 | name: '评论', 122 | component: r => require.ensure([], () => r(require('@/views/store/comment/comment'), 'Comment')) 123 | }, 124 | { 125 | path: 'seller', 126 | name: '商家信息中心', 127 | component: r => require.ensure([], () => r(require('@/views/store/seller/seller'), 'Seller')) 128 | }, 129 | { 130 | path: '', 131 | redirect: '/store/menu' 132 | } 133 | ] 134 | }, 135 | { 136 | path: '/cart', 137 | name: '购物车', 138 | component: r => require.ensure([], () => r(require('@/views/cart/cart'), 'CART')) 139 | }, 140 | { 141 | path: '/pay', 142 | name: '支付', 143 | component: r => require.ensure([], () => r(require('@/views/pay/pay'), 'PAY')) 144 | }, 145 | { 146 | path: '/order_detail', 147 | name: '订单详情', 148 | component: r => require.ensure([], () => r(require('@/views/order/order_detail'), 'OrderDetail')) 149 | }, 150 | { 151 | path: '/error', 152 | name: '找不到该页面', 153 | component: r => require.ensure([], () => r(require('@/views/404/error'), 'Error')) 154 | }, 155 | { 156 | path: '*', 157 | redirect: '/error' 158 | } 159 | ] 160 | }) 161 | -------------------------------------------------------------------------------- /src/stores/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Vuex from 'vuex' 3 | Vue.use(Vuex) 4 | import cart from './modules/cart' 5 | import address from './modules/address' 6 | import restaurant from './modules/restaurant' 7 | 8 | export default new Vuex.Store({ 9 | modules: { 10 | cart, 11 | address, 12 | restaurant 13 | } 14 | }) 15 | -------------------------------------------------------------------------------- /src/stores/modules/address.js: -------------------------------------------------------------------------------- 1 | import * as types from '../mutation-types' 2 | import {location} from '@/api/location' 3 | 4 | const state = { 5 | lat: '', // 当前位置纬度 6 | lng: '', // 当前位置经度 7 | address: { 8 | address: '定位中...', 9 | lat: '', 10 | lng: '', 11 | }, 12 | locationReady: false, //定位是否完成 13 | deliveryAddress: {} 14 | }; 15 | 16 | const getters = { 17 | address: state => state.address, 18 | locationReady: state => state.locationReady, 19 | deliveryAddress: state => state.deliveryAddress 20 | }; 21 | 22 | const actions = { 23 | clearAddress({commit}) { 24 | commit(types.CLEAR_ADDRESS); 25 | }, 26 | location({commit}) { 27 | location().then((response) => { 28 | if (response.data.status === 200) { 29 | let data = response.data.data; 30 | commit(types.RECORD_ADDRESS, {address: data.address, ...data.location}); //保存title 和 经纬度到VUEX中 31 | commit(types.LOCATION_READY, true); //定位完成 拉取商店 32 | } 33 | }) 34 | }, 35 | recordAddress({commit}, address) { 36 | commit(types.RECORD_ADDRESS, address); //保存title 和 经纬度到VUEX中 37 | commit(types.LOCATION_READY, true); //定位完成 拉取商店 38 | }, 39 | locationReady({commit}, boolean) { 40 | commit(types.LOCATION_READY, boolean); //定位完成 拉取商店 41 | }, 42 | recodeDeliveryAddress({commit}, address) { 43 | commit(types.RECORD_DELIVERY_ADDRESS, address); //定位完成 拉取商店 44 | }, 45 | failLocation({commit}) { //定位失败 46 | commit(types.FAIL_LOCATION); 47 | } 48 | }; 49 | 50 | const mutations = { 51 | [types.CLEAR_ADDRESS](state) { 52 | let address = {address: '定位中...', lat: '', lng: ''}; 53 | state.address = {...address}; 54 | }, 55 | [types.RECORD_ADDRESS](state, address) { 56 | state.address = {...address} 57 | }, 58 | //定位完成拉取附近餐馆 59 | [types.LOCATION_READY](state, boolean) { 60 | state.locationReady = boolean; 61 | }, 62 | [types.RECORD_DELIVERY_ADDRESS](state, address) { 63 | state.deliveryAddress = {...address}; 64 | }, 65 | [types.FAIL_LOCATION](state) { 66 | let address = {address: '定位失败...', lat: '', lng: ''} 67 | state.address = {...address}; 68 | } 69 | }; 70 | 71 | export default { 72 | state, 73 | getters, 74 | actions, 75 | mutations 76 | } 77 | -------------------------------------------------------------------------------- /src/stores/modules/cart.js: -------------------------------------------------------------------------------- 1 | import * as types from '../mutation-types' 2 | 3 | 4 | const state = { 5 | cartList: {}, //加入购物车列表 6 | ballInCart: false 7 | } 8 | 9 | //getters 10 | const getters = { 11 | cartList: state => state.cartList, 12 | ballInCart: state => state.ballInCart 13 | } 14 | 15 | //actions 16 | const actions = { 17 | addCart({commit}, {restaurant_id, restaurant_name, pic_url, food_id, price, name, foods_pic}) { 18 | commit('ADD_CART', {restaurant_id, restaurant_name, pic_url, food_id, price, name, foods_pic}) 19 | }, 20 | reduceCart({commit}, {restaurant_id, food_id}) { 21 | commit('REDUCE_CART', {restaurant_id, food_id}) 22 | }, 23 | deleteFood({commit}, {restaurant_id, food_id}) { 24 | commit('DELETE_CART', {restaurant_id, food_id}) 25 | }, 26 | emptyCart({commit}, {restaurant_id}) { 27 | commit('EMPTY_CART', {restaurant_id}); 28 | }, 29 | ballInCart({commit}, boolean) { 30 | commit(types.BALL_IN_CART, boolean); 31 | }, 32 | updateCart({commit}, {cartList}) { 33 | commit(types.UPDATE_CART, {cartList}); 34 | } 35 | } 36 | 37 | //mutations 38 | const mutations = { 39 | [types.ADD_CART](state, {restaurant_id, restaurant_name, pic_url, food_id, price, name, foods_pic}) { 40 | let cart = state.cartList; 41 | let restaurant; 42 | if (!cart[restaurant_id]) { //如果该商店还没有添加任何商品 进行初始化 43 | restaurant = cart[restaurant_id] = { 44 | totalPrice: 0, //总价格 45 | totalNum: 0, //总数量 46 | restaurant_name, //餐馆名 47 | pic_url //餐馆图片 48 | }; 49 | } else { 50 | restaurant = cart[restaurant_id]; 51 | } 52 | restaurant.totalPrice = (Number(restaurant.totalPrice) + Number(price)).toFixed(2); //计算总价格 53 | restaurant.totalNum++; //数量加一 54 | if (restaurant[food_id]) { //如果该食物已经在保存了 数量加1 55 | restaurant[food_id].num++; 56 | } else { 57 | restaurant[food_id] = { //初始化该食物 58 | name, 59 | price, 60 | foods_pic, 61 | num: 1, 62 | id: food_id, 63 | } 64 | } 65 | //触发更新 66 | state.cartList = {...cart} 67 | localStorage.setItem('cartList', JSON.stringify(state.cartList)); 68 | }, 69 | //减购物车 70 | [types.REDUCE_CART](state, {restaurant_id, food_id}) { 71 | let cart = state.cartList; 72 | let restaurant = cart[restaurant_id]; 73 | //修改购物车总价格 74 | restaurant.totalPrice = Number((restaurant.totalPrice - restaurant[food_id].price).toFixed(2)); 75 | restaurant.totalNum--; 76 | if (restaurant.totalNum === 0) { 77 | delete(cart[restaurant_id]); 78 | } else if (restaurant[food_id].num === 1) { 79 | delete(restaurant[food_id]); 80 | } else { 81 | restaurant[food_id].num--; 82 | } 83 | state.cartList = {...cart}; 84 | localStorage.setItem('cartList', JSON.stringify(state.cartList)); 85 | }, 86 | //删除食物 87 | [types.DELETE_CART](state, {restaurant_id, food_id}) { 88 | let cart = state.cartList; 89 | let restaurant = cart[restaurant_id]; 90 | let num = restaurant[food_id].num; 91 | let price = restaurant[food_id].price; 92 | restaurant.totalNum -= num; 93 | delete(restaurant[food_id]); 94 | if (restaurant.totalNum === 0) { 95 | delete(cart[restaurant_id]); 96 | } else { 97 | restaurant.totalPrice = Number((restaurant.totalPrice - price * num).toFixed(2)); //修改价格 98 | } 99 | state.cartList = {...cart}; 100 | localStorage.setItem('cartList', JSON.stringify(state.cartList)); 101 | }, 102 | //更新购物车记录 103 | [types.UPDATE_CART](state, {cartList}) { 104 | state.cartList = {...cartList}; 105 | }, 106 | //清空购物车 107 | [types.EMPTY_CART](state, {restaurant_id}) { 108 | let cart = state.cartList; 109 | delete cart[restaurant_id]; 110 | state.cartList = {...cart}; 111 | localStorage.setItem('cartList', JSON.stringify(state.cartList)); 112 | }, 113 | //小球进入购物车 114 | [types.BALL_IN_CART](state, boolean) { 115 | state.ballInCart = boolean; 116 | } 117 | } 118 | 119 | export default { 120 | state, 121 | getters, 122 | actions, 123 | mutations 124 | } 125 | -------------------------------------------------------------------------------- /src/stores/modules/restaurant.js: -------------------------------------------------------------------------------- 1 | import * as types from '../mutation-types' 2 | 3 | import {getRestaurant} from '@/api/restaurant' 4 | 5 | const state = { 6 | poi_info: {}, 7 | restaurant_info: {}, //商店的信息 包括 售卖的食物 8 | }; 9 | 10 | //getters 11 | const getters = { 12 | restaurant_info: state => state.restaurant_info, 13 | poi_info: state => state.poi_info 14 | }; 15 | 16 | //actions 17 | const actions = { 18 | getRestaurant({commit}, restaurant_id) { 19 | getRestaurant({restaurant_id}).then((response) => { 20 | let poi_info = response.data.data; 21 | commit('RECORD_RESTAURANT', poi_info) 22 | }) 23 | } 24 | }; 25 | 26 | //mutations 27 | const mutations = { 28 | //记录当前商店的信息 29 | [types.RECORD_RESTAURANT](state, poi_info) { 30 | state.poi_info = {...poi_info} 31 | }, 32 | }; 33 | 34 | export default { 35 | state, 36 | getters, 37 | actions, 38 | mutations 39 | } 40 | -------------------------------------------------------------------------------- /src/stores/mutation-types.js: -------------------------------------------------------------------------------- 1 | export const ADD_CART = 'ADD_CART' //加入购物车 2 | export const EMPTY_CART = 'EMPTY_CART' //清空购物车 3 | export const BALL_IN_CART = 'BALL_IN_CART' //小球进入购物车 4 | export const RECORD_ADDRESS = 'RECORD_ADDRESS' 5 | export const CLEAR_ADDRESS = 'CLEAR_ADDRESS' //重新定位时 清空原来定位信息 6 | export const FAIL_LOCATION = 'FAIL_LOCATION' //定位失败 7 | export const RECORD_SUGGESTION = 'RECORD_SUGGESTION' 8 | export const REDUCE_CART = 'REDUCE_CART' //减少购物车 9 | export const RECORD_DELIVERY_ADDRESS = 'RECORD_DELIVERY_ADDRESS' //配送地址 10 | export const RECORD_RESTAURANT = 'RECORD_RESTAURANT' 11 | export const UPDATE_CART = 'UPDATE_CART' //页面刷新时 更新购物车信息 12 | export const LOCATION_READY = 'LOCATION_READY' // 拉取餐馆信息 13 | export const DELETE_CART = 'DELETE_CART' //删除购物车某种食物 14 | export const SAVE_PATH = 'SAVE_PATH' //保存路由路径 15 | export const RESET_PATH = 'RESET_PATH' //重置路径 16 | 17 | -------------------------------------------------------------------------------- /src/style/common.scss: -------------------------------------------------------------------------------- 1 | body, div, span, header, footer, nav, section, aside, article, ul, dl, dt, dd, li, a, p, h1, h2, h3, h4,h5, h6, i, b, textarea, button, input, select, figure, figcaption{ 2 | padding: 0; 3 | margin: 0; 4 | list-style: none; 5 | font-style: normal; 6 | text-decoration: none; 7 | border: none; 8 | font-weight: normal; 9 | box-sizing: border-box; 10 | -webkit-tap-highlight-color:transparent; 11 | -webkit-font-smoothing: antialiased; 12 | &:hover{ 13 | outline: none; 14 | } 15 | } 16 | a{ 17 | color:#333; 18 | } 19 | html,body{ 20 | width: 100%; 21 | height:100%; 22 | line-height:1; 23 | } 24 | //iconfont 25 | @font-face { 26 | font-family: 'iconfont'; /* project id 407663 */ 27 | src: url('//at.alicdn.com/t/font_407663_9ufqp98dcmw5qaor.eot'); 28 | src: url('//at.alicdn.com/t/font_407663_9ufqp98dcmw5qaor.eot?#iefix') format('embedded-opentype'), 29 | url('//at.alicdn.com/t/font_407663_9ufqp98dcmw5qaor.woff') format('woff'), 30 | url('//at.alicdn.com/t/font_407663_9ufqp98dcmw5qaor.ttf') format('truetype'), 31 | url('//at.alicdn.com/t/font_407663_9ufqp98dcmw5qaor.svg#iconfont') format('svg'); 32 | } 33 | @mixin clearfix{ 34 | &:after{ 35 | content:""; 36 | display:table; 37 | clear:both; 38 | } 39 | } 40 | 41 | .swiper-pagination-bullet-active{ 42 | background: rgb(248,203,57) !important; 43 | } 44 | .swiper-pagination-bullet{ 45 | border-radius:0 ; 46 | } 47 | 48 | .iconfont{ 49 | font-style:normal; 50 | font-family: iconfont; 51 | } 52 | 53 | //自动填写密码出现的黄色背景 54 | input:-webkit-autofill { 55 | -webkit-box-shadow: 0 0 0 1000px white inset !important; 56 | } 57 | //focus产生黄色边框 58 | input:focus{ outline:none; } 59 | -------------------------------------------------------------------------------- /src/style/mixin.scss: -------------------------------------------------------------------------------- 1 | $mtYellow: #ffd161; 2 | $bottomLine: rgb(228, 228, 228); 3 | $mtGrey: rgb(214, 214, 214); 4 | 5 | $baseFontSize: 75; //基于视觉稿横屏尺寸/100得出的基准font-size 6 | @mixin px2rem($name, $px) { //用sass计算从px到rem的转换 7 | #{$name}: $px / $baseFontSize * 1rem; 8 | } 9 | 10 | @mixin loading { 11 | /*loading部分*/ 12 | background: #fff; 13 | text-align: center; 14 | font-size: 14px; 15 | height: 26px; 16 | line-height: 26px; 17 | .loading:before { 18 | content: ""; 19 | display: inline-block; 20 | position: relative; 21 | left: -11px; 22 | padding: 0; 23 | border: 0; 24 | background: 0; 25 | width: 2px; 26 | height: 2px; 27 | border-radius: 100%; 28 | box-shadow: 0 -7px 0 0.9px #666, 7px 0 #999, 0 7px #999, -7px 0 #999, -5px -5px 0 0.4px #999, 5px -5px 0 1.1px #666, 5px 5px #999, -5px 5px #999; 29 | animation: spin 1.5s linear infinite; 30 | -webkit-animation: spin 1.5s linear infinite; 31 | top: -4px; 32 | } 33 | @keyframes spin { 34 | from { 35 | transform: rotate(0deg) 36 | } 37 | to { 38 | transform: rotate(360deg) 39 | } 40 | } 41 | } 42 | 43 | @mixin ellipsis{ 44 | overflow: hidden; 45 | text-overflow:ellipsis; 46 | white-space: nowrap; 47 | } 48 | -------------------------------------------------------------------------------- /src/utils/auth.js: -------------------------------------------------------------------------------- 1 | const userInfo = 'mt-username' 2 | 3 | export function getInfo() { 4 | return localStorage.getItem(userInfo) 5 | } 6 | 7 | export function setInfo(username) { 8 | return localStorage.setItem(userInfo, username) 9 | } 10 | 11 | export function removeInfo() { 12 | return localStorage.removeItem(userInfo) 13 | } 14 | 15 | -------------------------------------------------------------------------------- /src/views/404/error.vue: -------------------------------------------------------------------------------- 1 | 12 | 63 | -------------------------------------------------------------------------------- /src/views/Index/Index.vue: -------------------------------------------------------------------------------- 1 | 2 | 34 | 35 | 71 | 72 | 152 | -------------------------------------------------------------------------------- /src/views/Index/nav.vue: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 105 | 106 | 171 | -------------------------------------------------------------------------------- /src/views/category/category.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 30 | 31 | 37 | -------------------------------------------------------------------------------- /src/views/confirm_order/children/address.vue: -------------------------------------------------------------------------------- 1 | 2 | 25 | 26 | 60 | 61 | 132 | -------------------------------------------------------------------------------- /src/views/confirm_order/children/children/add_address.vue: -------------------------------------------------------------------------------- 1 | 2 | 14 | 15 | 76 | 77 | 96 | -------------------------------------------------------------------------------- /src/views/home/children/address.vue: -------------------------------------------------------------------------------- 1 | 2 | 30 | 31 | 65 | 66 | 149 | -------------------------------------------------------------------------------- /src/views/home/children/collection.vue: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 37 | -------------------------------------------------------------------------------- /src/views/home/children/comment.vue: -------------------------------------------------------------------------------- 1 | 2 | 56 | 57 | 99 | 100 | 228 | -------------------------------------------------------------------------------- /src/views/home/children/footprint.vue: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 43 | -------------------------------------------------------------------------------- /src/views/home/children/friend.vue: -------------------------------------------------------------------------------- 1 | 2 | 26 | 27 | 36 | 37 | 122 | -------------------------------------------------------------------------------- /src/views/home/children/thank_record.vue: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 15 | 16 | 46 | -------------------------------------------------------------------------------- /src/views/home/home.vue: -------------------------------------------------------------------------------- 1 | 2 | 51 | 52 | 178 | 179 | 277 | -------------------------------------------------------------------------------- /src/views/index/nearby_shops.vue: -------------------------------------------------------------------------------- 1 | 2 | 61 | 62 | 160 | 161 | 296 | -------------------------------------------------------------------------------- /src/views/location/location.vue: -------------------------------------------------------------------------------- 1 | 2 | 21 | 22 | 67 | 68 | 117 | -------------------------------------------------------------------------------- /src/views/login/login.vue: -------------------------------------------------------------------------------- 1 | 2 | 36 | 37 | 78 | 79 | 148 | -------------------------------------------------------------------------------- /src/views/order/comment.vue: -------------------------------------------------------------------------------- 1 | 2 | 73 | 74 | 182 | 183 | 368 | -------------------------------------------------------------------------------- /src/views/order/order.vue: -------------------------------------------------------------------------------- 1 | 2 | 53 | 54 | 83 | 84 | 219 | -------------------------------------------------------------------------------- /src/views/order/order_detail.vue: -------------------------------------------------------------------------------- 1 | 2 | 92 | 93 | 135 | 136 | 309 | -------------------------------------------------------------------------------- /src/views/order/star.vue: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 24 | 25 | 46 | -------------------------------------------------------------------------------- /src/views/pay/pay.vue: -------------------------------------------------------------------------------- 1 | 2 | 84 | 85 | 196 | 197 | 382 | -------------------------------------------------------------------------------- /src/views/pay/scan.vue: -------------------------------------------------------------------------------- 1 | 2 | 26 | 27 | 93 | 94 | 138 | -------------------------------------------------------------------------------- /src/views/search/search.vue: -------------------------------------------------------------------------------- 1 | 2 | 22 | 23 | 65 | 66 | 100 | -------------------------------------------------------------------------------- /src/views/store/comment/comment.vue: -------------------------------------------------------------------------------- 1 | 2 | 85 | 86 | 168 | 169 | 373 | -------------------------------------------------------------------------------- /src/views/store/menu/bottom.vue: -------------------------------------------------------------------------------- 1 | 2 | 40 | 41 | 133 | 134 | 303 | -------------------------------------------------------------------------------- /src/views/store/menu/menu.vue: -------------------------------------------------------------------------------- 1 | 2 | 48 | 49 | 151 | 152 | 261 | -------------------------------------------------------------------------------- /src/views/store/seller/seller.vue: -------------------------------------------------------------------------------- 1 | 2 | 51 | 52 | 66 | 67 | 146 | -------------------------------------------------------------------------------- /src/views/store/store.vue: -------------------------------------------------------------------------------- 1 | 2 | 61 | 62 | 102 | 103 | 248 | -------------------------------------------------------------------------------- /src/views/store/store_detail.vue: -------------------------------------------------------------------------------- 1 | 2 | 35 | 36 | 54 | 55 | 153 | -------------------------------------------------------------------------------- /vue.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | function resolve(dir) { 4 | return path.join(__dirname, dir); 5 | } 6 | module.exports = { 7 | lintOnSave: true, 8 | chainWebpack: (config) => { 9 | config.resolve.alias 10 | .set('@', resolve('src')) 11 | .set('@assets',resolve('src/assets')) 12 | } 13 | }; 14 | --------------------------------------------------------------------------------