# mt-app **Repository Path**: qkongtao/mt-app ## Basic Information - **Project Name**: mt-app - **Description**: Vue全家桶+SSR+Koa2全栈开发美团网 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 5 - **Forks**: 1 - **Created**: 2020-02-23 - **Last Updated**: 2023-10-10 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 项目演示地址 [http://mt-app.qkongtao.cn](http://mt-app.qkongtao.cn "高仿美团网") # 项目介绍 前端 :Nuxt.js/vue-router/ Vuex/ ELement-ui 后端 :Node.js/Koa2/Koa-router/Nodemailer/Passport HTTP通讯 :Axios 数据支撑 :Mongoose/Redis/高德地图web服务api接口 # 项目结构 ``` components changeCity -->城市选择页面的所有 iselect.vue -->按省份选择等,那一栏的 hot.vue -->热门城市 那栏 categroy.vue -->按拼音首字母选择 那栏 products -->产品列表页,就是点击搜索出来的页面 categroy.vue -->分类,区域的部分 crumbs.vue -->赣州美团>赣南脐橙 iselect.vue -->分类,区域栏中偏右边的部分,像周边游,香坊区等部分 list.vue --> product.vue --> detail -->产品详情页,就是点击产品出现的页面 crumbs.vue --> item.vue --> list.vue --> summary.vue --> index artistic.vue -->页面下半部分,有格调的那个部分 life.vue -->中间包括轮播图的那部分,几乎全是图片的部分 menu.vue -->全部分类部分 silder.vue -->单独的轮播图组件,在life.vue文件中引用 public header -->包括搜索框往上面的部分 index.vue -->用于导出header下的其他组件 nav.vue -->页面右上角,什么我的美团,网址导航那部分 searchbar.vue -->整个搜索框部分 topbar.vue -->除了搜索框的所有顶部部分 user.vue -->用户登陆注册部分 geo.vue -->页面左上角,城市切换部分 footer index.vue -->底部部分 pages index.vue -->中间部分 register.vue -->注册组件 login.vue -->登录组件 exit.vue -->退出组件 register.vue -->注册组件 changeCity -->城市选择组件 products.vue -->产品列表页 detail.vue -->产品详情页 layout default.vue -->最终显示页面 blank.vue -->放置register.vue,login,exit的模版文件 server dbs models -->放置数据库数据 user.js -->users表,包括usename,password,email categroy.js city.js menu.js poi.js province.js config.js -->数据库配置文件(smtp服务, redis连接, mongodb连接) interface utils axios.js -->定义axios的配置项 passport.js -->利用koa-passport简便的实现登录注册功能(序列化,反序列化,local策略) users.js --> 登录系列接口定义(登录,退出,获取用户名,注册,验证等) geo.js -->城市,系列接口定义(获取所有城市,热门城市,获取省份等) index.js -->定义支持服务的接口文件(passport, session, 路由, 数据库, 处理post请求等) store modules -->vuex子模块 geo.js -->当前城市 home.js -->全部分类下的详细分类 index.js -->vuex模块(汇总子模块并且定义一些操作) redis启动->找到安装目录(develop)->redis-server mongoose启动->找到安装目录(develop)->mongod 支付逻辑在13-1的7.06分处,可以自己写 nuxt.config.js 配置文件:可以引入项目所需文件,像css文件,还可以配置很多其他文件 ``` # 实现功能 1. 登录注册,qq邮箱自动发验证码 2. 城市切换:更新不同城市的信息 3. search搜索,根据当前城市进行用POI的关键字进行条件搜索 4. 高德地图自动定位 # 项目安装 先安装npx `npm install -g npx` 然后用npx安装模板 `npx create-nuxt-app project_name` cd到那个目录,启动 `cd mt-app` `npm run dev` **由于无法使用import命令** 1. 使用babel-node启动 在pockage.json中编译中加入 --exec babel-node ``` "dev": "cross-env NODE_ENV=development nodemon server/index.js --watch server --exec babel-node", "build": "nuxt build", "start": "cross-env NODE_ENV=production node server/index.js --exec babel-node", ``` 2. 在根目录新建.babelrc文件 ``` { "presets":["es2015"] } ``` 3. 安装对应的插件 `cnpm i babel-core babel-preset-es2015 babel-cli` 即可使用import导入,并且启动成功 **使用sass** `cnpm i sass-loader node-sass` 项目要求: 1. 节省网络请求 2. 语义化 3. DOM最简化 遇到的问题: 1. 在做Vue项目时使用setTimeout,在里面调用this.add()方法,报错this.add 不是一个函数使用settimeout时,此时的this指向window,为什么this指向会变呢?不再指向data对象,**因为此时运行的代码是脱离了之前的执行环境** 解决:可以在settimeout里面的函数用箭头函数来表示; 或者把data里的this暂时存起来_this=this; **导入数据库** mongoimport -d dbs -c test pois.dat **ssr**:服务端直接打在网页上的源码,不需要重渲染 **拼音库** 可以实现那汉字转拼音 npm i js-pinyin **js按照数组里元素的首字母排序** 如果想按照其他标准进行排序,就需要提供比较函数,该函数要比较两个值,然后返回一个用于说明这两个值的相对顺序的数字。比较函数应该具有两个参数 a 和 b,其返回值如下: 若 a 小于 b,在排序后的数组中 a 应该出现在 b 之前,则返回一个小于 0 的值。 若 a 等于 b,则返回 0。 若 a 大于 b,则返回一个大于 0 的值。 `blocks.sort((a, b) => a.title.charCodeAt(0) - b.title.charCodeAt(0));` **改json数据结构映射关系是很好改的,改模板结构是很痛苦的** **产品列表的智能排序还要重新实现** JavaScript判断元素是否在工作窗口内 ```js function isInViewPortOfOne (el) { const viewPortHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight ;//窗口可视高度 const offsetTop = el.offsetTop;//元素顶部高度 const offsetHeight = el.offsetHeight;//元素高度 const scrollTop = document.documentElement.scrollTop;//滚动距离 //判断是否在工作窗口内 const top = (offsetTop+offsetHeight )- scrollTop if(top>0&&top首页 **编程式导航路由传参** ```js this.$router.push({ path: "/", query: { name: name } }); //接收参数 this.$router.push(`/products?keyword=${this.$route.query.name}`); ``` # 打包部署 `npm run build` 需要上传的文件 1. .nuxt目录 2. package.json 3. nuxt.config.js 4. static 5. server目录 ## 上传之后 1. 安装依赖(要安装好PM2,自带node) npm install 2. 写自动启动的脚本,内容如下 在项目根目录创建一个pm2.json文件 ``` [ { "name": "mt-app", "script": "npm run server", "env_dev": { "NODE_ENV": "development" }, "env_production": { "NODE_ENV": "production" } } ] ``` 3. 使用pm2管理启动项目 cd 到项目根目录 pm2 pm2.json启动项目 发现在服务器本地已经启动了 http://localhost:3000 但是没有在外网映射出去,所有使用域名无法访问 4. 使用Nginx配置映射 在 nginx.conf下面添加 ``` upstream nodenuxt { server 127.0.0.1:3000; # nuxt 项目监听PC端端口 keepalive 64; } server { #需要映射的端口和域名 listen 80; server_name **************.cn; location / { proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_set_header X-Nginx-Proxy true; proxy_cache_bypass $http_upgrade; proxy_pass http://nodenuxt; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } } ``` 配置完之后,发现使用域名可以成功访问,但是出现了资源跨域的问题。 5. 在nuxt.config,js配置文件里面做一下配置 ``` /* ** Nuxt.js modules */ modules: [ '@nuxtjs/axios', '@nuxtjs/proxy' ], proxy: [ [ '/api', { target: 'http://cp-tools.cn/', // api主机 pathRewrite: { '^/api': '/' } } ] ], axios: {}, ``` 使用接口代理获取资源 **就没有出现跨域的现象了**