Vue Vuex vue-route学习项目

Vue 2.0已经正式发布好长时间了。想找一个Vue.js Vuex vue-route的学习项目来练手。作个电商App吧,上gitHub搜索了一下搜到一大堆,不过基本上都不是使用单文件组件开发的,更不用说基于Vue.js全家桶了。本项目不同的地方在于使用vue-cli + webpack template人开发模式,还要求Web和移动端一体化,也就是响应式Web,并且不能Mock数据,额外须要有一个提供restful web api的后端应用。哈哈,就是搞全栈呀。css

1、后端服务

采用的是Express + mLab + Mongoose的技术栈。http模块加上Express自带路由利用中间件思想能够很方便地基于Node开发提供restful web api的Web应用。考虑到方便在线演示部署,数据库选用了MongoDB的云服务mLab。固然,提交数据到数据库时通常要选用便捷操做的对象模型工具(ORM)。在node.js和MongoDB数据库环境下,Mongoose做为就是不二之选了。具体实现请看https://github.com/szriafan/v...。另外,我将node.js代码免费托管到了https://heroku.com/(主机数据库都免费,爽呀)。如今直接在浏览器访问https://vue-shop-api.herokuap...就能够返回商品列表所须要的数据了,固然更好的选择是使用Postman之类的HTTP请求调试工具。前端

若是咱们不了解后端和mLab,只要在ations.js手动将axios的baseURL改成https://vue-shop-api.herokuap...就能够了。或者对mLab数据API足够了解,也能够不写Node.js应用的。为了方便你们全面学习测试,建议你们最好访问本地的restful应用。vue

注意,访问不一样端口的本地服务或不一样域名的远程服务都有跨域问题,使用CORS能够很好解决这个问题。node

app.all('/*', function(req, res, next) {
  res.header('Access-Control-Allow-Origin', '*');
  res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
  res.header('Access-Control-Allow-Headers', 'Content-type,Accept,X-Access-Token,X-Key');
  if (req.method == 'OPTIONS') {
    res.status(200).end();
  } else {
    next();
  }
});

好了,接下来集中精力开发前端。webpack

2、前端

一、运行vue-cli + webpack template就获得了一个Vue.js Vuex vue-route全家桶脚手架项目。咱们要完成两个部分:前台展现和后台管理。ios

二、前台展现有两个功能:展现商品列表和详情的功能、添加商品到购物车的功能。商品列表和详情页面都能添加商品到购物车,商品列表页只能经过点击按钮一次添加一件商品,但详情页面能够经过+-按钮或文本框输入来改变商品数量(不能大于库存),再经过点击添加按钮一次性添加多件商品。购物车列表页也能够能够经过+-按钮或文本框输入来改变商品数量,与详情页面操做不同的是购物车列表页改变商品数量时会同步保存数据,即便从新刷新页面或关闭浏览器,都会显示已保存的数据。而但详情页面若是改变数量后没有按添加按钮就不会添加商品到购物车。git

三、后台管理有的功能就是实现商品及品牌的CRUD操做。在新增修改商品时,会经过下拉框选择品牌,而下拉框用品牌数据来填充的。所以商品数据是依赖品牌数据的,所以后台管理时先应该添加商品数据。github

四、明确了上述需求后,先看到一下最终效果吧。源码在这里下载web

五、咱们来讲一说具体实现。SPA通常都有路由,复杂Vue.js应用页面之间的导航都要用到vue-route。vue-rout使用JavaScript动态初始化配置全局对象,将组件(components)映射到路由(routes),而后告诉vue-router在哪里渲染它们。经过注入路由器,咱们还能够在任何组件内经过this.$router访问路由器,也能够经过 this.$route访问当前路由。好比说当添加或修改商品成功后咱们就是经过this.$router回到商品列表页的。模板中的组件让用户在具备路由功能的应用中(点击)导航,其中to表示目标路由的连接,这个值能够是一个字符串或者是描述目标位置的对象,对应路由配置对象的path属性值或name对象。好比说App模板中的组件to属性设置为{name: 'Home'},经过路由映射会导航到Home组件所在的页面。建议设置to的属性值为name对象,由于这个对象通常不多改动,而首页连接设置成'/',一样是由于这个值不多改动。另外首页连接还得添加exact属性来精确匹配连接,你们都知道,其它path值确定包含/,不设置该属性会形成导航连接样式都添加激活连接类名。vue-router

六、以下面的文件路径树所示,本项目使用了大量的嵌套单文件组件,下面的项目components和pages文件夹包含了大量的单文件组件。嵌套单文件组件提升了代码复用性,让分模块团队开发变得容易,这对于开发大型Vue.js应用尤其重要。不过Vue组件使用单向数据流向下进行组件数据通讯,大量的会让代码难以维护,此时咱们就应该考虑用Vuex来实现多个组件共享状态。

├─components
│ ├─cart
│ │ CartControl.vue
│ │ CartItem.vue
│ ├─common
│ │ Loading.vue
│ ├─manufacturer
│ │ ManufacturerForm.vue
│ └─product
│ AddToCartButton.vue
│ ProductDetails.vue
│ ProductForm.vue
│ ProductItem.vue
│ ProductList.vue
├─pages
│ │ Cart.vue
│ │ Details.vue
│ │ Home.vue
│ └─admin
│ │ Index.vue
│ ├─manufacturer
│ │ Edit.vue
│ │ Manufacturers.vue
│ │ New.vue
│ └─product
│ Edit.vue
│ New.vue
│ Products.vue

以下面的文件路径树所示,本项目Vuex代码集中store文件夹中。Vuex应用的核心store(仓库),包含应用中大部分的状态,如商品、品牌、购物车数组, 咱们是在index.js中定义的; Action函数接受一个与store实例具备相同方法和属性的context对象,能够包含任意异步操做,如对后台数据访问商品和品牌数据的异步操做,咱们是在action.js中定义的;Vuex中的Mutation很是相似于事件:每一个Mutation都有一个字符串的事件类型 (type) 和一个回调函数(handler)。如对异步回调函数和添加商品到购物车时的同步函数,咱们是在mutations.js中定义的;Vuex容许定义getter从store中的state中派生出一些状态(计算属性),如从商品和品牌数组状态中派生出根据id查询到的状态,咱们是在getters.js中定义的;另外,咱们的mutation-types.js中使用常量替代mutation事件类型以方便多人协做。

├─store
│ actions.js
│ getters.js
│ index.js
│ mutation-types.js
│ mutations.js

在任意组件中访问store的计算属性时可以使用mapStatemapGetters辅助函数,分发Action、Mutation时使用mapActionmapMutation辅助函数。它们本质是都是语法糖,将store中的state、getter映射到局部计算属性,或将mutations和actions映射到局部方法,从而避免使用this.$store的方式来访问相应的函数。固然,并非全部状况下都能使用辅助函数,如created生命周期钩子函数中或条件语句中。

请注意,使用Vuex并不意味着咱们须要将全部的状态放入Vuex。若是有些状态严格属于单个组件,最好仍是做为组件的局部状态。咱们应该根据应用开发须要进行权衡和肯定。如CartControl组件中的count状态和每一个cart组件绑定不能单例化,所以不须要用放入Vuex来管理。

七、以下面的文件路径树所示,本项目plugins文件夹中有两个插件。插件会为Vue.js添加全局功能,本质上就是封装更好,复用性更强的组件,Vuex和vue-route就是这样两个优秀的插件。若是咱们想在任意组件中弹出模态框和信息提示、控制加载动画等,怎么办?每一个组件都加一个布尔控制变量确定致使代码冗余难以维护。用Vuex集中在根组件中处理也好不到哪里去,由于要写不少代码来判断事件类型。因此咱们得本身开发插件,感兴趣的话可参考vue-dialog和vue-toast的代码自行开发一个Loading插件。那样就能够在任意组件中控制加载动画了。

├─plugins
│ ├─vue-dialog
│ │ │ index.js
│ │ │ VueDialog.vue
│ │ └─themes
│ │ default.css
│ │ ios.css
│ └─vue-toast
│ │ index.js
│ └─components
│ Notification.vue
│ VueToast.vue

八、当咱们build好代码,在IE或手机自带的Android浏览器上运行时,发现添加商品到购物车的功能用不了。报错:Vuex requires a Promise polyfill in this browser,原来Vuex依赖Promise。若是浏览器并无实现Promise,那么可使用一个 polyfill的库,例如babel-polyfill。
第一步: 安装

npm install --save babel-polyfill

第二步:在webpack.config.js文件中,将entry的代码改成以下:

entry: {
    app: ["babel-polyfill", "./src/main.js"]
 }

或者将下列代码添加到使用Vuex以前的一个地方:

import 'babel-polyfill'

3、有待实现和改进功能

  • 登陆注册模块
  • 会员模块
  • 支付模块
  • 列表搜索排序功能
  • 图片列表的懒加载
  • 轮播图效果
  • 加入购物车动画
  • 页面切换动画

Vue.js devtools是一个很好的测试Vue.js应用的工具,对Vuex也支持得很好,值得拥有。

相关文章
相关标签/搜索