Vue.js初学者课程7:计算属性

今天,在Vue课程的第七课中,我们将讨论计算属性。这些Vue实例属性不存储值,而是计算它们。









Vue.js初学者课程1:实例Vue

Vue.js初学者,课程2:绑定属性

Vue.js初学者课程3:条件渲染

Vue.js初学者课程4:列表渲染

Vue .js初学者课程5:事件处理

Vue.js初学者课程6:绑定类和样式

Vue.js初学者课程7:计算的属性

Vue.js初学者课程8:组件



本课目的



我们的主要目标是将由数据对象brand的属性描述的数据显示product为一行。



初始码



以下是我们将以index.html标记<body>开始代码



<div id="app">
  <div class="product">
    <div class="product-image">
      <img :src="image" />
    </div>

    <div class="product-info">
      <h1>{{ product }}</h1>
      <p v-if="inStock">In stock</p>
      <p v-else :class="{ outOfStock: !inStock }">Out of Stock</p>

      <ul>
        <li v-for="detail in details">{{ detail }}</li>
      </ul>
      <div
        class="color-box"
        v-for="variant in variants"
        :key="variant.variantId"
        :style="{ backgroundColor:variant.variantColor }"
        @mouseover="updateProduct(variant.variantImage)"
      ></div>

      <button
        v-on:click="addToCart"
        :disabled="!inStock"
        :class="{ disabledButton: !inStock }"
      >
        Add to cart
      </button>

      <div class="cart">
        <p>Cart({{ cart }})</p>
      </div>
    </div>
  </div>
</div>


这是代码main.js



var app = new Vue({
    el: '#app',
    data: {
        product: 'Socks',
        brand: 'Vue Mastery',
        image: './assets/vmSocks-green.jpg',
        inStock: true,
        details: ['80% cotton', '20% polyester', 'Gender-neutral'],
        variants: [
          {
            variantId: 2234,
            variantColor: 'green',
            variantImage: './assets/vmSocks-green.jpg'    
          },
          {
            variantId: 2235,
            variantColor: 'blue',
            variantImage: './assets/vmSocks-blue.jpg' 
          }
        ],
        cart: 0
    },
    methods: {
      addToCart() {
        this.cart += 1
      },
      updateProduct(variantImage) {
        this.image = variantImage
      }
    }
})


请注意,已将名为的新属性添加到数据对象brand



任务



我们要的是存储brandproduct组合成一条线。换句话说,我们需要在标记中显示<h1>文本Vue Mastery Socks,而不仅仅是Socks为了解决这个问题,您需要想知道如何串联一个Vue实例中存储的两个字符串值。



问题的解决



我们将使用计算属性来解决此问题。由于这些属性不存储值,而是计算值,因此我们将一个属性添加到实例化Vue时使用的options对象中,computed并创建一个名为的计算属性title



computed: {
  title() {
    return this.brand + ' ' + this.product;
  }
}


我们认为,一切安排都非常简单明了。调用该方法时title(),它将执行字符串连接brandproduct然后返回生成的新字符串。



现在,我们只需要title<h1>页面的标签中显示它即可



现在,该标签如下所示:



<h1>{{ product }}</h1>


现在我们将像这样:



<h1>{{ title }}</h1>


让我们看一下页面,检查一下我们刚才所做的功能。





页面标题已更改



如您所见,显示标题Vue Mastery Socks,这意味着我们做对了所有事情。



我们从Vue实例数据中获取了两个值,并基于它们创建了一个新值。例如,如果该值brand曾经更新过-将字符串写入此属性Vue Craftery,则无需对计算属性的代码进行任何更改。此属性将继续返回正确的字符串,现在看起来像Vue Craftery Socks计算的属性title将仍然brand像以前一样使用该属性,但是现在brand将写入新值。



这是一个非常简单的示例,但是在实践中非常适用。现在让我们看一下计算属性的更复杂的用法。



更复杂的例子



现在,我们使用来更新页面上显示的图像updateProduct我们传递给它variantImage,然后image将鼠标悬停在相应的彩色正方形上,然后将写入方法的内容写入属性相关代码如下:



updateProduct(variantImage) {
  this.image = variantImage;
}


这种机制很好用,但是如果我们不仅需要更改图像,还需要更改其他内容(基于鼠标悬停在哪个颜色方块上),则意味着需要重构此代码。让我们开始吧。



即,image我们将在属性中替换它,而不是在数据中存储属性selectedVariant我们将其初始化为0。



selectedVariant: 0,


为什么是0?关键是我们计划根据index鼠标悬停的元素的索引(设置此属性我们可以向构造添加一个索引v-for



<div
  class="color-box"
  v-for="(variant, index) in variants"
  :key="variant.variantId"
  :style="{ backgroundColor:variant.variantColor }"
  @mouseover="updateProduct(variant.variantImage)"
></div>


请注意,现在的构造v-for=«variant in variants»现在是代码v-for=»(variant, index) in variants»



现在,我们不要传递variant.variantImage,而是updateProduct传递给此方法index



@mouseover="updateProduct(index)"


现在,让我们进入方法的代码updateProduct这是我们获取索引的地方。并且,而不是写新值this.image,写入indexthis.selectedVariant即,与鼠标指针悬停在其上的正方形相对应selectedVariant值将落入index为了调试目的,我们还将放置一个命令将该值记录到此方法中index



updateProduct(index) {
  this.selectedVariant = index;
  console.log(index);
}


如果现在刷新页面并打开开发人员工具控制台,则可以确保将鼠标悬停在正方形上时,控制台中的值为0和1。





检查我们创建的机制的功能



但是,该图像不再显示在页面上。警告出现在控制台中。





控制台警告



重点是我们删除了该属性,image并用属性替换了它selectedValue,但是此属性仍在我们的应用程序中使用。让我们通过将其返回image到Vue实例来解决问题,但这一次是作为计算属性。相应的代码如下所示:



image() {
  return this.variants[this.selectedVariant].variantImage;
}


在这里,我们返回variantImage数组元素的属性this.variants[this.selectedVariant]。作为访问数组元素的索引,使用的属性this.selectedVariant等于0或1。这分别使我们可以访问第一个或第二个数组元素。



如果现在刷新页面,将显示图像并响应鼠标悬停在彩色正方形上。但是现在,该机制是使用计算属性实现的。



现在,我们已经重构了用于updateProduct更新属性状态的方法的代码selectedVariant,我们可以处理数组中对象中存储的其他数据variants,例如variantQuantity现在将添加到对象中的字段



variants: [
  {
    variantId: 2234,
    variantColor: 'green',
    variantImage: './assets/vmSocks-green.jpg',
    variantQuantity: 10
  },
  {
    variantId: 2235,
    variantColor: 'blue',
    variantImage: './assets/vmSocks-blue.jpg',
    variantQuantity: 0
  }
],


让我们摆脱普通属性inStock,就像使用属性一样image,创建一个具有相同名称的新计算属性,其返回值将基于selectedVariantvariantQuantity



inStock(){
  return this.variants[this.selectedVariant].variantQuantity
}


此属性与计算属性非常相似image但是现在我们从相应的对象中获取的不是一个属性variantImage,而是一个属性variantQuantity



如果现在将鼠标悬停在一个正方形上,则对应的商品数量等于0,inStock将落入0,并且0是JavaScript中的一个值,该值转换为boolean值false因此,页面上将显示一条消息Out of Stock



请注意,将按钮设置inStock为0之前,该按钮也可以正确反应





按钮和标签取决于每种产品的数量,



为什么一切都可以正常工作?关键是,inStock它仍然用于将类绑定disableButton到我们的按钮。该应用程序的新版本与其先前版本之间的唯一区别是,它现在inStock是一个计算属性,而不是常规属性。



了解有关计算属性的更多信息



计算的属性被缓存。即,将计算这些属性的结果存储在系统中,直到更改这些结果所依赖的数据为止。结果,当它更改时variantQuantity,缓存将被清除。和inStock访问它下一次,该属性将返回一个新的结果,将被放置在缓存中。



考虑到这一点,我们可以说,如果需要资源密集型计算来获得某个值,那么使用计算属性(而不是方法)执行计算会更有利可图。每当需要相应的值时,都必须调用该方法。



另外,请务必记住,不要在计算出的属性代码中更改存储在Vue实例中的数据。在此代码中,您要做的就是根据现有数据执行计算。这些功能应该干净并且没有副作用。



作坊



向用于创建Vue实例的数据对象添加一个新的boolean属性onSale它将指示是否正在进行销售。创建一个sale基于的计算属性brandproductonSale形成一条线,据报道,现在是否进行销售。在产品卡中输出此行。



这里是一个模板,你可以用它来解决这个问题



这里有一个对这个问题的解决方案



结果



在本课程中,我们学习了计算属性。以下是我们了解到的最重要的信息:



  • 计算属性计算值,而不存储它们。
  • 计算属性可以使用存储在应用程序中的数据来从中创建新数据。




如果您正在为这门课程做功课,请告诉我们您是否正在做专门为您提供的课程,或者您走的更远?



Vue.js初学者课程1:实例Vue

Vue.js初学者,课程2:绑定属性

Vue.js初学者课程3:条件渲染

Vue.js初学者课程4:列表渲染

Vue .js初学者课程5:事件处理

Vue.js初学者课程6:绑定类和样式

Vue.js初学者课程7:计算的属性

Vue.js初学者课程8:组件






All Articles