使用Vue创建一个在线商店

git代码:https://github.com/chentianwei411/vue-router-demo.gitcss

 

使用Vue-CLI3html

webpack, ESLInt,vue

Vuex,node

vue-routerjquery

 

axios  (用于异步发出请求)webpack

vee-validate  (用于表格验证)ios

bootstrap-vuegit

vue-toastr-2   (用于添加通知)  (须要yarn add jquery, 须要yarn add toastr )github


  

The Project结构:

  • Products listing
  • Product Details (一个商品的详细介绍)
  • Cart(Add, Remove, and Listing)
  • Admin Section  (CRUD,管理Products)

 

基础:

须要安装node到最新版本,而后使用npm安装vue-cli。web

npm install -g vue-cli

 

使用vue ui用户界面建立一个app,并选择使用的插件。

(具体使用见我以前的博文)https://www.cnblogs.com/chentianwei/p/10116155.html

 

Vue的基础知识:

MVC,MVVM,MVP的区别/ Vue中忽略的知识点!

 

完成后的文件结构:

 


 

 

Routing 

参考:vue-router 

//2个基本组件
<router-view></router-view>

<router-link to="/">Home</router-link>

// store.js中的routes
 export default new Router({ routes: [ { path: '/', name: 'Home', component: Home }, { path: '/admin', //由于子路径有默认的,因此无需 name: 'Admin',
 component: Index, // children
 children: [ { path: 'new', name: 'New', component: New },

 

还有嵌套路由,及嵌套命名路由,动态路由。

过渡<transition>包裹<router-view>。


 

Form验证

使用VeeValidate便可。 见博文:https://www.cnblogs.com/chentianwei/p/10128205.html

看productForm.vue:

代码摘录:

//template: 
<form @submit.prevent="saveProduct">
      <div class="row">
      <div class="col-lg-7 col-md-5 col-sm-12 col-xs-12">
        <div class="form-group">
          <label>Name</label>
          <input type="text" placeholder="Name" v-model="model.name" v-validate="'required'" name="name" :class="{'form-control': true, 'error': errors.has('name') }" />
          <span class="small text-danger" v-show="errors.has('name')">Name is required</span>
        </div>
<script> import { ERROR_MSG } from '../../store/mutations-types.js' export default { // isEditing prop用于显示提交按钮上的名字
    props: ['model', 'isEditing', 'manufacturers'], methods: { saveProduct() {// 这是插件的方法,会返回一个Promise:
        this.$validator.validateAll().then(() => { // emit一个event给父组件
          this.$emit('save-product', this.model) }).catch(() => { // 提交一个错误到Vuex.Store
          this.$store.commit(ERROR_MSG, { type: 'error', title: 'Validation!', content: 'Please ensure the form is valid' }) }) } } } </script>


 

 

Vuex

本app核心要点解释(具体见git上的代码)

1.store.js文件,state的状态管理根文件。

import { productGetters, manufacturerGetters } from './getters.js'
//...略...
 export default new Vuex.Store({ strict: true, state: {//略... },
  // 把传入的对象合并:Object.assign()
  getters: Object.assign({}, productGetters, manufacturerGetters),

 

2.getters.js

要使用的计算属性。

 

3. mutations-types.js

// When creating the mutation and while committing to the mutation. // This creates a layer of possible typographical error. // You can use constants to replace these types // and allow tools like IntelliSense to help you avoid typos and errors: // 使用常量,来防止语法错误。

 

4. actions

import axios from 'axios'

//...

// 这里定义的actions都是由各个组件来激发的 // 例如: allProducts,它在Products.vue中被激发 // 提交ALL_PRODUCTS mutation,它会开始一个loading spinner即记录此时是加载中。 // 以后使用axios发出一个HTML request,这是异步函数。 // 收到response后,提交一个带有返回data做为参数的success mutation。 // 这个mutiation会修改state的products,并改showLoader为false,表明结束加载。
 export const productActions = { // Prodcuts.vue, PrdouctList.vue中被使用。(created hook内)
 allProducts ({commit}) { commit(ALL_PRODUCTS)  axios.get(`${API_BASE}/products`).then(response => {  commit(ALL_PRODUCTS_SUCCESS, response.data) }) },

 

5. mutations.js

export const productMutations = { // 每一个mutation都有一个success mutation, 它会在mutation完成后调用!
  // mutation只会抛出一个等待的pending state, 能够用于过渡的css
  // 而后success mutation更新UI,并关闭pending state。

  // showLoader 用于配合vue-toastr插件显示通知信息。
 [ALL_PRODUCTS] (state) { state.showLoader = true }, [ALL_PRODUCTS_SUCCESS] (state, payload) { state.showLoader = false state.products = payload },

 

 

各种知识点:

见博文  Vue.js简单的状态管理和 Vuex的几个核心概念使用。

 

因为状态零散地分布在许多组件和组件之间的交互中,大型应用复杂度也常常逐渐增加。

  • 若是多层组件嵌套使用,传递prop,和事件emit。都很不方便。
  • 不方便对数据的修改进行历史记录。影响后续的调试!

 

严格模式的表单处理:

参考以前的博客嵌套的JavaScript评论 Widget Models  (有一个替代的vue插件)


当在严格模式中使用 Vuex 时,在属于 Vuex 的 state 上使用 v-model 会比较棘手。

这是由于严格模式下,state的任何变化都须要经过mutation来改变。而v-model直接绑定data,因此会报错❌。

2种办法:

  • 不使用v-model,改用v-bind和v-on,而后使用action->mutation的顺序改变state
  • 仍是使用v-model,  使用带有setter 的双向绑定计算属性。
//template:

<input v-model="message">
//script
computed: { message: { get () {
return this.$store.state.obj.message }, set (value) { this.$store.commit('updateMessage', value) } } }

 


 

在组件中使用Store: 

包括

  1. A list of products (Home page)
  2. Product details (Details Page)
  3. Cart (Cart Page) + Cart count
  4. A table of products (Admin)
  5. form的edit
  6. A loading spinner

 

Products List, Item and Button

在/views/home.vue中

import ProductList from '../components/products/ProductList.vue'

 

编写ProductList.vue

编写product-item组件, 它用在ProductList.vue内。

编写product-button组件,它用在ProductItem.vue内

 

Product Details

建立一个产品详细描述的组件。Details.vue。它内部调用ProductDetails.vue

须要增长一个动态路径,来导航到产品详情页面。

//在routers.js的routes:内添加一个新的路径
{ path: '/details/:id', name: 'Details', component: Details }

 

 

由于cart.vue中也要用到ProductDetails.vue.

 


 

Admin Features(略)

Spinner, Cart & Strore Subscriptions(略)

相关文章
相关标签/搜索