我是靠谱客的博主 潇洒裙子,最近开发中收集的这篇文章主要介绍Vue基础-Options API(computed和watch)-Vue基础综合练习 书籍购物车案例,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

文章目录

    • 计算属性computed
      • 1.认识计算属性
      • 2.案例实现
        • 实现思路一:模板语法
        • 实现思路二:method
        • 实现思路三:computed
      • 3.计算属性 VS methods
      • 4.计算属性的set和get
    • 监听器watch
      • 1.认识监听器watch
      • 2.watch的配置选项
      • 3.watch的其他方式(了解)
    • 综合案例

计算属性computed

1.认识计算属性

我们知道,在模板中可以直接通过插值语法显示一些data中的数据

但是在某些情况,我们可能需要对数据进行一些转化后再显示,或者需要将多个数据结合起来进行显示

  • 比如我们需要对多个data数据进行运算、三元运算符来决定结果、数据进行某种转化后显示;

  • 在模板中使用表达式,可以非常方便的实现,但是设计它们的初衷是用于简单的运算;

  • 在模板中放入太多的逻辑会让模板过重和难以维护;

  • 并且如果多个地方都使用到,那么会有大量重复的代码;

我们有没有什么方法可以将逻辑抽离出去呢?

  • 可以,其中一种方式就是将逻辑抽取到一个method中,放到methods的options中;

  • 但是,这种做法有一个直观的弊端,就是所有的data使用过程都会变成了一个方法的调用;

  • 另外一种方式就是使用计算属性computed

那么什么是计算属性呢?

  • 官方并没有给出直接的概念解释;

  • 而是说:对于任何包含响应式数据的复杂逻辑,你都应该使用计算属性;

  • 计算属性将被混入到组件实例中 , 所有 getter 和 setter 的 this 上下文自动地绑定为组件实例;

计算属性的用法

  • 选项:computed

  • 类型{ [key: string]: Function | { get: Function, set: Function } }

那接下来我们通过案例来理解一下这个计算属性。


2.案例实现

我们来看三个案例

案例一:我们有两个变量:firstName和lastName,希望它们拼接之后在界面上显示

案例二:我们有一个分数:score

  • 当score大于60的时候,在界面上显示及格;

  • score小于60的时候,在界面上显示不及格;

案例三:我们有一个变量message,记录一段文字:比如Hello World

  • 某些情况下我们是直接显示这段文字;

  • 某些情况下我们需要对这段文字进行反转;

我们可以有三种实现思路:

思路一:在模板语法中直接使用表达式;

思路二:使用method对逻辑进行抽取;

思路三:使用计算属性computed;

实现思路一:模板语法

思路一的实现:模板语法

  • 缺点一:模板中存在大量的复杂逻辑,不便于维护(模板中表达式的初衷是用于简单的计算);

  • 缺点二:当有多次一样的逻辑时,存在重复的代码;

  • 缺点三:多次使用的时候,很多运算也需要多次执行,没有缓存;

    {{ firstNmae}} {{ lastName }}

    {{ score >= 60? "及格": "不及格" }}

    {{ message.split(" ").reverse().join(" ") }}

实现思路二:method

思路二的实现:method实现

  • 缺点一:我们事实上想显示的是一个结果,但是结果都变成了一种方法的调用;

  • 缺点二:多次使用方法的时候,没有缓存,也需要多次计算;

    {{ getFullName() }}

    {{ getScoreLevel() }}

    {{ reverseMessage() }}

实现思路三:computed

思路三的实现:computed实现

  • 注意:计算属性看起来像是一个函数,但是我们在使用的时候不需要加(),这个后面讲setter和getter时会讲到;

  • 我们会发现无论是直观上,还是效果上计算属性都是更好的选择;

  • 并且计算属性是有缓存的;

    {{ fullName }}

    {{ scoreLevel }}

    {{ reverseMessage }}

3.计算属性 VS methods

在上面的实现思路中,我们会发现计算属性和methods的实现看起来是差别是不大的,而且我们多次提到计算属性有缓存的。

  • 接下来我们来看一下同一个计算多次使用,计算属性和methods的差异:

    const app = Vue.createApp({
    data() {
    return {
    firstNmae: “chen”,
    lastName: “yq”,
    };
    },
    // 1.定义methods方法
    methods: {
    getFullName() {
    console.log(“调用了methods的getFullName”);
    return this.firstNmae + " " + this.lastName;
    },
    },

    // 2.定义计算属性
    computed: {
    fullName() {
    console.log(“调用了computed的fullName”);
    return this.firstNmae + " " + this.lastName;
    },
    },
    });

    {{ getFullName() }}

    {{ getFullName() }}

    {{ getFullName() }}

    {{ getFullName() }}

    {{ fullName }}

    {{ fullName }}

    {{ fullName }}

    {{ fullName }}

打印的结果如下 ( 我们会发现methods调用了四次, 而computed只会调用一次 ):

在这里插入图片描述

这是什么原因呢?

  • 这是因为计算属性会基于它们的依赖关系进行缓存;

  • 在数据不发生变化时,计算属性是不需要重新计算的;

  • 但是如果依赖的数据发生变化,在使用时,计算属性依然会重新进行计算;

例如我们对上面代码在添加一个按钮, 要求点击按钮, 内容发生改变

<!-- 1.使用methods -->
<h2>{{ getFullName() }}</h2>
<h2>{{ getFullName() }}</h2>
<h2>{{ getFullName() }}</h2>
<h2>{{ getFullName() }}</h2>
<!-- 2.使用computed -->
<h2>{{ fullName }}</h2>
<h2>{{ fullName }}</h2>
<h2>{{ fullName }}</h2>
<h2>{{ fullName }}</h2>
<!-- 3.添加按钮点击改变信息 -->
<button @click="changeMessage">改变信息</button>

那么我们来看看点击按钮前后的打印效果:

  • 点击按钮改变前:

在这里插入图片描述

  • 点击按钮改变信息后:

在这里插入图片描述

  • 改变信息后计算属性会重新执行一次, 而methods又重新执行了四次
  • 由此可见, computed的性能是更高的

4.计算属性的set和get

其实上面的代码中, 我们使用的都是计算属性的简写方式

  • 计算属性有完整的写法, 只不过开发中很少会这样写
  • 下面给大家介绍一下计算属性的完整写法

完整写法中, 我们设置一个计算属性, 这个计算属性其实是一个对象

  • 对象中有两个方法, 一个是set, 一个是get

计算属性在大多数情况下,只需要一个getter方法即可,所以我们会将计算属性直接写成一个函数

  • 计算属性的完整写法

    computed: {
    fullName: {
    get() {
    return this.firstName + " " + this.lastName;
    },
    },
    }

  • 当我们只需要getter方法的时候, 我们可以直接写出一个函数, 也就是我们之前的写法

    computed: {
    fullName() {
    return this.firstName + " " + this.lastName;
    },
    }

但是,如果我们确实想设置或修改计算属性的值(了解), 基本不会使用set

  • 这个时候我们也可以给计算属性设置一个setter的方法;

    {{ fullName }}

监听器watch

1.认识监听器watch

什么是侦听器呢?

  • 开发中我们在data返回的对象中定义了数据,这个数据通过插值语法等方式绑定到template中;

  • 当数据变化时,template会自动进行更新来显示最新的数据;

  • 但是在某些情况下,我们希望在代码逻辑中监听某个数据的变化,这个时候就需要用侦听器watch来完成了;

侦听器的用法如下

  • 选项:watch

  • 类型:{[key: string]: string | Function | Object | Array}

演示代码, 例如监听message发生了改变

// watch监听器
watch: {
// 监听message的改变
message() {
console.log("message发生了改变");
},
}
  • 如果我们想要拿到message改变之前的信息呢

  • 其实默认是有两个参数的, 一个oldValue改变之前的数据, 一个是newValue改变之后的数据

    watch: {
    // 默认有两个参数
    message(newValue, oldValue) {
    console.log(“message改变前是:”, oldValue);
    console.log(“message改变后是:”, newValue);
    },
    }

  • 如果是对象类型, 参数获取到的是Proxy代理对象

    // 监听info对象
    info(newValue, oldValue) {
    // 如果是对象类型, 那么拿到的是代理对象
    console.log(“info数据发生了变化:”, newValue, oldValue);
    // 代理对象同样可以使用对象的属性
    console.log(newValue.name, oldValue.name);
    },

  • 我们也可以获取Proxy代理对象的原始对象

    // 监听info对象
    info(newValue, oldValue) {
    // 通过toRaw方法获取原始对象
    console.log(Vue.toRaw(newValue), Vue.toRaw(oldValue));
    },

2.watch的配置选项

我们先来看一个例子

  • 当我们点击按钮的时候会修改info.name的值;

  • 这个时候我们使用watch来侦听info,可以侦听到info.name的变化吗?答案是不可以。

    {{ info.name }}

这是因为默认情况下,watch只是在侦听info的引用变化,对于内部属性的变化是不会做出响应的

  • 这个时候我们可以使用一个选项deep进行更深层的侦听;

  • 注意前面我们说过watch里面侦听的属性对应的也可以是一个Object;

    watch: {
    // 进行更深层次的监听
    info: {
    // 回调函数放在handler中
    handler(newValue, oldValue) {
    console.log(“info内部数据发生了变化”);
    },
    // 添加deep选项, 开启深度监听
    deep: true,
    },
    },

还有另外一个属性,是希望一开始的就会立即执行一次

  • 这个时候我们使用immediate选项;

  • 这个时候无论后面数据是否有变化,侦听的函数都会有限执行一次;

    watch: {
    // 进行更深层次的监听
    info: {
    // 回调函数放在handler中
    handler(newValue, oldValue) {
    console.log(“info内部数据发生了变化”);
    },
    // 添加deep选项, 开启深度监听
    deep: true,
    // 添加immediate选项, 启动默认监听
    immediate: true,
    },
    },

3.watch的其他方式(了解)

另外一个是Vue3文档中没有提到的,但是Vue2文档中有提到的是侦听对象的属性

  • 例如刚刚监听info.name属性, 可以有如下写法:

    watch: {
    “info.name”: function (newValue, oldValue) {
    console.log(“info.name发生了改变”, newValue, oldValue);
    },
    },

还有另外一种方式就是使用 w a t c h 的 A P I :我们可以在 c r e a t e d 的生命周期(暂时了解 , 后续会讲到)中,使用 t h i s . watch 的API:我们可以在created的生命周期(暂时了解, 后续会讲到)中,使用 this. watchAPI:我们可以在created的生命周期(暂时了解,后续会讲到)中,使用this.watchs 来侦听

  • 第一个参数是要侦听的源;

  • 第二个参数是侦听的回调函数callback;

  • 第三个参数是额外的其他选项,比如deep、immediate;

    created() {
    this.$watch(“info”, (newValue, oldValue) => {
    console.log(“info内部数据发生了变化”);
    }, { deep: true, immediate: true})
    }

综合案例

我们已经学习了很多Vue的语法, 现在我们来做一个相对综合一点的练习:书籍购物车

在这里插入图片描述

案例需求

  • 在界面上以表格的形式,显示一些书籍的数据;
  • 点击+或者-可以增加或减少书籍数量(如果为1,那么不能继续-);
  • 点击移除按钮,可以将书籍移除(当所有的书籍移除完毕时,显示:您当前没有选择任何商品~~~);
  • 在底部显示书籍的总价格;
  • 点击某一行时, 某一行高亮

思路分析:

  • 购买数量不能为负数, 等于零的的时候将按钮禁用: :disabled="item.count === 0"
  • 购买数量的增加和减少, 在v-for里面需要确定点击的是哪一个书籍的增加/减少, 需要在点击事件里面去传递一个index作为参数, 用于确定增加目标
  • 移除同理: 需要确定具体的移除目标, 点击事件里传入index, 使用数组的方法splice(index, 1)进行移除
  • 总价: 使用计算属性计算总价格, 遍历数组拿到每一个对象, 让数量*价格, 最后然后总价格
  • 购物车为空时, 显式一行字, 用v-if 和 v-else, 判断books.lenght是否等于0
  • 点击某一处高亮, 把样式写在一个类中(例如active), 动态添加类 :class = "{active: index === currentIndex}"

示例源代码:

  • css源代码

  • html和js代码

    书籍名称出版日期价格购买数量操作

先自我介绍一下,小编13年上师交大毕业,曾经在小公司待过,去过华为OPPO等大厂,18年进入阿里,直到现在。深知大多数初中级java工程师,想要升技能,往往是需要自己摸索成长或是报班学习,但对于培训机构动则近万元的学费,着实压力不小。自己不成体系的自学效率很低又漫长,而且容易碰到天花板技术停止不前。因此我收集了一份《java开发全套学习资料》送给大家,初衷也很简单,就是希望帮助到想自学又不知道该从何学起的朋友,同时减轻大家的负担。添加下方名片,即可获取全套学习资料哦

最后

以上就是潇洒裙子为你收集整理的Vue基础-Options API(computed和watch)-Vue基础综合练习 书籍购物车案例的全部内容,希望文章能够帮你解决Vue基础-Options API(computed和watch)-Vue基础综合练习 书籍购物车案例所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(30)

评论列表共有 0 条评论

立即
投稿
返回
顶部