{"id":20863548,"url":"https://github.com/simmzl/ele","last_synced_at":"2026-04-10T02:06:14.099Z","repository":{"id":112878740,"uuid":"109259132","full_name":"simmzl/ele","owner":"simmzl","description":"Vue.js 2.0 仿饿了么Web APP","archived":false,"fork":false,"pushed_at":"2017-11-22T15:20:40.000Z","size":4809,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-01-19T08:15:53.061Z","etag":null,"topics":["better-scroll","es6","eslint","postcss","stylus","vue","webpack"],"latest_commit_sha":null,"homepage":"","language":"Vue","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/simmzl.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-11-02T12:00:57.000Z","updated_at":"2017-11-18T15:46:29.000Z","dependencies_parsed_at":null,"dependency_job_id":"224b263c-a556-40d0-869e-264621775e2b","html_url":"https://github.com/simmzl/ele","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simmzl%2Fele","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simmzl%2Fele/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simmzl%2Fele/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simmzl%2Fele/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/simmzl","download_url":"https://codeload.github.com/simmzl/ele/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243236618,"owners_count":20258873,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["better-scroll","es6","eslint","postcss","stylus","vue","webpack"],"created_at":"2024-11-18T05:29:37.594Z","updated_at":"2025-12-27T05:27:57.094Z","avatar_url":"https://github.com/simmzl.png","language":"Vue","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ele\n\n\u003e Vue.js 仿[饿了么Web App](https://h5.ele.me)\n\n## 技术栈\n\n- vue\n- vuex\n- vue-router\n- vue-resource\n- webpack\n- eslint\n- better-scroll\n- stylus\n- postCss\n\n## Build Setup\n\n``` bash\n# install dependencies\nnpm install\n\n# serve with hot reload at localhost:8080\nnpm run dev\n\n# build for production with minification\nnpm run build\n\n# build for production and view the bundle analyzer report\nnpm run build --report\n```\n\n## Tips \u0026 坑：\n\n### router-view\nvue1.0升至2.0+后，v-link改为`\u003crouter-view\u003e\u003c/router-view\u003e`,入口js文件的设置也跟随变化，需要按照官网配置[router.vuejs.org](https://router.vuejs.org/zh-cn/essentials/getting-started.html),\n不仅把这些.vue .js文件的配置改了，还需要在package.json中的dependencies内，把vue和vue-router的版本也改为最新；\n### 移动端像素\n在手机等移动端物理像素有别于逻辑像素，具体的比例根据不同设备的设备像素比不同而不同；\n\n一个在开发过程中使用手机浏览页面的方法：\n- 使用`ipconfig`查看自己PC局域网IP；\n- 将浏览器url中的localhost改为局域网IP；\n- 复制链接至[草料网](https://cli.im/)生成二维码；\n- 使用同在一个局域网的手机扫码访问即可！\n\n实现移动端一像素边框的方法：[利用min-device-pixel-ratio媒体功能实现真正的1像素](http://blog.csdn.net/zzxboy1/article/details/56016475)\n\n### vue-resource\n使用vue-resource时注意`this.$http.get(url).then((res) =\u003e {})`中回调函数then()中获取到的json内容在res.body,data中。\n在使用ajax的get方法获取数据来填充app.vue内seller等对象之前，seller等对象还是空对象，所以在用seller内的数据渲染时，需要加v-if判断seller等对象是否有值，\n否则会报错。\n\n### sticky footers\nsticky footers，即**粘性页脚布局**，在遇到下面两个布局的时候需要用到：\n- 在内容未撑满页面时，footer固定在底部 \n- 在内容超出页面高度时，footer随着页面的变大而往下移动，也保持在页面底部。\n\n#### 一种兼容性最佳的解决方案（负margin布局）\n##### 思路:\n 一般情况下，一个网页分为header、content、footer；\n - 将头部和内容装入一个容器wrapper-main，再将wrapper-main封装到wrapper中；\n - 将wrapper的min-height设为100%，wrapper-main的padding-bottom设为footer的高度;\n - 将footer的margin-top设为负的自身的高度;\n \n 这样就达到了当wrapper的高度为100%时，footer固定在视口的底部，当其高度大于100%时，footer则一直在wrapper后面的效果；\n```html\n\u003cdiv class=\"wrapper clearfix\"\u003e\n  \u003cdiv class=\"wrapper-main\"\u003e\n    \u003cheader\u003e头部\u003c/header\u003e\n    \u003cdiv class=\"content\"\u003e页面内容\u003c/div\u003e  \n\u003c/div\u003e\n\u003c/div\u003e\n\u003cfooter\u003e页脚\u003c/footer\u003e\n```\n```css\n.wrapper{\n  min-height: 100%;\n}\n.wrapper-main{\n  padding-bottom: 50px;\n}\nfooter{\n  position: relative;\n  height: 50px;\n  margin-top: -50px;\n  clear: both;\n}\n.clearfix:after {\n  display: block;\n  content: '';\n  clear: both;\n  height: 0;\n  visibility: hidden\n}\n```\n#### 第二种：flex布局\n##### 思路\n讲header和content包装在一个wrapper-main内，再将footer和wrapper-main包装在display为flex的一个wrapper内。\n```html\n\u003cdiv class=\"wrapper\"\u003e\n  \u003cdiv class=\"wrapper-main\"\u003e\n    \u003cheader\u003e头部\u003c/header\u003e\n    \u003cdiv class=\"content\"\u003e页面内容\u003c/div\u003e\n  \u003c/div\u003e\n  \u003cfooter\u003e页脚\u003c/footer\u003e\n\u003c/div\u003e\n```\n```css\n.wrapper{\n  display: flex;\n  flex-direction: column;\n  min-height: 100%;\n}\n.wrapper-main{\n  flex: 1;\n}\nfooter{\n  flex: 0;\n}\n```\n### vue过渡效果\nvue2+已经将过渡效果升级为`transition` 的封装组件，具体使用：\n```html\n\u003ctransition name=\"fade\"\u003e\n  \u003cp\u003ehello\u003c/p\u003e\n\u003c/transition\u003e\n```\n```css\n.fade-enter-active, .fade-leave-active {\n  transition: opacity .5s\n}\n.fade-enter, .fade-leave-to /* .fade-leave-active in below version 2.1.8 */ {\n  opacity: 0\n}\n```\n[官方文档](https://cn.vuejs.org/v2/guide/transitions.html)\n\n### 好的编程习惯\n写css时尽量用class名而非标签名，在渲染性能上，class优于标签，尤其在层级嵌套较深时。\n\n### Vue 获取 DOM 对象的接口—— vm.$refs\n在vue 1.0中使用`v-el`定义element,2.0 升级为 `ref`\n\n### vm.$nextTick( [callback] )\n`vm.$nextTick( [callback] )`在修改数据之后立即使用这个方法，获取更新后的 DOM。\n ```javascript\nnew Vue({\n  methods: {\n    example: function () {\n      // 修改数据\n      this.message = 'changed'\n      // DOM 还没有更新\n      this.$nextTick(function () {\n        // DOM 现在更新了\n        // `this` 绑定到当前实例\n        this.doSomething();\n      })\n    }\n  }\n})\n```\n\n### 左边栏固定宽度，右侧自动适应\n#### 方法之一：使用flex布局\n```html\n\u003cdiv class=\"goods\"\u003e\n  \u003cdiv class=\"menu\"\u003e\u003c/div\u003e\n  \u003cdiv class=\"content\"\u003e\u003c/div\u003e\n\u003c/div\u003e\n\n\n\u003cstyle\u003e\n  .goods{\n    display: flex;\n    height: 400px;\n  }\n  .menu{\n    background: #4FB3A4;\n    flex: 0 0 100px;\n    /*flex: none | [ \u003c'flex-grow'\u003e \u003c'flex-shrink'\u003e \u003c'flex-basis'\u003e 默认 0 1 auto]*/\n    /*flex-grow：定义项目的放大比例，默认为0*/\n    /*flex-shrink：定义了项目的缩小比例，默认为1*/\n    /*flex-basis：定义了在分配多余空间之前，项目占据的主轴空间（main size）*/\n  }\n  .content{\n    flex: 1;\n    background: yellow;\n  }\n\u003c/style\u003e\n```\n更多方法参考我的一篇总结：[左侧定宽，右侧自适应与双飞翼布局](http://blog.simmzl.cn/2017/11/左侧定宽，右侧自适应与双飞翼布局.html)\n\n### v-for使用索引\n`v-for` 遍历数组时的参数顺序已经变更，当包含 `index` 时，之前遍历数组时的参数顺序是 `(index, value)`，现在是 `(value, index)`。来和 JavaScript 的原生数组方法 (例如 `forEach` 和 `map`) 保持一致。\n\n### 右侧滚动时根据滚动位置实时计算左侧菜单active的值\n首先遍历获取每个li标签的`clientHeight`值，依次叠加并存入数组`listHeight`，之后给右侧`ul`添加`scroll`事件，获取滚动的值后，利用vue的计算属性计算当前滚动的值在`listHeight`的区间，从而通过该区间确定左侧菜单栏对应的active类的位置\n\n### 绑定 Class\n动态地切换 class可以通过v-bind绑定class，可以使用对象语法(传入一个对象，通过判断对象属性值是否为true来切换class)、数组语法(同理)：\n```\n:class=\"{'hightLight': totalCount\u003e0}\"\n\nv-bind:class=\"{ active: isActive, 'text-danger': hasError }\"\u003e\ndata: {\n  isActive: true,\n  hasError: false\n}\n```\n### ES6 多行字符串 连接字符串\n在ES6之前，拼接字符串需要使用`+`,在ES6中只需使用反引号配合`${ 变量 }`即可；\n```javascript\n// 旧版\nalert(\"你好，\\n 我叫\\n Olive\");\n// ES6\nalert(`你好\n我叫\nolive`);\n\n// 旧版\nlet name = 'cat';\nconsole.log('你好,' + name + '!');\n// ES6\nconsole.log( `你好,${name}!` );\n```\n### 子组件和父组件之间通信\n#### 父组件good.vue --- 子组件food.vue\n\n- 首先父组件内通过import引入子组件\n- 通过components注册组件\n- 将子组件名作为标签名实现在父组件内使用子组件\n- 子组件内通过props引入父组件数据\n```javascript\nprops() {\n  food: {\n    type: Object\n  }\n}\n```\n- 父组件通过在子组件标签内使用v-bind传入数据food\n```html\n\u003cfood :food=\"food\"\u003e\u003c/food\u003e\n```\n#### 父组件可以调用子组件方法，反之则不行\n##### 编程规范\n组件的方法如果是私有的，命名时最好在前面加上`_`，如：\"_show\",公有则不加\n##### 调用方法\n使用 `ref` 为子组件指定一个引用 `ID`，然后在父组件中使用`this.$ref.id.show()`即可使用子组件的方法。\n### 事件修饰符\nVue.js 为 `v-on` 提供了事件修饰符，使用@.stop阻止冒泡\n[官方文档](https://cn.vuejs.org/v2/guide/events.html#事件修饰符)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsimmzl%2Fele","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsimmzl%2Fele","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsimmzl%2Fele/lists"}