Vue学习(三)

news2025/1/18 12:01:11

一、列表渲染

v-for指令

  • 用于展示列表数据

  • 语法<li v-for="(item, index) in items" :key="index"></li>key可以是index,最好是遍历对象的唯一标识

  • 可遍历:数组、对象

<!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>列表渲染-基本列表</title>
    <script src="./js/vue.js"></script>
</head>
<body>
    <div id="root">
        <h3>人员列表(遍历数组)</h3>
        <ul>
            <li v-for="(p, index) in persons" :key="index">{{p.name}}--{{index}}</li>
        </ul>
        <h3>遍历字符串</h3>
        <ul>
            <li v-for="(char, index) in str" :key="index">{{char}}--{{index}}</li>
        </ul>
        <h3>遍历指定次数</h3>
        <ul>
            <li v-for="(num, index) in 5" :key="index">{{num}}--{{index}}</li>
        </ul>

        <h3>遍历对象</h3>
        <ul>
            <li v-for="(car, index) in cars" :key="index">{{car}}--{{index}}</li>
        </ul>
    </div>
    <script>
        Vue.config.productionTip = false;
        new Vue({
            el: "#root",
            // 函数形式的data
            data() {
                return {
                    persons: [
                        { id: "001", name: "张三", age: 18 },
                        { id: "002", name: "李四", age: 20 },
                        { id: "003", name: "王五", age: 19 },
                    ],
                    str:"hanzhe",
                    cars:[
                        {name:"保时捷",rice:198},
                        {name:"宝马",rice:208}
                    ]
                }
            }
        })
    </script>
</body>
</html>

 

二、列表渲染中key的作用

<!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>列表渲染-基本列表</title>
    <script src="./js/vue.js"></script>
</head>
<body>
    <div id="root">
        <h3>遍历对象</h3>
        <button @click="addCar">添加一个汽车</button>
        <ul>
            <!-- :key用作固定值 -->
            <li v-for="(car, index) in cars" :key="1">{{car.name}}--{{car.rice}} <input type="text"></li> 
        </ul>
    </div>
    <script>
        Vue.config.productionTip = false;
        new Vue({
            el: "#root",
            // 函数形式的data
            data() {
                return {
                    cars: [
                        { name: "保时捷", rice: 198 },
                        { name: "宝马", rice: 208 }
                    ]
                }
            },
            methods: {
                addCar(){
                    // 在后面加个数据没问题
                    // this.cars.push({ name: "宝马1", rice: 203 })
                    this.cars.unshift({ name: "宝马1", rice: 203 })
                }
            },
        })
    </script>
</body>
</html>

 key用固定值后,看一个现象看一个现象

点击添加按钮后:

分析:

面试题:react、vue中key有什么作用?

  • 虚拟DOM中key的作用:key是虚拟DOM中对象的标识,但数据发生变化时,vue会根据新的数据生成新的虚拟DOM,随后Vue进行新虚拟DOM与旧的DOM的差异进行比较,比较规则如下

  • 对比规则

  • 旧虚拟DOM中找到了新虚拟DOM相同的key

    • 若虚拟DOM中内容没变,直接使用之前的真实DOM

    • 若虚拟DOM内容改变了,则生成新的真实DOM,随后替换页面中之前的真实DOM

  • 旧虚拟DOM中未找到与新虚拟DOM相同的key

    创建新的真实DOM,随后渲染到页面上

  • 用index作为key可能会引发的问题

  • 若对数据进行逆序添加,删除等破坏顺序的操作,会产生没必要真实DOM更新,界面效果没问题,但是效率低下

  • 若结构中还包含输入类的DOM,会产生错误DOM更新,界面有问题

  • 开发中如何选择Key?

    最好每条数据的唯一标识作为key

    如果仅仅是在页面渲染,使用index作为key完全没问题。

三、列表过滤

分别使用计算属性和监听实现:

<!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>列表渲染-基本列表</title>
    <script src="./js/vue.js"></script>
</head>

<body>
    <div id="root">
        <h3>遍历对象</h3>
        <input type="text" placeholder="请输入名字" v-model="keyWord">
        <ul>
            <li v-for="(car, index) in filterCars" :key="index">{{car.name}}--{{car.rice}}</li>
        </ul>
    </div>

    <script>
        Vue.config.productionTip = false;
        new Vue({
            el: "#root",
            // 函数形式的data
            data() {
                return {
                    keyWord: '',
                    cars: [
                        { name: "保时捷", rice: 198 },
                        { name: "宝马", rice: 208 }
                    ],
                    filterCars: []
                }
            },
            // 使用计算属性
            // computed: {
            //     filterCars: {
            //         get() {
            //             return this.cars.filter((p) => {
            //                 // 过滤空格
            //                 return p.name.indexOf(this.keyWord) !== -1;
            //             })
            //         },
            //         set(value) {
            //             alert(value)
            //         }
            //     }
            // }

            // 使用监听属性
            // 需要在data中添加 filterCars:[]

            watch: {
                keyWord: {
                    immediate:true,
                    handler(newValue) {
                        this.filterCars = this.cars.filter((p) => {
                            return p.name.indexOf(this.keyWord) !== -1;
                        })
                    }
                }
            }
        })
    </script>
</body>

</html>

四、列表排序

<!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>列表渲染-基本列表</title>
    <script src="./js/vue.js"></script>
</head>

<body>
    <div id="root">
        <h3>遍历对象</h3>
        <input type="text" placeholder="请输入名字" v-model="keyWord">
        <button v-on:click="btn1">价格降序</button>
        <button @click="btn2">价格升序</button>
        <button @click="btn3">原来降序</button>
        <ul>
            <li v-for="(car, index) in filterCars" :key="index">{{car.name}}--{{car.rice}}</li>
        </ul>
    </div>

    <script>
        Vue.config.productionTip = false;
        new Vue({
            el: "#root",
            // 函数形式的data
            data() {
                return {
                    keyWord: '',
                    sortType: 0,
                    cars: [
                        { name: "保时捷", rice: 198 },
                        { name: "保马", rice: 208 },
                        { name: "保马2", rice: 309 },
                        { name: "雷克萨斯", rice: 500 }
                    ],
                    filterCars: []
                }
            },
            methods: {
                btn1(event) {
                    this.sortType = 2
                },

                btn2() {
                    this.sortType = 1
                },

                btn3() {
                    this.sortType = 0
                }
            },
            // 使用监听属性
            // 需要在data中添加 filterCars:[]
            watch: {
                keyWord: {
                    immediate: true,
                    handler(newValue) {
                        const arr = this.cars.filter((p) => {
                            return p.name.indexOf(this.keyWord) !== -1;
                        })

                        // 非 0 即true
                        if (this.sortType) {
                            arr.sort((p1, p2) => {
                                return this.sortType == 1 ? p2.rice - p1.rice : p1.rice - p2.rice
                            })
                        }
                        // 将排序后的数据赋值
                        this.filterCars = arr;
                    }
                }
            }
        })
    </script>
</body>
</html>

五、数据监视

data属性是对象时,修改对象可能不能触发MVVM的变化:

<!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>列表渲染-基本列表</title>
    <script src="./js/vue.js"></script>
</head>

<body>
    <div id="root">
        <h3>遍历对象</h3>
        <button v-on:click="updatebmw2">修改宝马2的数据</button>
        <ul>
            <li v-for="(car, index) in cars" :key="index">{{car.name}}--{{car.rice}}</li>
        </ul>
    </div>

    <script>
        Vue.config.productionTip = false;
        new Vue({
            el: "#root",
            // 函数形式的data
            data() {
                return {
                    cars: [
                        { name: "保时捷", rice: 198 },
                        { name: "保马", rice: 208 },
                        { name: "保马2", rice: 309 },
                        { name: "雷克萨斯", rice: 500 }

                    ]
                }
            },
            methods: {
                updatebmw2() {
                    // 将数组中存下标2开始,删除一个,并添加后面的数据
                    // 数组改变了,能触发mvvm模型的变化
                    // this.cars.splice(2,1,{ name: "保马2", rice: 109 }) 


                    // 数据虽然变化了,但是没有触发data上数据的变化
                    // this.cars[2] = { name: "保马2", rice: 109 }

                    // 生效的
                    this.cars[2].name = "名称修改了";
                    console.log(JSON.stringify(this.cars))
                }
            },
            // 使用监听属性
            // 需要在data中添加 filterCars:[]
            watch: {
                keyWord: {
                    immediate: true,
                    handler(newValue) {
                        const arr = this.cars.filter((p) => {
                            return p.name.indexOf(this.keyWord) !== -1;
                        })
                        // 将排序后的数据赋值
                        this.filterCars = arr;
                    }
                }
            }
        })
    </script>
</body>

</html>

模拟一个数据监视:

let data = {
  name: '尚硅谷',
  address: '北京',
}

function Observer(obj) {
  // 汇总对象中所有的属性形成一个数组
  const keys = Object.keys(obj)
  // 遍历
  keys.forEach((k) => {
    Object.defineProperty(this, k, {
      get() {
        return obj[k]
      },
      set(val) {
        console.log(`${k}被改了,我要去解析模板,生成虚拟DOM.....我要开始忙了`)
        obj[k] = val
      }
    })
  })
}

// 创建一个监视的实例对象,用于监视data中属性的变化
const obs = new Observer(data)
console.log(obs)

// 准备一个vm实例对象
let vm = {}
vm._data = data = obs

原理:

  • vue会监视data中所有层次的数据

  • 如何监测对象中的数据?

  • 通过setter实现监视,且要在new Vue()时传入要检测的数据

    • 兑现创建后追加的属性vue默认不做响应式处理

    • 如果需要给后添加的属性做响应式,使用如下API
      Vue.set(target,propertyName/index,value)
      vm.$set(target,propertyName/index,value)

  • 如何检测数组中的数据
    通过包裹数组新元素的方法实现,本质做了两件事
    调用原生对应的方法对数组进行更新
    重新解析模板,进而更新页面

  • 在vue修改数组的某个元素时,用如下方法
    push,pop,unshift,shift,splice,sort,reverse这几个方法被Vue重写了
    特别注意:vue.set()和vm.$set()不能给vm或vm的根对象(data)添加属性

<title>总结数据监视</title>
<style>button {margin-top: 10px;}</style>
<script type="text/javascript" src="../js/vue.js"></script>

<div id="root">
  <h1>学生信息</h1>
  <button @click="student.age++">年龄+1岁</button> <br />
  <button @click="addSex">添加性别属性,默认值:男</button> <br />
  <button @click="student.sex = '未知' ">修改性别</button> <br />
  <button @click="addFriend">在列表首位添加一个朋友</button> <br />
  <button @click="updateFirstFriendName">修改第一个朋友的名字为:张三</button> <br />
  <button @click="addHobby">添加一个爱好</button> <br />
  <button @click="updateHobby">修改第一个爱好为:开车</button> <br />
  <button @click="removeSmoke">过滤掉爱好中的抽烟</button> <br />
  <h3>姓名:{{ student.name }}</h3>
  <h3>年龄:{{ student.age }}</h3>
  <h3 v-if="student.sex">性别:{{student.sex}}</h3>
  <h3>爱好:</h3>
  <ul>
    <li v-for="(h,index) in student.hobby" :key="index">{{ h }} </li>
  </ul>
  <h3>朋友们:</h3>
  <ul>
    <li v-for="(f,index) in student.friends" :key="index">{{ f.name }}--{{ f.age }}</li>
  </ul>
</div>

<script type="text/javascript">
  Vue.config.productionTip = false

  const vm = new Vue({
    el: '#root',
    data: {
      student: {
        name: 'tom',
        age: 18,
        hobby: ['抽烟', '喝酒', '烫头'],
        friends: [
          { name: 'jerry', age: 35 },
          { name: 'tony', age: 36 }
        ]
      }
    },
    methods: {
      addSex() {
        // Vue.set(this.student,'sex','男')
        this.$set(this.student, 'sex', '男')
      },
      addFriend() {
        this.student.friends.unshift({ name: 'jack', age: 70 })
      },
      updateFirstFriendName() {
        this.student.friends[0].name = '张三'
      },
      addHobby() {
        this.student.hobby.push('学习')
      },
      updateHobby() {
        // this.student.hobby.splice(0,1,'开车')
        // Vue.set(this.student.hobby,0,'开车')
        this.$set(this.student.hobby, 0, '开车')
      },
      removeSmoke() {
        this.student.hobby = this.student.hobby.filter((h) => {
          return h !== '抽烟'
        })
      }
    }
  })

 

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

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

相关文章

探究Vue3中的Composition API:优化组件逻辑的新利器

一、toRef函数 在 Vue 3.0 中&#xff0c;引入了一种新的响应式 API,即 toRef。toRef 函数可以将一个普通值转换为响应式引用类型&#xff0c;这样就可以在模板中直接使用这个响应式引用类型的属性&#xff0c;并且当该属性发生变化时&#xff0c;视图会自动更新。 <templat…

【C++代码】用栈实现队列,用队列实现栈--代码随想录

队列是先进先出&#xff0c;栈是先进后出。卡哥给了关于C方向关于栈和队列的4个问题&#xff1a; C中stack 是容器么&#xff1f; 使用的stack是属于哪个版本的STL&#xff1f; 使用的STL中stack是如何实现的&#xff1f; stack 提供迭代器来遍历stack空间么&#xff1f; …

测试开发【Mock平台】09开发:项目管理(五)搜索、删除和Table优化

【Mock平台】为系列测试开发教程&#xff0c;从0到1编码带你一步步使用Spring Boot 和 Antd React框架完成搭建一个测试工具平台&#xff0c;希望作为一个实战项目对各位的测试开发学习之路有帮助&#xff0c;大奇一个专注测试技术干货原创与分享的家伙。 Mock平台系统项目基本…

【大数据实训】基于Hive的北京市天气系统分析报告(二)

博主介绍&#xff1a;✌全网粉丝6W,csdn特邀作者、博客专家、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于大数据技术领域和毕业项目实战✌ &#x1f345;文末获取项目联系&#x1f345; 目录 1. 引言 1.1 项目背景 1 1.2 项目意义 1 2.…

蓝队追踪者工具TrackAttacker,以及免杀马生成工具

蓝队追踪者工具TrackAttacker&#xff0c;以及免杀马生成工具。 做过防守的都知道大HW时的攻击IP量&#xff0c;那么对于这些攻击IP若一个个去溯源则显得效率低下&#xff0c;如果有个工具可以对这些IP做批量初筛是不是更好&#xff1f; 0x2 TrackAttacker获取 https://githu…

[管理与领导-67]:IT基层管理者 - 辅助技能 - 4- 职业发展规划 - 评估你与公司的八字是否相合

目录 前言&#xff1a; 一、概述 二、八字相合的步骤 2.1 企业文化是否相合 2.2.1 企业文化对职业选择的意义 2.2.2 个人与企业三观不合的结果 2.2.3 什么样的企业文化的公司不能加入 2.2 公司的发展前景 2.3 公司所处行业发展 2.4 创始人的三观 2.5 创始人与上司的…

HDMI 输出实验

FPGA教程学习 第十四章 HDMI 输出实验 文章目录 FPGA教程学习前言实验原理实验过程程序设计时钟模块&#xff08;video_pll&#xff09;彩条产生模块&#xff08;color_bar)配置数据查找表模块&#xff08;lut_adv7511&#xff09;I2C Master 寄存器配置模块&#xff08;i2c_c…

692. 前K个高频单词

题目来源&#xff1a;力扣 题目描述&#xff1a; 给定一个单词列表 words 和一个整数 k &#xff0c;返回前 k 个出现次数最多的单词。 返回的答案应该按单词出现频率由高到低排序。如果不同的单词有相同出现频率&#xff0c; 按字典顺序 排序。 示例 1&#xff1a; 输入:…

css transition 指南

css transition 指南 在本文中&#xff0c;我们将深入了解 CSS transition&#xff0c;以及如何使用它们来创建丰富、精美的动画。 基本原理 我们创建动画时通常需要一些动画相关的 CSS。 下面是一个按钮在悬停时移动但没有动画的示例&#xff1a; <button class"…

【斗罗Ⅱ】最强武魂揭秘,98级玄老、95级言少哲神兽级武魂曝光

Hello,小伙伴们&#xff0c;我是小郑继续为大家深度解析【绝世唐门】 在斗罗大陆动画绝世唐门中&#xff0c;98级玄老已经登场&#xff0c;他是一个很随意的老人&#xff0c;乍眼一看&#xff0c;似乎是一个邋里邋遢、好吃懒做的人&#xff0c;但是实际上他却是史莱克学院重量级…

精心整理了优秀的GitHub开源项目,包含前端、后端、AI人工智能、游戏、黑客工具、网络工具、AI医疗等等,空闲的时候方便看看提高自己的视野

精心整理了优秀的GitHub开源项目&#xff0c;包含前端、后端、AI人工智能、游戏、黑客工具、网络工具、AI医疗等等&#xff0c;空闲的时候方便看看提高自己的视野。 刚开源就变成新星的 igl&#xff0c;不仅获得了 2k star&#xff0c;也能提高你开发游戏的效率&#xff0c;摆…

自建音乐服务器Navidrome之二

6 准备音乐资源 可选 Last.fm Lastfm是 Audioscrobbler 音乐引擎设计团队的旗舰产品&#xff0c;以英国为总部的网络电台和音乐社区。有遍布232个国家超过1500万的活跃听众。据说有6亿音乐资源。 docker-compose.yml 配置 Navidrome 可以从 Last.fm 和 Spotify 获取专辑信息和…

性能测试 —— Jmeter 命令行详细

我们在启动Jmeter时 会看见&#xff1a;Don’t use GUI mode for load testing !, only for Test creation and Test debugging.For load testing, use CLI Mode (was NON GUI) 这句话的意思就是说&#xff0c;不要使用gui模式进行负载测试&#xff0c;gui模式仅仅是创建脚本…

涂鸦智能携手亚马逊云科技 共建“联合安全实验室” 为IoT发展护航

2023年8月31日&#xff0c;全球化IoT开发者平台涂鸦智能&#xff08;NYSE: TUYA&#xff0c;HKEX: 2391&#xff09;在“2023亚马逊云科技re:Inforce中国站”大会宣布与全球领先的云计算公司亚马逊云科技共同成立“联合安全实验室”&#xff0c;旨在加强IoT行业的安全合规能力与…

管理类联考——逻辑——形式逻辑——汇总篇——知识点突破——论证逻辑——假设——否定代入

角度——原理 可以用“否定代入法”验证疑似选项 由于假设是使推理成立的一个必要条件&#xff0c;根据必要条件的性质若Р是S的必要条件&#xff0c;那么┐P → ┐S可知&#xff0c;如果一个推理在没有某一条件时&#xff0c;这个推理必然不成立&#xff0c;那么这个条件就是…

41.岛屿数量(第四期模拟笔试)(BFS练习题)

题目&#xff1a; 给定一个 m 行 n 列的二维地图&#xff0c;初始化每个单元格都是海洋&#xff0c;二维地图外也全是海洋。 操作 addLand 会将单元格&#xff08;col, row&#xff09;变为陆地。 定义一系列相连的被海洋包围的陆地为岛屿&#xff0c; 横向相邻或者纵向相连的…

%temp%

C:\Users\ADMINI~1\AppData\Local\Temp

springboot~静态资源配置

springboot~静态资源配置 springboot的静态资源默认路径给静态资源请求加前缀指定静态资源加载的包欢迎页 springboot的静态资源默认路径 请求效果见图 给静态资源请求加前缀 有时需要用拦截器对某些请求进行拦截后再处理相关的业务代码&#xff0c;此时我们就要对请求进行…

2023年智能算法之淘金优化器,MATLAB代码免费获取

今天为大家带来一期淘金优化算法(Gold rush optimizer.,GRO)。 GRO算法是受淘金热启发&#xff0c;模拟了淘金者在淘金热时期如何利用淘金的三个关键概念进行淘金&#xff1a;迁移、协作和淘金。 原理详解 ①金矿勘探阶段&#xff1a; 与大多数智能算法相似&#xff0c;就是随机…

MyBatis学习

一、Mybatis使用 1、新建mybatis配置文件 <?xml version"1.0" encoding"UTF-8" ?> <!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd"> <configu…