# 使用Vue全家桶+Node.js搭建的小型全栈项目
## 前言
接触vue框架也有一个多月的时间了,整理下之前做过的一个小demo,主要是熟悉vue全家桶技术,界面布局模仿的是猫眼,数据使用的是豆瓣开发者提供的后台接口。整个过程从搭建脚手架到最后项目打包上线,是一个完整的开发流程,中间涉及到的知识点比较多,也比较零碎,通过这个项目对我自己的知识体系做一个梳理和总结。
项目已上传github,欢迎大家下载交流。
前端项目地址:https://github.com/Hanxueqing/Douban-Movie
后台数据地址:https://github.com/Hanxueqing/Douban-API
## 项目技术栈
- Vue.js全家桶:vue-cli、vue-router、vue-resource(新版已替换成axios)、vuex
- 语言:ES6
- UI:Mint-UI、Vant部分组件
- 后台接口:express、MongoDB。关于如何制作数据接口可以参考我之前的这篇文章:[《不会写API数据接口的前端攻城狮不是好程序猿》](https://www.jianshu.com/p/966a03327c76)。
- 打包上线:阿里云服务器。关于如何申请、配置阿里云服务器,并且将项目打包上线可以参考我之前的这篇文章:[《从0到1:阿里云服务器部署web项目全过程》](https://www.jianshu.com/p/3693dad9b574)。
## 项目运行
```
# 克隆到本地
git clone git@github.com:Hanxueqing/Douban-Movie.git
# 安装依赖
npm install
# 开启本地服务器localhost:8080
yarn serve
# 发布环境
yarn build
```
## 项目开发
### 1、安装vue-cli3脚手架
现在使用前端工程化开发项目是主流的趋势,也就是说,我们需要使用一些工具来搭建vue的开发环境,一般情况下我们使用webpack来搭建,在这里我们直接使用vue官方提供的,基于webpack的脚手架工具:vue-cli。
#### (1)全局安装webpack
```
cnpm install webpack -g
```
#### (2)全局安装yarn
```
cnpm install yarn -g
```
#### (3)全局安装vue-cli
```
cnpm install -g @vue/cli
OR
yarn global add @vue/cli
```
#### (4)查看安装结果
我的电脑已经安装过了,依次执行命令:
```
node -v
yarn -v
vue -V (注意这里是大写的“V”)
```
*注意:要求node.js版本8或者8+*
出现相应的版本号,则说明安装成功
![](http://ww4.sinaimg.cn/large/006tNc79ly1g58ujsv6p4j30hw050gnc.jpg)
### 2.用vue-cli来构建项目
#### (1)创建项目
```
vue create douban(项目名称)
```
(注意这里的名字不能有大写字母,如果有会报错*Sorry, name can no longer contain capital letters*)
![](http://ww3.sinaimg.cn/large/006tNc79ly1g58um3khlij30mw044js1.jpg)
阮一峰老师博客[为什么文件名要小写](https://link.jianshu.com?t=http://www.ruanyifeng.com/blog/2017/02/filename-should-be-lowercase.html)可以参考一下。
第一个vue-model是我保存过的设置,第一次create的时候是没有的。 default是默认设置,会给你安装babel和eslint模块,我们选择第三个Manually select features自己手动配置。
![](http://ww2.sinaimg.cn/large/006tNc79ly1g58ummhyctj30ms07q3zh.jpg)
输入空格是选择当前选项,输入a是全选。
(加粗的是要选择的配置项)
**Babel** 安装这个模块后就可以识别ES6的语法,不然只能识别ES5的语法
TypeScript 是 JavaScript 的一个超集,支持 ECMAScript 6 标准。
Progressive Web App (PWA) Support 渐进式增强的前端网页技术PWA,是一个专门的学科,可以做离线存储的功能,手机断网的情况下也可以访问这个页面,我们目前用不到,先不安装了。
**Router** 路由
**Vuex** 全局状态管理
**CSS Pre-processors** CSS预处理语言
Linter / Formatter 格式化工具,帮助我们更好的编写代码
Unit Testing 单元测试
E2E Testing
选择好这四项之后输入enter回车
接下几项配置依次是:
1. 是否使用history模式配置路由,输入**n**,回车
2. 由于我们刚才选择了CSS预处理语言,所以这里我们就选择**Sass/SCSS(with node-sass)**这个稳定版本
3. 你需要在哪里存储你的这些配置文件,我们选择**in package.json**
4. 最后是你想将这些配置保存为一个预设应用于以后的文件吗,保存以后就不用再手动配置这些选项,以后直接使用即可,我之前保存过了,这里就先选择**n**。
![](http://ww3.sinaimg.cn/large/006tNc79ly1g58uzqnavzj31as03swfw.jpg)
回车之后就进入了下载状态,速度取决于你当前的网速。
![](http://ww3.sinaimg.cn/large/006tNc79ly1g58v8glgr7j30r408ota6.jpg)
安装成功后会提示我们进入douban这个文件夹下运行yarn serve启动监听。
![](http://ww3.sinaimg.cn/large/006tNc79ly1g58v96amr2j30iy0fc40s.jpg)
#### (2)加载编译文件
将Vue.config.js编译文件拷贝到douban文件夹下
### 3、整理下src文件夹
#### (1)router
新建router文件夹,将router.js文件拖进去,重命名为index.js,routes里面的内容删掉。
![](http://ww3.sinaimg.cn/large/006tNc79ly1g58vbmvsqnj30zc0f0abz.jpg)
#### (2)views
views文件夹下的两个.vue文件删掉,assets文件夹下的logo图删掉,components文件夹下的HelloWorld组件删掉 。
#### (3)App.vue
App.vue文件样式删掉,id名为app的div内容删掉。
![](http://ww4.sinaimg.cn/large/006tNc79ly1g58vglxkqrj30qc0fcjsw.jpg)
#### (4)在views中新建页面
在views文件夹下依次创建首页、书影音、广播、小组、我的页面,文件夹下创建index.vue文件,以vue为后缀名的文件包含template、script、style三部分,webpack在解析.vue文件时以vue-loader加载器加载。
#### (5)在router中配置路由
在router文件夹下依次创建首页、书影音、广播、小组、我的页面js路由文件,每一个路由配置一个name名字,方便我们以后通过具名路由的方式找到这个路由组件,最后在index.js中引入。
#### (6)在App.vue中引入<router-view>
#### (7)编写样式文件
新建stylesheets文件夹
webpack在打包的过程中不会处理前面加下划线的文件,避免重复进行打包
依次创建:_base.scss基本样式
_commons.scss通用样式
_mixins.scss混合样式
_reset.scss重置样式
最后在main.scss文件夹下依次引入
```scss
@import "_base.scss";
@import "_mixins.scss";
@import "_reset.scss";
@import "_commons.scss";
```
在main.js中将样式作为一个模块引入
```javascript
//引入main.scss文件
import "./stylesheets/main.scss"
```
### 4、Tabbar组件
#### (1)slot插槽:具名槽口、匿名槽口
首先我们将正常状态图标和选中状态图标依次引入,写好样式,给正常状态图标命名为normalImg,选中状态图标命名为activeImg,这里我们用到了slot插槽。在子组件中写上slot标签,并赋上name值,作为具名槽口,就可以在父组件传入要插入的内容。
子组件:
```js
<span><slot name = "normalImg"></slot></span>
<span><slot name = "activeImg"></slot></span>
```
父组件:
```js
<TabItem>
<img slot = "normalImg" src = "../../assets/ic_tab_home_normal.png" alt = "">
<img slot = "activeImg" src = "../../assets/ic_tab_home_active.png" alt = "">
</TabItem>
```
#### (2)v-if/v-else指令:控制显示和隐藏
第一步实现点击图标由普通样式切换为选中样式,需要设置一个flag属性,来控制normalImg与activeImg的显示,这里我们用到了v-if和v-else指令
```js
<span v-if = "!flag"><slot name = "normalImg"></slot></span>
<span v-else><slot name = "activeImg"></slot></span>
```
#### (3)父组件给子组件传值的两种方式:事件绑定、自定义事件
在父组件中给子组件传递唯一txt、mark、sel属性值以及changeSelected方法,父组件通过属性绑定的方法把selected值传递�