8、class与style绑定

8.1、理解

(1)在应用界面中,某个(些)元素的样式是变化的 (2)class/style绑定就是专门用来实现动态样式效果的技术

8.2、绑定class

(1)绑定class样式–字符串写法,适用于:样式的类名不确定,需要动态指定 (2)绑定class样式–数组写法,适用于:要绑定的样式个数不确定、名字也不确定 (3)绑定class样式–对象写法,适用于:要绑定的样式个数确定、名字也确定,但要动态决定用不用

例如:


<style>.basic {width: 300px;height: 60px;margin: 10px;border: 1px solid black;}.happy {background-color: pink;border: 1px solid black;} .sad {background-color: rgb(70, 67, 68);border: 1px solid black;}.wu {background-color: rgb(236, 3, 42);border: 1px solid black;}.at1 {background-color: green;border: 4px solid black;}.at2 {background-color: green;border: 4px dashed black;}.at3 {background-color: green;border: 4px solid blue;}</style>
 <div id="root"><!-- 绑定class样式--字符串写法,适用于:样式的类名不确定,需要动态指定 --><div class="basic" :class="classStr">{{name}}</div><!-- 绑定class样式--数组写法,适用于:要绑定的样式个数不确定、名字也不确定 --><div class="basic" :class="classArr">{{name}}</div><!-- 绑定class样式--对象写法,适用于:要绑定的样式个数确定、名字也确定,但要动态决定用不用 --><div class="basic" :class="classObj">{{name}}</div></div>
 Vue.config.productionTip = false; //设置为 false 以阻止 vue 在启动时生成生产提示。const vm = new Vue({el: "#root",data: {name: "test",classStr: "happy",classArr: ['at1', 'at2', 'at3'],classObj: {at1: true,at2: false}}})
 

8.3、style绑定

(1)绑定style样式–对象写法 ,属性名改为小驼峰命名 (2)绑定style样式–数组写法(不常用),数组其中是对象 例如:

 
<style>.basic {width: 300px;height: 60px;margin: 10px;border: 1px solid black;}</style>
 <div id="root"><!-- 绑定style样式--对象写法 --><div class="basic" :style="styleObj">{{name}}</div><!-- 绑定style样式--数组写法(不常用) --><div class="basic" :style="styleArr">{{name}}</div></div>
 const vm = new Vue({el: "#root",data: {name: "test",styleObj: {fontSize: '40px',color: "red",backgroudColor: "yellow"},styleArr: [{fontSize: '40px',color: "red"}, {backgroudColor: "yellow"}​]}})

9、条件渲染

9.1、v-if

写法:

  • v-if=“表达式”

  • v-else-if=“表达式”

  • v-else 适用于:切换频率较低的场景 特点:不展示的DOM元素直接被删除 注意:v-if可以和v-else-if、v-else一起使用,但要求结构不能被打断

 
<!DOCTYPE html><html><head><meta charset="UTF-8" /><title>条件渲染</title><script type="text/javascript" src="../js/vue.js"></script></head><body><div id="root"><h2>当前的n值是:{{n}}</h2><button @click="n++">点我n+1</button><h2 v-show="true">Hello,{{name}}!</h2>​<div v-if="n === 1">Angular</div><div v-else-if="n === 2">React</div><div v-else>Vue</div></div></body>​<script type="text/javascript">Vue.config.productionTip = false​const vm = new Vue({el:'#root',data:{name:'jojo',n:0}})</script></html>

< template>配合v-if使用:

     
<template v-if="true"><h3>你好,{{name}}</h3><h3>你好,{{name}}</h3><h3>你好,{{name}}</h3></template>

< template>不会渲染到DOM结构中,且只有和v-if配合使用才可以起到整套删除整套显示的效果。

9.2、v-show

写法:v-show=“表达式” 适用于:切换频率较高的场景 特点:不展示的DOM元素未被移除,仅仅是使用样式隐藏掉了

使用v-if的时,元素可能无法获取到,而使用v-show一定可以获取到

10、列表渲染

10.1、基本列表

v-for指令:

  • 用于展示列表数据

  • 语法:

v-for="(item,index) in xxx" :key="xxx"

举例:


<!DOCTYPE html><html><head><meta charset="UTF-8" /><title>基本列表</title><script type="text/javascript" src="../js/vue.js"></script></head><body><div id="root"><h2>人员列表(遍历数组)</h2><ul><li v-for="(p,index) in persons" :key="index">{{p.name}}-{{p.age}}</li></ul>​<h2>汽车信息(遍历对象)</h2><ul><li v-for="(value,k) in car" :key="k">{{k}}-{{value}}</li></ul>​<h2>遍历字符串</h2><ul><li v-for="(char,index) in str" :key="index">{{char}}-{{index}}</li></ul><h2>遍历指定次数</h2><ul><li v-for="(number,index) in 5" :key="index">{{index}}-{{number}}</li></ul></div>​<script type="text/javascript">Vue.config.productionTip = falsenew Vue({el:'#root',data:{persons:[{id:'001',name:'张三',age:18},{id:'002',name:'李四',age:19},{id:'003',name:'王五',age:20}],car:{name:'奥迪A8',price:'70万',color:'黑色'},str:'hello'}})</script></body></html>

总结:

v-for指令:

  1. 用于展示列表数据

  2. 语法:<li v-for="(item, index) in xxx" :key="yyy">,其中key可以是index,也可以是遍历对象的唯一标识

  3. 可遍历:数组、对象、字符串(用的少)、指定次数(用的少)

10.2、key的原理

我们在上面遍历数组的代码基础上,增加一个需求:点击一个按钮在张三的上面增加一行老刘的信息,并在每一行后面增加一个input框,用这个需求来分析key的原理:

 <!DOCTYPE html><html><head><meta charset="UTF-8" /><title>key的原理</title><script type="text/javascript" src="../js/vue.js"></script></head><body><div id="root"><h2>人员列表</h2><button @click.once="add">添加老刘</button><ul><li v-for="(p,index) in persons" :key="index">{{p.name}} - {{p.age}}<input type="text"></li></ul></div>​<script type="text/javascript">Vue.config.productionTip = falsenew Vue({el:'#root',data:{persons:[{id:'001',name:'张三',age:18},{id:'002',name:'李四',age:19},{id:'003',name:'王五',age:20}]},methods: {add(){const p = {id:'004',name:'老刘',age:40}this.persons.unshift(p)}},})</script></html>

原理:

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

  2. 对比规则:

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

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

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

    • 旧虚拟DOM中未找到与新虚拟DOM相同的key:创建新的真实DOM,随后渲染到到页面

  3. 用index作为key可能会引发的问题:

    若对数据进行逆序添加、逆序删除等破坏顺序操作:会产生没有必要的真实DOM更新 ==> 界面效果没问题, 但效率低 若结构中还包含输入类的DOM:会产生错误DOM更新 ==> 界面有问题

  4. 开发中如何选择key?

    最好使用每条数据的唯一标识作为key,比如id、手机号、身份证号、学号等唯一值 如果不存在对数据的逆序添加、逆序删除等破坏顺序的操作,仅用于渲染列表,使用index作为key是没有问题的

10.3、列表过滤

下面用两个例子(分别是用监视和计算属性)来实现列表过滤:

例子一(监视):

<div id="root"><input type="text" placeholder="请输入名字" v-model="keyword"><ul><li v-for="p in person1" :key="p.id">{{p.name}}-{{p.age}}-{{p.sex}}</li></ul>
</div> 
   const vm = new Vue({el: "#root",data: {keyword: "",person: [{id: '001',name: "马冬梅",age: 18,sex: '女'}, {id: '002',name: "周冬雨",age: 28,sex: '女'}, {id: '003',name: "周杰伦",age: 13,sex: '男'}, {id: '004',name: "温兆伦",age: 45,sex: '男'}, ],person1: []},watch: {keyword: {//初始状态页面没有数据显示,即初始状态person1为空,此时让handler先执行一遍,让person1得到数据immediate: true,handler(val) {//filter过滤器 遍历旧数组中的元素后,返回过滤后的新数组this.person1 = this.person.filter((p) => {//indexOf 前一个字符串中是否包含有括号里的字符串,不包含返回-1return p.name.indexOf(val) !== -1})}}}})

例子二(计算属性):

<div id="root"><input type="text" placeholder="请输入名字" v-model="keyword"><ul><li v-for="p in person1" :key="p.id">{{p.name}}-{{p.age}}-{{p.sex}}</li></ul>
</div>
 const vm = new Vue({el: "#root",data: {keyword: "",person: [{id: '001',name: "马冬梅",age: 18,sex: '女'}, {id: '002',name: "周冬雨",age: 28,sex: '女'}, {id: '003',name: "周杰伦",age: 13,sex: '男'}, {id: '004',name: "温兆伦",age: 45,sex: '男'}, ]},computed: {person1() {return this.person.filter((p) => {return p.name.indexOf(this.keyword) !== -1})}}})

10.4、列表排序

在上面用计算属性的列表过滤的基础上增加一个排序功能:

<div id="root"><input type="text" placeholder="请输入名字" v-model="keyword"><button @click="sortType=2">年龄升序</button><button @click="sortType=1">年龄降序</button><button @click="sortType=0">原顺序</button><ul><li v-for="p in person1" :key="p.id">{{p.name}}-{{p.age}}-{{p.sex}}</li></ul>
</div>
 const vm = new Vue({el: "#root",data: {keyword: "",sortType: 0, //0原顺序,1降序,2升序person: [{id: '001',name: "马冬梅",age: 18,sex: '女'}, {id: '002',name: "周冬雨",age: 28,sex: '女'}, {id: '003',name: "周杰伦",age: 13,sex: '男'}, {id: '004',name: "温兆伦",age: 45,sex: '男'}, ]},computed: {person1() {const arr = this.person.filter((p) => {return p.name.indexOf(this.keyword) !== -1})//判断是否排序if (this.sortType) {arr.sort((a, b) => {return this.sortType === 1 ? b.age - a.age : a.age - b.age})}return arr}}})

穿插:Vue监测数据的原理

1、更新时的一个问题

<div id="root"><ul><button @click="mdm">更新马冬梅的信息</button><li v-for="p in person" :key="p.id">{{p.name}}-{{p.age}}</li></ul>
</div>
const vm = new Vue({el: "#root",data: {person: [{id: '001',name: "马冬梅",age: 18,sex: '女'}, {id: '002',name: "周冬雨",age: 28,sex: '女'}, {id: '003',name: "周杰伦",age: 13,sex: '男'}, {id: '004',name: "温兆伦",age: 45,sex: '男'}, ]},methods: {mdm() {this.person[0].name = '马老师'this.person[0].age = 50this.person[0].sex = '男'}}})

上述代码实现更新马冬梅的信息:

点击按钮后成功更新:

但是将methods中的方法改为直接修改整个对象元素:

methods: {mdm() {this.person[0] = {id: '001',name: "马老师",age: 50,sex: "男"}}
}

这样点击按钮,信息就没有更新,其实Vue无法监测到直接给数组元素赋的值,下面说说Vue监测数据的原理。

2、监测数据的原理

①Vue会监测data中所有层次的数据,就是即使对象中的对象的属性也能递归监测

②如何监测对象中的数据 通过setter实现监测,且要在new Vue时就传入要监测的数据

(1)对象中后追加的属性,Vue默认不做响应式处理

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

③如何监测数组中的数据 通过包裹数组更新的方法实现,本质就是做了两件事:

(1)调用原生对应的方法对数组进行更新

(2)重写解析模板,进行更新页面

④在Vue修改数组中的某一个元素不能直接赋值,即不能直接带下标赋值,Vue监测不到,就像上面的问题一样,一定要用如下方法:

(1)使用数组的一些API:push()/pop()/shift()/unshift()/splice()/sort()/reverse()

(2)Vue.set()或vm.$set()

当然可以直接改变整个数组。

特别注意:Vue.set()和vm.$set()不能给vm或vm的根数据对象 添加属性

例子:

<!DOCTYPE html>
<html><head><meta charset="UTF-8" /><title>Vue数据监视</title><style>button{margin-top: 10px;}</style><script type="text/javascript" src="../js/vue.js"></script></head><body><div id="root"><h1>学生信息</h1><button @click="student.age++">年龄+1岁</button><br/><button @click="addSex">添加性别属性,默认值:男</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></body><script type="text/javascript">Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。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,'开车')},removeSmoke(){this.student.hobby = this.student.hobby.filter((h)=>{return h !== '抽烟'})}}})</script>
</html>

效果:

每个点击之后

11、收集表单数据

<!DOCTYPE html>
<html><head><meta charset="UTF-8" /><title>收集表单数据</title><script type="text/javascript" src="../js/vue.js"></script></head><body><div id="root"><form @submit.prevent="demo">账号:<input type="text" v-model.trim="userInfo.account"> <br/><br/>密码:<input type="password" v-model="userInfo.password"> <br/><br/>年龄:<input type="number" v-model.number="userInfo.age"> <br/><br/>性别:男<input type="radio" name="sex" v-model="userInfo.sex" value="male">女<input type="radio" name="sex" v-model="userInfo.sex" value="female"> <br/><br/>爱好:学习<input type="checkbox" v-model="userInfo.hobby" value="study">打游戏<input type="checkbox" v-model="userInfo.hobby" value="game">吃饭<input type="checkbox" v-model="userInfo.hobby" value="eat"><br/><br/>所属校区:<select v-model="userInfo.city"><option value="">请选择校区</option><option value="beijing">北京</option><option value="shanghai">上海</option><option value="shenzhen">深圳</option><option value="wuhan">武汉</option></select><br/><br/>其他信息:<textarea v-model.lazy="userInfo.other"></textarea> <br/><br/><input type="checkbox" v-model="userInfo.agree">阅读并接受<a href="http://www.atguigu.com">《用户协议》</a><button>提交</button></form></div></body><script type="text/javascript">Vue.config.productionTip = falsenew Vue({el:'#root',data:{userInfo:{account:'',password:'',age:0,sex:'female',hobby:[],city:'beijing',other:'',agree:''}},methods: {demo(){console.log(JSON.stringify(this.userInfo))}}})</script>
</html>

总结:

  1. 收集表单数据:

  • 若:<input type="text"/>,则v-model收集的是value值,用户输入的内容就是value值

  • 若:<input type="radio"/>,则v-model收集的是value值,且要给标签配置value属性

  • 若:<input type="checkbox"/>

    • 没有配置value属性,那么收集的是checked属性(勾选 or 未勾选,是布尔值)

    • 配置了value属性:

      • v-model的初始值是非数组,那么收集的就是checked(勾选 or 未勾选,是布尔值)

      • v-model的初始值是数组,那么收集的就是value组成的数组

  1. v-model的三个修饰符:

  • lazy:失去焦点后再收集数据

  • number:输入字符串转为有效的数字

  • trim:输入首尾空格过滤

Vue2学习笔记(尚硅谷张天禹老师)Day-02相关推荐

  1. 尚硅谷 张天禹老师vue2笔记(方便自己查阅)

    视频链接: 文章目录 尚硅谷 张天禹老师vue2笔记 脚手架文件结构 关于不同版本的Vue vue.config.js配置文件 ref属性 props配置项 mixin(混入) 插件 scoped样式 ...

  2. [记录学习]自学尚硅谷张天禹Vue2+3框架_vue_test

    首先感谢尚硅谷和张天禹老师的教学分享!Respect! 学习来源:B站 https://www.bilibili.com/video/BV1Zy4y1K7SH?p=1&vd_source=07 ...

  3. [记录学习]自学尚硅谷张天禹Vue2+3框架_vue3_test

    首先感谢尚硅谷和张天禹老师的教学分享!Respect! 学习来源:B站 https://www.bilibili.com/video/BV1Zy4y1K7SH?p=1&vd_source=07 ...

  4. Vue2学习笔记(尚硅谷张天禹老师)day-01

    Vue 一.vue核心 1.vue简介 1.1.vue是什么 一套用于构建用户界面的渐进式JavaScript框架. 渐进式:vue可以自底向上逐层应用:简单应用:只需一个轻量小巧的核心库:复杂应用: ...

  5. Vue2学习笔记(尚硅谷张天禹老师)Day-03

    12.过滤器 定义:对要显示的数据进行特定格式化后再显示(使用于一些简单逻辑的处理) 语法: 注册过滤器: 全局过滤器 Vue.filter(name, callback)或局部过滤器 new Vue ...

  6. Vue2笔记 尚硅谷张天禹

    笔记 脚手架文件结构 ├── node_modules ├── public │ ├── favicon.ico: 页签图标 │ └── index.html: 主页面 ├── src │ ├── a ...

  7. 尚硅谷张天禹Vue课程v-for中key的原理动画PPT(免费领取)

    最近在看尚硅谷张天禹老师的Vue课程,他通过PPT动画的形式把v-for中key的底层原理讲解的非常透彻,觉得很生动,很遗憾没有找到对应的PPT动画资源,想必不少朋友跟我一样,为了便于后面的复习,所以 ...

  8. MySQL学习笔记——尚硅谷李玉婷经典版MySQL基础笔记(一)

    MySQL学习笔记--尚硅谷李玉婷经典版MySQL基础笔记(一) MySQL学习笔记目录 MySQL学习笔记--尚硅谷李玉婷经典版MySQL基础笔记(一) 一.基础知识 1.MySQL的语法规范 2. ...

  9. maven学习笔记——尚硅谷

    文章目录 maven学习笔记--尚硅谷 第一章 Maven概述 第一节 为什么要学习Maven 1.Maven 作为依赖管理工具 1.1 jar 包的规模 1.2 jar 包的来源 1.3 jar 包 ...

最新文章

  1. Flutter 构建完整应用手册-动画
  2. Python执行pyinstaller打包生成的exe文件实战
  3. 01月26日【Python3 基础知识】
  4. Lua中使用Sleep函数
  5. base64的c语言实现方法
  6. 使用Kotlin写脚本
  7. linux中添加一个用户到指定用户组的两种方式,修改一个用户到指定用户组的一种方式...
  8. JVM—内存模型JMM
  9. wikioi 1034 家 实时动态的网络流量(费用流)
  10. 深入了解Java 8日期和时间API
  11. android 编辑自定义可编辑表格,smart 框架 列表 可编辑表格
  12. 2.Spring Boot 入门
  13. 怎样能看懂matlab中的代码,初学者怎样能看懂代码
  14. 计算机考试一级b软件未来教育,2019.9全国计算机一级MS Office考试每日一练
  15. 蔬菜出口流程 |外贸流程
  16. matlab如何调整顺时针逆时针,关于算法:确定线段的方向是顺时针还是逆时针
  17. D. Concatenated Multiples
  18. 使用SAP的中国公司
  19. SpringBoot结合Redis实现维护客户端登录状态
  20. 36氪2022年Q3总收入同比增长两位数超预期,连续第四个季度盈利,广告收入同比增长20%

热门文章

  1. linux C++通讯架构实战课程
  2. MySQL学习(十七):数据类型之文本字符串类型
  3. 使用neurolab报错AssertionError
  4. 教你如何删除流氓软件(以一个压缩软件为例)
  5. Jackjson使用
  6. 查看网页加密密码超简单
  7. 下一代 Windows 10X 操作系统要来了!
  8. 大写金额转小写(千万以下)
  9. 数据库系统设计课程总结3-sql 进阶
  10. [译]PG复制和自动故障转移--2