微豆 Vdo - Vue 2.0 实现豆瓣 Web App 教程
微豆 Vdo
一个使用 Vue.js 与 Material Design 重构豆瓣的项目。
GitHub: https://github.com/RalfZhang/vdo
快速使用
1 | # 克隆项目到本地 |
教程
安装 vue-cli 脚手架
运行如下命令,即可创建一个名为 my-project 的 vue 项目,并且通过本地 8080 端口启动服务
1 | npm install -g vue-cli |
在运行 vue init webpack my-project
后,会依次要求输入以下配置内容
- 项目名称
- 项目描述
- 作者
- 选择 Vue 构建:运行+编译 或 仅运行时
- 是否安装 vue-loader
- 是否使用 ESLint
- 如果是,请选择模式:标准模式、AirBNB 模式、自定义
- 是否使用 Karma + Mocha 的单元测试
- 是否使用 Nightwatch e2e 测试
安装完成后,即可看到以下文件结构:
1 | . |
ESLint 配置
ESLint 配置在根目录的 .eslintrc.js
里。
正常情况下,ESLint 报错是因为你的代码不符合现有的 ESLint 规范。
如果你的情况实在不想被 ESLint 报错,我举出两个解决方案,来处理 ESLint 报错问题。
注:本例使用 AirBNB ESLint 规则。
例:通过 npm run dev
启动服务,打开 ./src/main.js
,添加一句 console.log('abc')
,结果如下:
1 | import Vue from 'vue'; |
注:为做演示,句末未添加分号。
保存 main.js
文件后,页面与终端均提示如下错误:
1 | ERROR Failed to compile with 1 errors |
以上输出表明出现两个问题:
- 警告:不允许 console 语句。
- 错误:句末未加分号。
解决问题 1
- 在
.eslintrc.js
文件中的rules
键名下添加'no-console': 'off',
,即关闭 console 警告。
解决问题 2
- 你可以选择继续在
.eslintrc.js
文件中添加关闭句末分号判定的规则。 - 或者,也可以把
package.json
文件中的script
下的lint
命令改为"lint": "eslint --fix *.js *.vue src/* test/unit/specs/* test/e2e/specs/*"
。同时,将/build/webpack.base.conf.js
里formatter: require('eslint-friendly-formatter')
后添加, fix: true
即自动修复。(值得注意的是,自动修复不能解决所有问题,有时也不甚完美,可以多试几次体会下 fix 的效果。)
做完更改后,重新运行 npm run dev
即可看到无问题报告,并且 console
语句后已经自动加上了分号。
静态页面开发
此时,浏览器应该已经打开了 localhost:8080 页面。
在此情况下,请尝试更改 /src/App.vue
和 /src/components/Hello.vue
文件中<template>
标签内的内容,保存后即可立即看到浏览器页面已自动更新了你做出的改动。
接下来,你需要去阅读并学习 Vue.js 教程页面,务必熟悉 基础 部分的内容,掌握 组件 章节。
熟悉之后,便可以完成基础的静态页面(或者说是组件)设计工作。
本项目使用了基于 Vue 2.0 和 Material Desigin 的 UI 组件库 Muse-UI。
提示:./src/components
文件夹多用于保存公用组件。至于页面组件,推荐在新建 ./src/view
文件夹后存放于此。
vue-router 2 使用
当一个个静态组件完成后,需要按照路由组织这些组件文件。
请前往 vue-router 2 介绍 阅读 基础 部分教程,并可以边阅读边配置路由。
路由文件是 ./src/router.index.js
。
本项目中使用了 HTML5 History 模式,路由配置比较简单,可以参考。
API 请求转发配置
至此,你应该已经完成了所有的静态页面的工作,接下来我们准备搭建请求,为后面的 xhr 请求做好准备。
打开
http://api.douban.com/v2/movie/in_theaters
查看接口数据,留意此地址。在
./config/index.js
中的proxyTable
配置代理:1
2
3
4
5
6
7
8
9proxyTable: {
'/api': {
target: 'http://api.douban.com/v2',
changeOrigin: true,
pathRewrite: {
'^/api': ''
}
}
}重新启动
npm run dev
,打开localhost:8080/api/movie/in_theaters
查看结果是否与直接请求豆瓣 API 相同。本应该使用了以下 API:
/v2/movie/search?q={text}
电影搜索api;/v2/movie/in_theaters
正在上映的电影;/v2/movie/coming_soon
即将上映的电影;/v2/movie/subject/:id
单个电影条目信息。
更多请参考 豆瓣电影 API 文档。
这样我们就可以在应用中调用 /api/movie/in_theaters
来访问 http://api.douban.com/v2/movie/in_theaters
,从而解决跨域的问题。
使用 axios
axios 库使用起来相当简单。
你可以在单个组件中尝试引入并调用:
1 | import axios from 'axios'; |
这里,可以用返回的 result
去更新 data(){ }
中 return
的数据。
更多 axios 用法请参考 文档
使用 Vuex 并分离代码
为了试代码更加结构化,我们应当将数据请求和视图分离。
这一节中,我们有两个任务要做:
- 分离数据请求层逻辑。
- 使用 Vuex 管理状态。
将二者放到同一节中主要是因为二者再同一目录下,我们来查看 ./store
文件夹的结构:
1 | . |
针对第一个任务:
base.js
存放封装的基础请求函数**/api.js
存放该模块下公开的请求函数
针对第二个任务,我们需要先了解 Vuex。
请查看 Vuex 文档,了解其 核心概念。
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。Vuex 也集成到 Vue 的官方调试工具 devtools extension,提供了诸如零配置的 time-travel 调试、状态快照导入导出等高级调试功能。
其实在我看来,Vuex 相当于某种意义上设置了读写权限的全局变量,将数据保存保存到该“全局变量”下,并通过一定的方法去读写数据。(希望这能帮助你理解 Vuex)
为了方便模块化管理:
- 我将
store.js
作为入口文件,去挂载各个模块; /movies/
文件夹下为电影相关的模块;/movies/moudule.js
为电影模块的主要 Vuex 文件;/movies/type.js
为使用常量替代 Mutation 事件类型的实现。
到此便完成了所有开发上的基础问题。
发布
- 运行
npm run build
,即可在生成的/dist
文件夹下看到所有文件。 - 将文件复制到你的服务器上某个目录(我的是
/var/www/Vdo/dist
),按照下一节配置 Nginx 即可
提示:可以使用 scp
命令将本地文件拷贝至服务器,例如 scp -P 20 -r dist user@host:/target/location
附:配置与开启 Nginx
注:以下以 CentOS 为例
- 服务器安装 Nginx:
yum install nginx
- 服务器打开
/etc/nginx/conf.d/default.conf
- 替换全文为本项目
/doc/nginx.conf
文件中的内容 - 服务器运行
nginx
提示:
403 Forbidden
错误可能是由于文件和文件夹权限引起的,请用chmod
把存放index.html
的所有路径上的文件夹权限设置为 755,并将index.html
文件权限设置成 644 即可。- 更改 Nginx 配置文件后,可以使用
nginx -s reload
命令刷新。
结语
至此,主体工作已经完成。
欢迎 Star 本项目 https://github.com/RalfZhang/vdo 。
感谢&参考
- https://github.com/superman66/vue2.x-douban
- http://blog.guowenfh.com/2016/03/24/vue-webpack-01-base/
- http://vuejs-templates.github.io/webpack/
- https://github.com/mzabriskie/axios
- https://museui.github.io/
- https://vuejs-templates.github.io/webpack/
License
MIT