当前位置: 首页 > news >正文

Vue学习(三)

一、列表渲染

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",// 函数形式的datadata() {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",// 函数形式的datadata() {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",// 函数形式的datadata() {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",// 函数形式的datadata() {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 即trueif (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",// 函数形式的datadata() {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 = falseconst 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 !== '抽烟'})}}})

 

相关文章:

Vue学习(三)

一、列表渲染 v-for指令 用于展示列表数据 语法<li v-for"(item, index) in items" :key"index"></li>key可以是index,最好是遍历对象的唯一标识 可遍历&#xff1a;数组、对象 <!DOCTYPE html> <html lang"en">&l…...

贝锐蒲公英异地组网路由器如何设置虚拟串口功能?

蒲公英虚拟串口功能&#xff0c;可实现智能组网内的其它成员异地调试此串口&#xff0c;无需到现场进行调试&#xff0c;为企业降低运营成本、便捷掌控设备数据。 1. 蒲公英硬件设置串口 进入蒲公英云管理平台&#xff0c;点击【工业应用】->【串口设置】&#xff0c;开启…...

MySQL 8.1.0 推出 InnoDB Cluster 只读副本

全面了解 8.1.0 版本新功能&#xff1a;InnoDB Cluster 只读副本的相关操作。 作者&#xff1a;Miguel Arajo 高级软件工程师 / Kenny Gryp MySQL 产品总监 本文来源&#xff1a;Oracle MySQL 官网博客 * 爱可生开源社区出品。 前言 MySQL 的第一个 Innovation 版本 8.1.0 已…...

java并发编程 PriorityBlockingQueue详解

文章目录 1 PriorityBlockingQueue是什么2 核心属性详解3 核心方法详解3.1 offer(E e)3.2 poll()3.3 take()3.4 peek() 4 总结 1 PriorityBlockingQueue是什么 PriorityBlockingQueue类上的注释描述&#xff1a;一个无界阻塞队列&#xff0c;它使用与类PriorityQueue相同的排序…...

SpringMVC_基本使用

一、JavaWEB 1.回顾 JavaWEB 1.1新建项目结构 新建 javaweb 项目目录结构 1.2导入依赖 依赖 <dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.1.0</version><scope>…...

大屏开发,浏览器的可视区域和设备的分辨率

在线屏幕检测 - 显示器检测 - 显示器坏点检测工具...

【微服务部署】06-日志集成

文章目录 1. EFK日志三件套集成1.1 核心组件1.2 部署 2. Exceptionless日志系统2.1 Exceptionless核心特性2.2 Exceptionless部署文件2.3 K8s中使用Exceptionless 1. EFK日志三件套集成 1.1 核心组件 Elasticsearch&#xff08;存储&#xff09;Fluentd&#xff08;收集器&am…...

【Python】python使用docxtpl生成word模板

python使用docxtpl生成word模板 python-docxtpl包简单使用和实战&#xff0c;Python处理word&#xff0c;docx文件。 最近需要处理一些爬虫得到的数据来进行一些自动化报告的操作&#xff0c;因为需要生成的是word的报告&#xff0c;所以估选用docxtpl库来直接生成模板 docxt…...

C++学习笔记总结练习:多态与虚函数

1 多态 多态分类 静态多态&#xff0c;是只在编译期间确定的多态。静态多态在编译期间&#xff0c;根据函数参数的个数和类型推断出调用的函数。静态多态有两种实现的方式 重载。&#xff08;函数重载&#xff09;模板。 动态多态&#xff0c;是运行时多态。通过虚函数机制实…...

linux 批量更改指定后辍文件的可执行权限

要在Linux上批量更改指定后缀文件的可执行权限&#xff0c;您可以使用find命令来查找这些文件&#xff0c;然后使用chmod命令来更改它们的权限。以下是一些步骤&#xff1a; 1. 打开终端。 2. 使用 find 命令查找要更改权限的文件&#xff0c;例如&#xff0c;如果您想要更…...

数据结构(Java实现)-Map和Set

搜索树 概念 二叉搜索树又称二叉排序树&#xff0c;它或者是一棵空树&#xff0c;或者是具有以下性质的二叉树: 若它的左子树不为空&#xff0c;则左子树上所有节点的值都小于根节点的值 若它的右子树不为空&#xff0c;则右子树上所有节点的值都大于根节点的值 它的左右子树也…...

C++进程、线程、内存管理

目录 进程和线程区别 进程和线程切换的区别 系统调用流程 系统调用是否会引起线程切换 为什么需要使用虚拟内存 进程和线程区别 本质区别&#xff1a; 进程是资源分配的基本单元。 线程是操作系统调度的基本单元。 地址空间&#xff1a; 进程具有独立的虚拟地址空间。 线程…...

打车系统网约车系统开发支持APP公众号H5小程序版本源码

一、操作流程 二、业务模式 三、用户端 用户注册登录&#xff1a;未注册的手机号将自动创建账号 通过好友的邀请链接进行注册&#xff0c;将会绑定上下级关系 也可以注册的时候输入好友的邀请码&#xff0c;也可以绑定关系 用户充值&#xff1a; 用户下单支付时&#xff0c;可以…...

HTTP/1.1协议的状态码

2023年8月30日&#xff0c;周三下午 HTTP/1.1协议定义了一组状态码&#xff0c;用于表示请求的处理结果。 每个状态码都有特定的含义&#xff0c;它们以三位数字的形式出现在响应的状态行中。 下面是一些常见的HTTP/1.1协议的状态码及其含义&#xff1a; 1xx&#xff08;信息…...

SpringCloud(十)——ElasticSearch简单了解(一)初识ElasticSearch和RestClient

文章目录 1. 初始ElasticSearch1.1 ElasticSearch介绍1.2 安装并运行ElasticSearch1.3 运行kibana1.4 安装IK分词器 2. 操作索引库和文档2.1 mapping属性2.2 创建索引库2.3 对索引库的查、删、改2.4 操作文档 3. RestClient3.1 初始化RestClient3.2 操作索引库3.3 操作文档 1. …...

CAD文字显示?问号解决

背景 从别人哪儿发过来的CAD文件&#xff0c;打开后发现有些文字显示为&#xff1f; 问题排查 通过点击文字特性得知 该文字的样式是 SF和仿宋通过命令行执行st 得知&#xff0c;两种样式关联的字体都是仿宋GB_2312&#xff0c;但当前操作系统无此字体&#xff0c;故显示为&…...

Calico切换网络模式无效

Calico切换网络模式无效 Calico由原先的BGP模式切换为IP IP模式发现未生效&#xff0c;使用的模式还是BGP模式&#xff0c;Calico卸载后查询Etcd发现存在很多Calico数据 [rootk8s-master-1 ~]# etcdctl get / --prefix --keys-only | grep calico /calico/ipam/v2/assignment…...

数据生成 | MATLAB实现GAN生成对抗网络结合SVM支持向量机的数据生成

数据生成 | MATLAB实现GAN生成对抗网络结合SVM支持向量机的数据生成 目录 数据生成 | MATLAB实现GAN生成对抗网络结合SVM支持向量机的数据生成生成效果基本描述程序设计参考资料 生成效果 基本描述 数据生成 | MATLAB实现GAN生成对抗网络结合SVM支持向量机的数据生成。 生成对抗…...

iOS - 资源按需加载 - ODR

一、瘦身技术大图 二、On-Demand Resources 简介 将其保存管理在苹果的服务器&#xff0c;按需使用资源、优化包体积&#xff0c;实现更小的应用程序。ODR 的好处&#xff1a; 应用体积更小&#xff0c;下载更快&#xff0c;提升初次启动速度资源会在后台下载操作系统将会在磁…...

arduino仿真 SimulIDE1.0仿真器

SimulIDE 是一个开源的电子电路模拟器&#xff0c;支持模拟各种电子元器件的行为&#xff0c;可以帮助电子工程师和爱好者进行电路设计和测试。以下是 SimulIDE 的安装和使用说明&#xff1a; 安装 SimulIDE SimulIDE 可以在 Windows、Linux 和 Mac OS X 等操作系统上安装。您…...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…...

在四层代理中还原真实客户端ngx_stream_realip_module

一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡&#xff08;如 HAProxy、AWS NLB、阿里 SLB&#xff09;发起上游连接时&#xff0c;将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后&#xff0c;ngx_stream_realip_module 从中提取原始信息…...

SpringCloudGateway 自定义局部过滤器

场景&#xff1a; 将所有请求转化为同一路径请求&#xff08;方便穿网配置&#xff09;在请求头内标识原来路径&#xff0c;然后在将请求分发给不同服务 AllToOneGatewayFilterFactory import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; impor…...

OpenLayers 分屏对比(地图联动)

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能&#xff0c;和卷帘图层不一样的是&#xff0c;分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...

学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”

2025年#高考 将在近日拉开帷幕&#xff0c;#AI 监考一度冲上热搜。当AI深度融入高考&#xff0c;#时间同步 不再是辅助功能&#xff0c;而是决定AI监考系统成败的“生命线”。 AI亮相2025高考&#xff0c;40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕&#xff0c;江西、…...

TSN交换机正在重构工业网络,PROFINET和EtherCAT会被取代吗?

在工业自动化持续演进的今天&#xff0c;通信网络的角色正变得愈发关键。 2025年6月6日&#xff0c;为期三天的华南国际工业博览会在深圳国际会展中心&#xff08;宝安&#xff09;圆满落幕。作为国内工业通信领域的技术型企业&#xff0c;光路科技&#xff08;Fiberroad&…...

Python实现简单音频数据压缩与解压算法

Python实现简单音频数据压缩与解压算法 引言 在音频数据处理中&#xff0c;压缩算法是降低存储成本和传输效率的关键技术。Python作为一门灵活且功能强大的编程语言&#xff0c;提供了丰富的库和工具来实现音频数据的压缩与解压。本文将通过一个简单的音频数据压缩与解压算法…...

动态规划-1035.不相交的线-力扣(LeetCode)

一、题目解析 光看题目要求和例图&#xff0c;感觉这题好麻烦&#xff0c;直线不能相交啊&#xff0c;每个数字只属于一条连线啊等等&#xff0c;但我们结合题目所给的信息和例图的内容&#xff0c;这不就是最长公共子序列吗&#xff1f;&#xff0c;我们把最长公共子序列连线起…...

智警杯备赛--excel模块

数据透视与图表制作 创建步骤 创建 1.在Excel的插入或者数据标签页下找到数据透视表的按钮 2.将数据放进“请选择单元格区域“中&#xff0c;点击确定 这是最终结果&#xff0c;但是由于环境启不了&#xff0c;这里用的是自己的excel&#xff0c;真实的环境中的excel根据实训…...

AI书签管理工具开发全记录(十八):书签导入导出

文章目录 AI书签管理工具开发全记录&#xff08;十八&#xff09;&#xff1a;书签导入导出1.前言 &#x1f4dd;2.书签结构分析 &#x1f4d6;3.书签示例 &#x1f4d1;4.书签文件结构定义描述 &#x1f523;4.1. ​整体文档结构​​4.2. ​核心元素类型​​4.3. ​层级关系4.…...