使用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(略)

相關文章
相關標籤/搜索