【精简你的Vue代码】用class封装替换Vue的methods

介绍

用 Vue 提供的 methods 来处理业务是我们从一开始学 Vue 的习惯做法,但是,这会产生一个弊端,就是当业务十分复杂时,methods 中的代码就会变得十分冗长,使得代码阅读性下降,调试和维护的难度也跟着加大。因此,我个人比较强烈推荐将业务从 Vue 的 methods 中分离出来集中管理的。接下来,我们用购物车为例来说明用 class 封装业务逻辑,去掉 methods 的具体做法。

new Vue实例:script.js

我们在 data 中创建购物车对象 cart 时,不是用 cart: { } 来初始化购物车,而是通过 cart : new ShoppingCar() 。在这里我们无需写任何 methods,但是对于一些计算属性,我们仍然要明确写出来,不过可以通过调用 cart 对象的方法来完成。

import Vue from 'https://dev.jspm.io/vue/dist/vue';
import {ShoppingCart} from './shoppingCart.j'

//some fake products
let products = [
  { id: "170001", name: "masks" , "price": 10},
  { id: "170002", name: "pears" , "price": 6},
  { id: "170003", name: "cakes" , "price": 40},
  { id: "170004", name: "bikes" , "price": 200},
]

/*
Important Here!!!
1. We create an empty shopping cart by using class ShoppingCart instead of passing a {}.
2. We still need to add the computed attrs, but that's bearable because we can compute them by calling methods from ShoppingCart 
*/
new Vue({
  el: "#app",
  data() {
    return {
      cart: new ShoppingCart(), //==>1
      products
    };
  },
  /*No methods are needed, as we are able to define them in ShoppingCart class*/
  computed: {
    count() {
      return this.cart.count(); //==>2
    },
    totalPrice() {
      return this.cart.totalPrice();
    }
  }
});

封装购物车业务 ShoppingCart.js

这里我们封装 cart 对象的所有业务逻辑(添加,删除,计算数量和总额等),本来写在 methods 中的代码,被我们搬到 ShoppingCart 集中管理,使得 script.js 中原本的 Vue 实例代码更加精简,也使得购物车的业务代码更加集中,容易维护。

import Vue from 'https://dev.jspm.io/vue/dist/vue';

export class ShoppingCart {
  
  list = {};//shopping cart content

  constructor() {
    //this.list = {}
  }
  
  //Add an item to the shopping cart
  add(item) {
    let exist = Object.keys(this.list).includes((item.id));
    if(exist) {
      this.list[item.id].count++;
    }else{
      Vue.set(this.list, item.id, {"id": item.id, "name": item.name, count: 1, price: item.price });
    }
  }

  //Remove an item from the shopping cart
  remove(item) {
    if(!this.list[item.id]) return;
   
    this.list[item.id].count--;

    if(this.list[item.id].count == 0) {
        delete this.list[item.id];
    }
  }

  //Count the total number of all items
  count() {
    let items = Object.values(this.list)
    let total = items.reduce((total, item )=> {
      return total += item.count;
    }, 0);
    return total;
  }

  //Count the total price of all items
  totalPrice() {
    let items = Object.values(this.list)
    let total = items.reduce((total, item )=> {
      return total += item.price * item.count;
    }, 0);
    return total;
  }
}

页面 index.html

在 html 或 template 中,我们的 click 事件调用的不是 methods 中的方法,而是 cart 对象的方法。


<html>
  <head>
    <link rel="stylesheet" href="lib/style.css">
  head>
  <body>
    <h1>My Shopping Carth1>
    <div id="app">
    <div v-for="(item, i) in products">
    	
      <button @click="cart.add(item)">add {{item.name}}button>
      <button @click="cart.remove(item)">remove {{item.name}}button>
    div>  
    Shopping Cart: {{count}} items, total price is {{totalPrice}}
      <table border="1" cellspacing="0" cellpadding="0">
        <tr>
          <th>idth><th>nameth><th>unit priceth>
          <th>countth><th>priceth>
        tr>
        <tr v-for="(item, i) in cart.list">
          <td>{{item.id}}td>
          <td>{{item.name}}td>
          <td>{{item.price}}td>
          <td>{{item.count}}td>
          <td>{{item.price * item.count}}td>
        tr>
      ul>
    div>
    
  body>
    <script type="module" src="lib/script.js">script>
html>

测试截图

以下是测试截图,有需要的可以下载 github 上的代码 shopping-cart-class
【精简你的Vue代码】用class封装替换Vue的methods_第1张图片

你可能感兴趣的:(Vue.js)