Vue开源:微豆 - Vue 2.0 实现豆瓣 Web App

sophy 8年前
   <h2>微豆 Vdo</h2>    <p>一个使用 Vue.js 与 Material Design 重构 豆瓣 的项目。</p>    <p>项目网站 <a href="/misc/goto?guid=4959742093760863809" rel="nofollow,noindex">http://vdo.ralfz.com/</a></p>    <p>GitHub <a href="/misc/goto?guid=4959742093858465746" rel="nofollow,noindex">https://github.com/RalfZhang/Vdo</a></p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/3b50582bb69e08271b32e28aad187418.gif"></p>    <h2>快速使用</h2>    <pre>  <code class="language-javascript"># 克隆项目到本地  git clone https://github.com/RalfZhang/Vdo.git    # 安装依赖  npm install    # 在 localhost:8080 启动项目  npm run dev</code></pre>    <h2>教程</h2>    <h2>安装 vue-cli 脚手架</h2>    <p>运行如下命令,即可创建一个名为 my-project 的 vue 项目,并且通过本地 8080 端口启动服务</p>    <pre>  <code class="language-javascript">npm install -g vue-cli  vue init webpack my-project  cd my-project  npm install  npm run dev</code></pre>    <p>在运行 vue init webpack my-project 后,会依次要求输入以下配置内容</p>    <ul>     <li> <p>项目名称</p> </li>     <li> <p>项目描述</p> </li>     <li> <p>作者</p> </li>     <li> <p>选择 Vue 构建:运行+编译 或 仅运行时</p> </li>     <li> <p>是否安装 vue-loader</p> </li>     <li> <p>是否使用 ESLint</p>      <ul>       <li> <p>如果是,请选择模式:标准模式、AirBNB 模式、自定义</p> </li>      </ul> </li>     <li> <p>是否使用 Karma + Mocha 的单元测试</p> </li>     <li> <p>是否使用 Nightwatch e2e 测试</p> </li>    </ul>    <p style="text-align:center"><img src="https://simg.open-open.com/show/32a5f473bb9b6871d479dd01817195e1.png"></p>    <p>安装完成后,即可看到以下文件结构:</p>    <pre>  <code class="language-javascript">.  |-- build                            // 项目构建相关代码  |   |-- build.js                     // 生产环境构建代码  |   |-- check-version.js             // 检查 node、npm 等版本  |   |-- dev-client.js                // 热重载相关  |   |-- dev-server.js                // 构建本地服务器  |   |-- utils.js                     // 构建工具相关  |   |-- webpack.base.conf.js         // webpack 基础配置(出入口和 loader)  |   |-- webpack.dev.conf.js          // webpack 开发环境配置  |   |-- webpack.prod.conf.js         // webpack 生产环境配置  |-- config                           // 项目开发环境配置  |   |-- dev.env.js                   // 开发环境变量  |   |-- index.js                     // 项目一些配置变量(开发环境接口转发将在此配置)  |   |-- prod.env.js                  // 生产环境变量  |   |-- test.env.js                  // 测试环境变量  |-- src                              // 源码目录  |   |-- components                   // vue 公共组件  |   |-- store                        // vuex 的状态管理  |   |-- App.vue                      // 页面入口文件  |   |-- main.js                      // 程序入口文件,加载各种公共组件  |-- static                           // 静态文件,比如一些图片,json数据等  |-- test                             // 自动化测试相关文件  |-- .babelrc                         // ES6语法编译配置  |-- .editorconfig                    // 定义代码格式  |-- .eslintignore                    // ESLint 检查忽略的文件  |-- .eslistrc.js                     // ESLint 文件,如需更改规则则在此文件添加  |-- .gitignore                       // git 上传需要忽略的文件  |-- README.md                        // 项目说明  |-- index.html                       // 入口页面  |-- package.json                     // 项目基本信息  .</code></pre>    <h2>ESLint 配置</h2>    <p>ESLint 配置在根目录的 .eslintrc.js 里。</p>    <p>正常情况下,ESLint 报错是因为你的代码不符合现有的 ESLint 规范。</p>    <p>如果你的情况实在不想被 ESLint 报错,我举出两个解决方案,来处理 ESLint 报错问题。</p>    <p>注:本例使用 AirBNB ESLint 规则。</p>    <p>例:通过 npm run dev 启动服务,打开 ./src/main.js ,添加一句 console.log('abc') ,结果如下:</p>    <pre>  <code class="language-javascript">import Vue from 'vue';  import App from './App';  import store from './vuex/store';  /* import router from './router';*/    // 添加此句  console.log('abc')    /* eslint-disable no-new */  new Vue({    el: '#app',    /* router,*/    template: '<App/>',    components: { App },    store,  });</code></pre>    <p>注:为做演示,句末未添加分号。</p>    <p>保存 main.js 文件后,页面与终端均提示如下错误:</p>    <pre>  <code class="language-javascript">ERROR  Failed to compile with 1 errors    error  in ./src/main.js    ⚠  http://eslint.org/docs/rules/no-console  Unexpected console statement    C:\Users\Ralf\Documents\code\ralfz\vue\test\vue02\src\main.js:8:1    console.log('abc')     ^    ✘  http://eslint.org/docs/rules/semi        Missing semicolon    C:\Users\Ralf\Documents\code\ralfz\vue\test\vue02\src\main.js:8:19    console.log('abc')                       ^  ✘ 2 problems (1 error, 1 warning)  Errors:    1  http://eslint.org/docs/rules/semi  Warnings:    1  http://eslint.org/docs/rules/no-console   @ multi ./build/dev-client ./src/main.js</code></pre>    <p>以上输出表明出现两个问题:</p>    <ol>     <li> <p>警告:不允许 console 语句。</p> </li>     <li> <p>错误:句末未加分号。</p> </li>    </ol>    <p>解决问题 1</p>    <ul>     <li> <p>在 .eslintrc.js 文件中的 rules 键名下添加 'no-console': 'off', ,即关闭 console 警告。</p> </li>    </ul>    <p>解决问题 2</p>    <ul>     <li> <p>你可以选择继续在 .eslintrc.js 文件中添加关闭句末分号判定的规则。</p> </li>     <li> <p>或者,也可以把 package.json 文件中的 script 下的 lint 命令改为</p> "lint": "eslint --fix *.js *.vue src/* test/unit/specs/* test/e2e/specs/*"</li>    </ul>    <p>即自动修复。值得注意的是,自动修复不能解决所有问题,有时也不甚完美,可以多试几次体会下 fix 的效果。</p>    <p>做完更改后,重新运行 npm run dev 即可看到无问题报告,并且 console 语句后已经自动加上了分号。</p>    <h2>静态页面开发</h2>    <p>此时,浏览器应该已经打开了 localhost:8080 页面。</p>    <p>在此情况下,请尝试更改 /src/App.vue 和 /src/components/Hello.vue 文件中 <template> 标签内的内容,保存后即可立即看到浏览器页面已自动更新了你做出的改动。</p>    <p>接下来,你需要去阅读并学习 Vue.js 教程页面 ,务必熟悉 <strong>基础</strong> 部分的内容,掌握 <strong> 组件 </strong> 章节。</p>    <p>熟悉之后,便可以完成基础的静态页面(或者说是组件)设计工作。</p>    <p>本项目使用了基于 Vue 2.0 和 Material Desigin 的 UI 组件库 Muse-UI 。</p>    <p>提示: ./src/components 文件夹多用于保存公用组件。至于页面组件,推荐在新建 ./src/view 文件夹后存放于此。</p>    <h2>vue-router 2 使用</h2>    <p>当一个个静态组件完成后,需要按照路由组织这些组件文件。</p>    <p>请前往 vue-router 2 介绍 阅读 <strong>基础</strong> 部分教程,并可以边阅读边配置路由。</p>    <p>路由文件是 ./src/router.index.js 。</p>    <p>本项目中使用了 HTML5 History 模式 ,路由配置比较简单,可以参考。</p>    <h2>API 请求转发配置</h2>    <p>至此,你应该已经完成了所有的静态页面的工作,接下来我们准备搭建请求,为后面的 xhr 请求做好准备。</p>    <ol>     <li> <p>打开 http://api.douban.com/v2/movie/in_theaters 查看接口数据,留意此地址。</p> </li>     <li> <p>在 ./config/index.js 中的 proxyTable 配置代理:</p> <pre>  <code class="language-javascript">proxyTable: {      '/api': {          target: 'http://api.douban.com/v2',          changeOrigin: true,          pathRewrite: {              '^/api': ''          }      }  }</code></pre> </li>     <li> <p>重新启动 npm run dev ,打开 localhost:8080/api/movie/in_theaters 查看结果是否与直接请求豆瓣 API 相同。</p> </li>     <li> <p>本应该使用了以下 API:</p>      <ul>       <li> <p>/v2/movie/search?q={text} 电影搜索api;</p> </li>       <li> <p>/v2/movie/in_theaters 正在上映的电影;</p> </li>       <li> <p>/v2/movie/coming_soon 即将上映的电影;</p> </li>       <li> <p>/v2/movie/subject/:id 单个电影条目信息。</p> </li>      </ul> </li>    </ol>    <p>这样我们就可以在应用中调用 /api/movie/in_theaters 来访问 http://api.douban.com/v2/movie/in_theaters ,从而解决跨域的问题。</p>    <h2>使用 axios</h2>    <p>axios 库使用起来相当简单。</p>    <p>你可以在单个组件中尝试引入并调用:</p>    <pre>  <code class="language-javascript">import axios from 'axios';  axios.get('/v2/movie/in_theaters', { 'city': '广州' })      .then((result) => {          console.log(result);      });</code></pre>    <p>这里,可以用返回的 result 去更新 data(){ } 中 return 的数据。</p>    <h2>使用 Vuex 并分离代码</h2>    <p>为了试代码更加结构化,我们应当将数据请求和视图分离。</p>    <p>这一节中,我们有两个任务要做:</p>    <ol>     <li> <p>分离数据请求层逻辑。</p> </li>     <li> <p>使用 Vuex 管理状态。</p> </li>    </ol>    <p>将二者放到同一节中主要是因为二者再同一目录下,我们来查看 ./store 文件夹的结构:</p>    <pre>  <code class="language-javascript">.  |-- store                          // 数据处理根目录  |   |-- movies                     // 单个电影模块文件夹  |   |   |-- api.js                 // 电影模块对外开放的接口  |   |   |-- module.js              // Vuex 模块  |   |   |-- type.js                // Vuex 操作 key  |   |-- base.js                    // 基础方法  |   |-- store.js                   // Vuex 入口  .</code></pre>    <p>针对第一个任务:</p>    <ul>     <li> <p>base.js 存放封装的基础请求函数</p> </li>     <li> <p>**/api.js 存放该模块下公开的请求函数</p> </li>    </ul>    <p>针对第二个任务,我们需要先了解 Vuex。</p>    <p>请查看 <a href="/misc/goto?guid=4959741973466267992" rel="nofollow,noindex">Vuex 文档</a> ,了解其 <strong>核心概念</strong> 。</p>    <p>Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。Vuex 也集成到 Vue 的官方调试工具 devtools extension,提供了诸如零配置的 time-travel 调试、状态快照导入导出等高级调试功能。</p>    <p>其实在我看来,Vuex 相当于某种意义上设置了读写权限的全局变量,将数据保存保存到该“全局变量”下,并通过一定的方法去读写数据。(希望这能帮助你理解 Vuex)</p>    <p>为了方便模块化管理:</p>    <ul>     <li> <p>我将 store.js 作为入口文件,去挂载各个模块;</p> </li>     <li> <p>/movies/ 文件夹下为电影相关的模块;</p> </li>     <li> <p>/movies/moudule.js 为电影模块的主要 Vuex 文件;</p> </li>     <li> <p>/movies/type.js 为 使用常量替代 Mutation 事件类型 的实现。</p> </li>    </ul>    <p>到此便完成了所有开发上的基础问题。</p>    <h2>发布</h2>    <ol>     <li> <p>运行 npm run build ,即可在生成的 /dist 文件夹下看到所有文件。</p> </li>     <li> <p>将文件复制到你的服务器上某个目录(我的是 /var/www/Vdo/dist ),按照下一节配置 Nginx 即可</p> </li>    </ol>    <p>提示:可以使用 scp 命令将本地文件拷贝至服务器,例如 scp -P 20 -r dist user@host:/target/location</p>    <h2>附:配置与开启 Nginx</h2>    <p>注:以下以 CentOS 为例</p>    <pre>  <code class="language-javascript">yum install nginx  /etc/nginx/conf.d/default.conf  /doc/nginx.conf  nginx  </code></pre>    <p>提示:</p>    <ol>     <li> <p>403 Forbidden 错误可能是由于文件和文件夹权限引起的,请用 chmod 把存放 index.html 的所有路径上的文件夹权限设置为 755,并将 index.html 文件权限设置成 644 即可。</p> </li>     <li> <p>更改 Nginx 配置文件后,可以使用 nginx -s reload 命令刷新。</p> </li>    </ol>    <h2> </h2>    <p> </p>    <p> </p>