【vue3】04-vue基础语法补充及阶段案例

news2024/11/17 17:25:32

文章目录

  • vue基础语法补充
    • vue的computed
    • vue的watch侦听
  • 书籍购物车案例

vue基础语法补充

vue的computed

computed:用于声明要在组件实例上暴露的计算属性。(官方文档描述)

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

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

  • 比如我们需要对多个data数据进行运算、三元运算符来决定结果、数据进行某种转化后显示;
  • 在模板中使用表达式,可以非常方便的实现,但是设计它们的初衷是用于简单的运算;
  • 在模板中放入太多的逻辑会模板过重难以维护;

而且因为多个地方都使用到,所以会有大量重复的代码,那么我们可以将逻辑抽离出去:

  • 比如直接逻辑抽取到一个method中,放到methods的options中;
  • 但是,这种做法有一个直观的弊端,就是所有的data使用过程都会变成了一个方法的调用,所以正确的做法应该是抽离出来后放入计算属性computed中

用法示例:

    <div id="app">
        <h2>{{fullName}}</h2>

        <!-- 2.显示分数等级 -->
        <h2>{{getScorelevel}}</h2>

        <!-- 3.反转单词显示文本 -->
        <h2>{{reverseMessage}}</h2>
    </div>
    <script>

        const app = Vue.createApp({
            data() {
                return {
                    // 1.姓名
                    firstName: "kobe",
                    lastName: "byrant",
                    // 2.分数及不及格
                    score: 65,
                    // 3.一串文本:对文本中的单词进行反转显示
                    message: "my name is sevgilid"

                }
            },
            methods: {

            },

            computed: {
                // 计算属性对应的是一个函数(经过响应式复杂逻辑转化的都应写在computed里)
                // 计算属性是有缓存的
                fullName() {
                    return this.firstName + "" + this.lastName
                },

                getScorelevel() {
                    return this.score > 60 ? '及格' : '不及格'
                },

                reverseMessage() {
                    return this.message.split("").reverse().join("")
                }

            }
        })
        app.mount('#app')
    </script>

vue的watch侦听

watch:用于声明在数据更改时调用的侦听回调。(官方文档描述

什么是侦听器呢?

  • 开发中我们在data返回的对象中定义了数据,这个数据通过插值语法等方式绑定到template中;
  • 当数据变化时,template会自动进行更新来显示最新的数据;
  • 但是在某些情况下,我们希望在代码逻辑中监听某个数据的变化,这个时候就需要用侦听器watch来完成了;

用法:{ [key: string]: string | Function [ Object | Array}

如下示例:

点击按钮后message就会修改,且控制台打印’‘message发生了改变’’

    <div id="app">
        <h2>{{message}}</h2>
        <button @click="changeMessage">修改message</button>
    </div>
    <script>

        const app = Vue.createApp({
            data() {
                return {
                    message: 'hello vue'
                }
            },
            methods: {
                changeMessage() {
                    this.message = "你好啊,李二狗"
                }
            },
            watch: {
                message() {
                    console.log("message发生了改变");
                }
            }
        })
        app.mount('#app')
    </script>

通过以上例子发现其实就是想监听谁在里面写谁,但这样使用的话只知道数据发生了改变,并不知道改变是什么。

  1. 其实回调函数里默认是有传过来两个参数的:分别是newvalue,oldvalue,像下面这样修改代码后就可以看到前后数据发生的改变:
    watch: {
        message(newValue,oldValue) {
        console.log("message已发生改变", newValue, oldValue);
      }

打印结果:

在这里插入图片描述

  1. 如果是监听的是一个对象类型,那么拿到的是代理对象,可以通过newValue.name这样去拿值
 <div id="app">
        <h2>{{info}}</h2>
        <button @click="changeInfo">改变info</button>
    </div>
    <script>

        const app = Vue.createApp({
            data() {
                return {
                    info:{name:"daa",age:15}
                }
            },
            methods: {
                changeInfo(){
                    this.info={name:"kkk",age:25}
                }
            },
            watch: {
                info(newValue,oldValue){
                    console.log("info数据发生了变化", newValue,oldValue);
                    console.log(newValue.name,oldValue.name);![在这里插入图片描述](https://img-blog.csdnimg.cn/9a9764dc762549caa4d9e4905b6336ea.png)

                }
            }
        })
        app.mount('#app')
    </script>

控制台打印结果:

在这里插入图片描述

  • 如果想拿到原生对象:Vue.toRaw(newValue)在这里插入图片描述
  1. watch的侦听选项配置:
  • deep:true:为true时进行深度监听
  • immediate:true:为true时第一次渲染直接执行一次监听器

其实默认是不进行深度监听的,像下面的例子:

  • 如果修改的是整个info是可以监听到的
  • 但是只修改info对象中的一个属性是监听不到
 <script>

        const app = Vue.createApp({
            data() {
                return {
                    info: {name:"kkk", age:25}
                }
            },

            methods:{
                changeInfo(){
                    // 1.修改原对象,可以监听
                    // this.info = {name:"wxx", age:52}

                    // 2.直接修改原对象的一个属性
                    this.info.name = "sevgilid"
                }
            },

            watch:{
                // 默认watch监听不会进行深度监听(所以只改变属性时未监听到)
                // info(newValue,oldValue){
                //     console.log("info数据发生了改变", newValue,oldValue);
                // }

                // 进行深度监听
                info:{
                    handler(newValue,oldValue){
                        console.log("info一发生改变",newValue, oldValue);
                    },
                    // 监听器选项:
                    //info进行深度监听:加上以下配置后即可监听到属性改变
                    deep:true,
                    // 第一次渲染直接执行一次监听器
                    immediate:true
                }

            
            }
        })
        app.mount('#app')
    </script>

书籍购物车案例

一个相对综合的案例,可以对前面几篇博客知识进行练习(完整代码在文末

在这里插入图片描述

案例说明:
1.在界面上以表格的形式,显示一些书籍的数据;
2.在底部显示书籍的总价格;
3.点击+或者-可以增加或减少书籍数量(如果为1,那么不能继续-);
4.点击移除按钮,可以将书籍移除(当所有的书籍移除完毕时,显示:购物车为空);
5.点击行变色

案例步骤:
1.搭建界面内容:做出表格,调整基本样式
2.获取数据:可以从后台拿数据,这里选择自己在data中模拟数据
3.分析实现逻辑:

  • 使用v-for遍历数据配合插值语法实现界面的动态填充
  • 为按钮绑定methods中的方法,使用v-if判断为1时不能继续
  • 在computed计算属性中实现对价格及数量的逻辑抽取
  • 使用split方法移出
  • 为点击行动态绑定active样式

步骤代码详解:

遍历数据及加减:

在这里插入图片描述
在这里插入图片描述

注意事项:

  1. 遍历时外层使用template包裹
  2. v-for就要写key(自己写的时候忘记了)
  3. 因为绑定按钮的时候是动态绑定:所以点击事件的时候要传入参数,即拿到索引才能知道你点击的是哪一个按钮)
  4. 小于1不可再点击-1按钮时应:disabled={item<=1}

总价响应式:

在这里插入图片描述

注意事项:

  1. 抽取后写入computed计算属性,而非放入methods中进行方法的调用
  2. 遍历时内部不要忘记加上const

移出操作:

在这里插入图片描述
注意事项:

  1. 绑定事件时传递index参数来判断移出的是第几行
  2. slice()的使用

行变色:

  1. 通过点击获取索引index来判断点击的第几行
  2. 在data中定义currentIndex
  3. 点击事件中将获取到的index赋值给currentIndex
  4. tr动态绑定active时使用对象语法,通过判断index === currentIndex的布尔值来动态绑定

案例完整代码:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="../Vue3.js"></script>
    <style>
        table {
            border-collapse: collapse;
            color: brown;
            text-align: center;
        }

        table,
        th,
        td {
            border: 1px solid black;
        }

        .active {
            background-color: aqua;
        }
    </style>

</head>

<body>
    <div id="app">
        <div class="shopCurt">
            <table>
                <thead>
                    <tr>
                        <th>序号</th>
                        <th>商品名字</th>
                        <th>价格</th>
                        <th>数量</th>
                        <th>商品描述</th>
                        <th>操作</th>
                    </tr>
                </thead>

                <tbody>
                    <template v-for="( item,index ) in infos">
                        <tr :class="{active:index === currentIndex}" @click="rowClick(index)">
                            <td>{{ index+1 }}</td>
                            <td>{{ item.name }}</td>
                            <td>{{ item.price }}</td>
                            <td><button @click="decrement(index)" :disabled="item.count<=1">-1</button>{{ item.count }}
                                <button @click="increment(index)">+1</button>
                            </td>
                            <td>{{ item.dec }}</td>
                            <td><button @click="removeBook(index)">{{ item.caozuo }}</button></td>
                        </tr>
                    </template>


                </tbody>
            </table>
        </div>
        <h2>AllPrice:{{ allPrice }}</h2>
    </div>
</body>


<script src="./Vue3.js"></script>
<script>
    const app = Vue.createApp({

        data() {
            return {
                currentIndex: -1,

                infos: [
                    { sort: 0, name: "华为电脑", price: 9.9, count: 1, dec: "9.9秒杀快来抢购", caozuo: "移除" },
                    { sort: 0, name: "iphoneX", price: 12.8, count: 1, dec: "苹果X最新出炉", caozuo: "移除" },
                    { sort: 0, name: "小米11Plus", price: 13.1, count: 1, dec: "速度来抢", caozuo: "移除" },
                    { sort: 0, name: "外星人电脑", price: 56, count: 1, dec: "真的便宜", caozuo: "移除" },
                    { sort: 0, name: "OPPOR11", price: 100, count: 1, dec: "好用不贵", caozuo: "移除" }
                ]
            }
        },
        computed: {
            allPrice() {
                let price = 0;
                for (const item of this.infos) {
                    price += item.price * item.count
                }
                return price
            }

        },
        methods: {
            // 监听加减按钮
            increment(index) {
                this.infos[index].count++
            },
            decrement(index) {
                this.infos[index].count--
            },
            // 监听行点击变色
            rowClick(index) {
                this.currentIndex = index;
            },
            // 移出操作
            removeBook(index) {
                this.infos.splice(index, 1)
            }
        }
    })
    app.mount('#app')
</script>

</html>

实现效果:

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/419638.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

科学的演变:从笛卡尔到生成式人工智能

编者按&#xff1a;本文主要介绍了科学的演变历史&#xff0c;从笛卡尔到生成式人工智能。文章探讨了数学在验证科学原理中的作用&#xff0c;并介绍了新机器学习工具如何验证新的科学。 文中提到&#xff0c;将生成式人工智能与Excel或iPhone进行比较是低估了这一新技术的潜在…

【AI】PaddlePaddle实现自动语音识别

文章目录文档背景安装环境Python版本pip环境安装模型需要的环境项目目录结构数据准备生成数据字典数据预处理训练模型创建模型构建模型的目的模型黑盒在模型中充当什么角色解码方法总结文档背景 学习AI的过程中&#xff0c;难免会出现各种各样的问题。比如&#xff0c;什么样的…

制造业生产管理系统(500强制造企业数字化实践)

前言 制造业是国民经济的支柱产业之一&#xff0c;随着科技和数字化的发展&#xff0c;制造业正在经历着一场新的变革。传统的制造模式已经无法满足市场的快速变化和客户的多样化需求&#xff0c;制造企业急需通过数字化和智能化转型升级&#xff0c;提高生产效率和质量水平&a…

第十四届蓝桥杯嵌入式详解

目录 第一部分 客观试题&#xff08;15 分&#xff09; 不定项选择&#xff08;1.5 分/题&#xff09; 第二部分 程序设计试题&#xff08;85 分&#xff09; 2.1 STM32CubeMX初始化配置 2.1.1 配置GPIO 2.1.2 配置ADC 2.1.3 配置RCC 2.1.4 配置定时器TIM 2.1.5 配置ADC1、AD…

【从零开始学Skynet】基础篇(二):了解Skynet

1、节点和服务 在下图所示的服务端系统中&#xff0c;每个Skynet进程&#xff08;操作系统进程&#xff09;都称为一个节点&#xff0c;每个节点都可以开启数千个Lua服务&#xff0c;每个服务都是一个Actor。不同节点可以部署在不同的物理机上&#xff0c;提供分布式集群的能力…

Velocity入门到精通(上篇)

最近自己所做的项目使用到这个Velocity模板引擎&#xff0c;分享一下在互联网找的学习资料。 目录 一. velocity简介 1. velocity简介 2. 应用场景 3. velocity 组成结构 二. 快速入门 1. 需求分析 2. 步骤分析 3. 代码实现 3.1 创建maven工程 3.2 引入坐标 3.3 编…

Redis锁的租约问题

目录Redis的租约问题Redis租约问题的想法Redis租约问题的解决方案Redis的租约问题 首先我们先来说一说什么是Redis的租约问题。   在我们实现Redis分布式锁的时候&#xff0c;我们会出现Redis锁的时间<业务执行执行时间&#xff0c;这其实就是一个典型的租约问题&#xf…

【C++】你了解命名空间吗?

C语言之父&#xff1a;Bjarne Stroustrup博士(本贾尼) 当我们在编写代码的时候&#xff0c;可能会产生一些命名冲突&#xff0c;为了解决这一冲突我们引出命名空间的概念 (ps:命名冲突的产生主要包括两个方面原因&#xff1a;1、与库函数名冲突&#xff1b;2、相互之间的冲突&…

【LeetCode】剑指 Offer 51. 数组中的逆序对 p249 -- Java Version

题目链接&#xff1a;https://leetcode.cn/problems/shu-zu-zhong-de-ni-xu-dui-lcof/ 1. 题目介绍&#xff08;51. 数组中的逆序对&#xff09; 在数组中的两个数字&#xff0c;如果前面一个数字大于后面的数字&#xff0c;则这两个数字组成一个逆序对。输入一个数组&#xf…

python3 DataFrame一些好玩且高效的操作

pandas在处理Excel/DBs中读取出来&#xff0c;处理为DataFrame格式的数据时&#xff0c;处理方式和性能上有很大差异&#xff0c;下面是一些高效&#xff0c;方便处理数据的方法。 map/apply/applymaptransformagg遍历求和/求平均shift/diff透视表切片&#xff0c;索引&#x…

VS Code 将推出更多 AI 功能给 Java 开发者

大家好&#xff0c;欢迎来到我们的二月更新&#xff01;我们将为您带来与 JUnit 5 并行测试相关的新功能以及用于 Spring Boot Dashboard 的过滤功能。另外&#xff0c;OpenAI 和 ChatGPT 是最近的热点&#xff0c;所以在 GitHub Copilot 方面也有一些令人激动的消息&#xff0…

【郭东白架构课 模块二:创造价值】19|节点二:架构活动的目标为什么常常被忽略?

你好&#xff0c;我是郭东白。从这节课开始&#xff0c;我们就进入到架构活动第二个环节的学习&#xff0c;那就是目标确认。 为架构活动确认一个正确目标&#xff0c;是架构师能为架构活动做出最大贡献的环节。从我的个人经验来看&#xff0c;一大半架构活动的目标都不具备正…

类文件具有错误的版本 55.0, 应为 52.0

最近在编译时报如下错误 java: 无法访问com.xx错误的类文件: /xxx.jar!/aa.class类文件具有错误的版本 55.0, 应为 52.0请删除该文件或确保该文件位于正确的类路径子目录中。 原来我依赖的jar包的编译版本是jdk11,而我本地代码编译的版本的jdk1.8,两个版本不一致&#xff0c;所…

C++类和对象终章——友元函数 | 友元类 | 内部类 | 匿名对象 | 关于拷贝对象时一些编译器优化

文章目录&#x1f490;专栏导读&#x1f490;文章导读&#x1f337;友元&#x1f33a;概念&#x1f33a;友元函数&#x1f341;友元函数的重要性质&#x1f33a;友元类&#x1f341;友元类的重要性质&#x1f337;内部类&#xff08;不常用&#xff09;&#x1f33a;内部类的性…

Ubuntu 下载并切换Python默认版本(无痛顺畅版)

Ubuntu 下载并切换Python默认版本的方法 文章目录Ubuntu 下载并切换Python默认版本的方法一&#xff0c;前言二&#xff0c;在ubantu中下载指定python版本1&#xff0c;更新apt版本为最新2&#xff0c;安装software-properties-common3&#xff0c;将 deadsnakes PPA 添加到你的…

并发 并行 进程 线程

并发 并行 进程 线程 进程和线程介绍 程序、进程和线程的关系示意图 并发和并行 1)多线程程序在单核上运行&#xff0c;就是并发 2)多线程程序在多核上运行&#xff0c;就是并行 示意图: 小结

大模型时代的“Linux”生态,开启人工智能新十年

演讲 | 林咏华 智源人工智能研究院副院长 整理 | 何苗出品 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09;2018 年以来&#xff0c;超大规模预训练模型的出现推动了 AI 科研范式从面向特定应用场景、训练专有模型&#xff0c;转变为大模型微调模型服务的AI工业化开…

016 - 如何写一个 C++ 类

到目前为止&#xff0c;我们学了类 class&#xff0c;本期我们要尝试着从头开始写一个类。 本期不会讲的太深。我们不会写非常复杂的类&#xff0c;我们要会完成一个基本的 log 类&#xff0c;来演示一下我们已经学过的相关知识。 接下来的几期&#xff0c;我们会继续学习类。…

银行数字化转型导师坚鹏:《银行业金融机构数据治理指引》

《银行业金融机构数据治理指引》 ——“监”听则明 护航银行高质量发展课程背景&#xff1a; 很多金融机构存在以下问题&#xff1a; 不清楚《银行业金融机构数据治理指引》出台背景&#xff1f; 不知道如何理解《银行业金融机构数据治理指引》相关规定&#xff1f; 不清楚…

重生之我是孔乙己——查找数组缺失元素的几种方法

&#x1f48c; 博客内容&#xff1a;查找缺失元素 &#x1f600; 作  者&#xff1a;陈大大陈 &#x1f680; 个人简介&#xff1a;一个正在努力学技术的准前端&#xff0c;专注基础和实战分享 &#xff0c;欢迎私信&#xff01; &#x1f496; 欢迎大家&#xff1a;这里是…