【vue】vue动态样式绑定详解_05
目录
⬛ 绑定样式
1. 绑定内联样式
2. 绑定class
❣️ 巩固总结:样式绑定——动态绑定元素的class
❣️ 巩固总结:样式绑定——动态绑定内联样式
❣️ 小结
💥 扩展:this判断—8种指向
⬛ 总结:知识点提炼
【前文回顾】👉 vue双向数据绑定的原理解析及代码实现_04
⬛ 绑定样式
1. 绑定内联样式
(1). 不好的做法: 将style属性看做一个普通的字符串属性进行绑定。
a.
data:{
变量: "css属性:值; css属性:值;..."
}
b. 问题: 极其不便于只操作其中某一个css属性
(2). 好的办法: 将style看做一个对象来绑定。每个css属性都是对象中的一个属性。
结果: "css属性1:属性值1; css属性2:属性值2;..."
↑ ↑ ↑ ↑
a. <元素 :style="{ css属性1: 变量1, css属性2: 变量2, ... }"
data:{
变量1:"属性值1",
变量2:"属性值2",
... ...
}
b. 优点: 轻易只修改其中某一个css属性值,而不影响其他属性值
c. 问题: 如果多个css属性的变量零散的保存在data中,如果多个元素都需要控制内联样式,就极容易发生冲突。
d. 示例: 控制一个飞机的飞行
1_style.html
Document img{ position:fixed; left:50%; } <!--
-->
var vm=new Vue({ el:"#app", data:{ marginLeft:"-100px", //必须带单位 bottom:"50px" } })
运行结果:
(3). 更好的解决办法: 将每个元素所需的所有内联样式变量,集中保存在data中的一个对象里。
a.
data:{
变量名1:{
css属性:值,
... : ...
},
变量名2:{
css属性:值,
... : ...
}
b. 优点: 避免不同元素间相同css属性的冲突
c. 示例: 控制两个飞机的飞行
1_style2.html
Document img{ position:fixed; }
var vm=new Vue({ el:"#app", data:{ img1Style:{ marginLeft:"-200px", bottom:"25px", }, img2Style:{ marginLeft:"100px", bottom:"100px" } } })
运行结果:
(4). 问题: 如果元素上有些内联css属性是固定不变的,而有些css属性是可能发生变化的?
(5). 解决: 其实在一个元素上写死的固定不变的style和动态变化的:style是可以并存的。最后运行的结果是,:style动态生成的css属性会和style中固定不变的属性合并为最终应用到元素上的style属性。
结果: style="固定不变的css属性:值; 变化的css属性: 值; ..."
↑ ↑
<元素 style="固定不变的css属性:值" :style="变量"
data:{
变量:{
变化的css属性: 值
}
}
比如:
data:{
img1Style:{
marginLeft:"-200px",
bottom:"25px",
}
}
(6). 问题: DOM中经常批量修改一个元素的多个css属性,如果单个修改每个css属性值,代码会很繁琐
(7). 解决: 用class来代替单独修改每个css属性。
2. 绑定class
(1). 不好的方法: 将整个class字符串,看做一个普通的字符串属性绑定.
data:{
变量: "class1 class2 ..."
}
缺点: 极其不便于修改其中某一个class
(2). 好的方法: 将class看做一个对象来绑定。
a. <元素 :class="{ class1: 变量1, class2: 变量2, ... }"
data:{
变量1: true或false,
变量2: true或false,
... : ...
}
说明: 当一个class对应的变量值是true,则这个class会出现在编译后的元素上,起作用;当一个class对应的变量值为false,则这个class不会出现在编译后的元素上,不起作用!
b. 优点: 极其便于修改其中某一个class
c. 示例: 验证手机号
2_class.html
Document .span-cls{ padding:5px 10px; } .success{ background-color:lightGreen; border:green; color:green; } .fail{ background-color:pink; border:red; color:red; } 手机号: <!-- {{msg}} --> {{msg}} //2. 创建new Vue()对象 var vm=new Vue({ el:"#app", //3. 创建模型对象 //因为界面中共需要4个变量,所以:data:{ phone:"", success:false, fail:false, msg:"" }, //因为界面中需要一个事件处理函数 methods:{ vali(){ //定义验证手机号的正则表达式: var reg=/^1[3-9]\d{9}$/; //用正则验证手机号正确 if(reg.test(this.phone)==true){ //就修改span为验证通过的样子 this.success=true; this.fail=false; this.msg=" √ 手机号格式正确"; }else{//否则如果验证失败 //就修改span为验证失败的样式 this.success=false; this.fail=true; this.msg=" × 手机号格式不正确" } } } })
运行结果:
d. 问题: 如果多个元素都需要用同一个class,但是启用和禁用的状态各不相同,如果将变量直接保存在data中,极容易发生冲突
(3). 更好的方法: 将一个元素的多个class包裹在一个对象变量中:
a.
data:{
变量1:{
class名: true或false,
... : ...
},
变量2:{
class名: true或false,
... : ...
}
}
b. 优点: 即使多个元素,共用同一个class,也不会发生冲突!
c. 示例: 验证手机号和身份证号
2_class3.html
Document .span-cls { padding: 5px 10px; } .success { background-color: lightGreen; border: green; color: green; } .fail { background-color: pink; border: red; color: red; } 手机号: {{phoneMsg}}
身份证号: {{pidMsg}} //2. 创建new Vue()对象 var vm = new Vue({ el: "#app", //3. 创建模型对象 //因为界面中共需要4个变量,所以: data: { phone: "", //接文本框中的值 pid: "", //接文本框中的值 phoneSpan: { //控制手机号验证结果的样式 success: false, fail: false, }, pidSpan: { //控制身份证号验证结果的样式 success: false, fail: false, }, phoneMsg: "", //保存手机号的错误提示 pidMsg: "", //保存身份证号的错误提示 }, //因为界面中需要一个事件处理函数 methods: { valiPhone() { //定义验证手机号的正则表达式: var reg = /^1[3-9]\d{9}$/; //用正则验证手机号正确 // 复习小程序中js高级第2天 if (reg.test(this.phone) == true) {//就修改span为验证通过的样子this.phoneSpan = { success: true, fail: false,};this.phoneMsg = " √ 手机号格式正确"; } else {//否则如果验证失败//就修改span为验证失败的样式this.phoneSpan = { success: false, fail: true,};this.phoneMsg = " × 手机号格式不正确"; } }, valiPid() { //定义验证身份证号的正则表达式: var reg = /^\d{15}(\d\d[0-9x])$/i; //用正则验证身份证号正确 // 复习小程序中js高级第2天 if (reg.test(this.pid) == true) {//就修改span为验证通过的样子this.pidSpan = { success: true, fail: false,};this.pidMsg = " √ 身份证号格式正确"; } else {//否则如果验证失败//就修改span为验证失败的样式this.pidSpan = { success: false, fail: true,};this.pidMsg = " × 身份证号格式不正确"; } }, }, });
运行结果:
(4). 问题: 如果元素上有些class是固定不变的,而有些class是可能发生变化的?
(5). 解决: 其实在一个元素上写死的固定不变的class和动态变化的:class是可以并存的。最后运行的结果是,:class动态生成的class字符串会和class中固定不变的class字符串合并为最终应用到元素上的class属性。
❣️ 巩固总结:样式绑定——动态绑定元素的class
我们可以通过数组和对象的两种形式绑定元素的 Class。
💦 对象语法形式 💦
在巩固总结上面的文章篇幅里,讲解的便是绑定元素的class的对象语法,在这里我们重新再回顾一下。
1️⃣ 对象语法
通过传给 v-bind:class
一个对象,以动态地切换 class:
代码解释: 上面的语法表示 show
这个 class 存在与否将取决于数据属性 isShow
是否为真值。
实例演示
Document .hide { display: none; } Hello ! var vm = new Vue({ el: '#app', data: { isHide: true },})//vm.isHide = true
代码解释: HTML 代码第 2 行,我们给 div 绑定样式,当 isHide 为真值时, 其渲染结果为
,否则
。 打开控制台,修改 vm.isHide 的值可以动态改变页面效果。
2️⃣ 与普通的 class 属性共存
此外,v-bind:class
指令也可以与普通的 class 属性共存。 语法:
当有如下模板:
和如下 data:
data: { isShow: true, hasError: false}
页面结果渲染为:
代码解释: 当 isShow
或者 hasError
变化时,class 列表将相应地更新。
例如,如果 hasError
的值为 true
,isShow
的值为 true
,class 列表将变为 "defaultClass show text-danger"
。
例如,如果 hasError
的值为 true
,isShow
的值为 false
,class 列表将变为 "defaultClass text-danger"
。
在之前介绍的案例中,我们将绑定的数据对象内联定义在模板里, 这样显得比较繁琐。其实,我们可以统一定义在一个 classObject 中:
实例演示
Document Hello ! var vm = new Vue({ el: '#app', data: { classObject: { show: true, 'text-danger': false } },})
页面结果渲染为:
代码解释: HTML 代码中,我们首先给 div 一个固定样式 defaultClass, 然后通过 classObject 给 div 绑定样式。 JS 代码 第 6-9 行,我们定义了数据 classObject,它有两个属性:1. 属性 show,值为 true,2. 属性 text-danger,值为 false。所以,最后页面渲染的效果是:
3️⃣ 利用计算属性绑定样式
我们也可以在这里绑定一个返回对象的计算属性。这是一个常用且强大的模式:
实例演示
Document var vm = new Vue({el: '#app', computed: { //对象语法————classObject: function(){...}等价于classObject(){...} classObject: function () { return { show: true, //对象的属性名引号可加可不加,若属性名里有特殊字符,属性名必须加引号) 'text-danger': false } } }})
页面结果渲染为:
代码解释: HTML 代码中,我们通过 classObject 给 div 绑定样式。 JS 代码 第 6-11 行,我们定义了计算属性 classObject,它返回一个对象,该对象有两个属性:1. 属性 show,值为 true,2. 属性 text-danger,值为 false。所以,最后页面渲染的效果是:
💦 数组语法形式 💦
我们可以把一个数组传给 v-bind:class
,以应用一个 class 列表:
实例演示
Document Hello ! var vm = new Vue({el: '#app', data: { classA: 'classA', classB: 'classB1 classB2' },})
页面结果渲染为:
代码解释: 在 HTML 代码中,我们通过数组给 div 绑定样式,数组中有 classA 和 classB 两个值。 在 JS 代码第 6-7 行定义了 classA 和 classB 两个字符串,它的格式和元素 class 的格式相同,不同的样式类之间以空格相隔。
如果你也想根据条件切换列表中的 class,可以用三元表达式:
这样写将始终添加 classB
的样式,但是只有在 isShow
为真时才添加 showClass
。
不过,当有多个条件 class 时这样写有些繁琐。所以在数组语法中也可以使用对象的形式来表达数组中的某一项:
代码解释: 在 HTML 中,div 绑定一个样式数组,数组第一项是一个对象表达式 { showClass: isShow }。当 isShow 为 true 时样式最终绑定为:
;当 isShow 为 false 时样式最终绑定为:
;
❣️ 巩固总结:样式绑定——动态绑定内联样式
和 Class 的绑定一样,Style 的绑定同样可以通过数组和对象的两种形式。
💦 对象语法 💦
在文章开头时,讲解的便是绑定内联样式的对象语法,在这里我们重新再回顾一下。
v-bind:style
的对象语法十分直观——看着非常像 CSS,但其实是一个 JavaScript 对象。CSS 属性名可以用驼峰式 (camelCase) 或短横线分隔 (kebab-case,记得用引号括起来,因为对象的书写格式中规定,属性名引号可加可不加,但若属性名里有特殊字符,属性名必须加引号,关于队对象的知识点介绍,请之后关注我的JS专栏) 来命名:
实例演示
Document var vm = new Vue({el: '#app', data: { backgroundColor: 'red', width: 300 }})
页面结果渲染为:
代码解释: 在 HTML 代码中,我们给 div 绑定 background-color 和 width 两个内联样式,它们的值在 data 中定义。
在模板中写较为复杂的表达式语法显得比较繁琐,通常直接绑定到一个样式对象更好,这会让模板显得更加清晰:
实例演示
Document var vm = new Vue({el: '#app', data: { styleObject: { "background-color": 'red', width: '300px' } },})
页面结果渲染为:
代码解释: 在 HTML 代码中,我们给 div 绑定数据 styleObject,它们的值在 data 中定义(data里保存界面里所有需要的变量)。
💦 数组语法 💦
v-bind:style
的数组语法可以将多个样式对象应用到同一个元素上:
实例演示
Document var vm = new Vue({el: '#app', data: { stylesA: { "background-color": 'red', width: '300px' }, stylesB: { color: '#fff', height: '300px' } }})
页面结果渲染为:
❣️ 小结
本小节我们学习了如何通过v-bind
来动态绑定样式。主要有以下知识点:
- 通过 v-bind:class 动态绑定元素的 Class;
- v-bind:style 动态绑定元素的内联样式;
- 如何通过数组和对象的形式给 v-bind:class 和 v-bind:style 赋值。
💥 扩展:this判断—8种指向
this 8种指向: 判断this,一定不要看定义在哪儿!只看调用时!
➡️ 1. obj.fun() this->obj
➡️ 2. fun() 或 (function(){ ... })() 或 多数回调函数 或 定时器函数 this->window
➡️ 3. new Fun() this->new正在创建的新对象
➡️ 4. 类型名.prototype.共有方法=function(){ ... } this->将来谁调用指谁,同第一种情况
➡️ 5. DOM或jq中事件处理函数中的this->当前正在触发事件的DOM元素对象
如果需要使用简化版函数,必须$(this)
➡️ 6. 箭头函数中的this->箭头函数外部作用域中的this
➡️ 7. jQuery.fn.自定义函数=function(){ ... } this->将来调用这个自定义函数的.前的jQuery子对象,不用再$(this)
➡️ 8. new Vue()中methods中的函数中的this->当前new Vue()对象
⬛ 总结:知识点提炼
1. MVVM: 界面View+模型Model+视图模型ViewModel
2. Vue绑定原理: 访问器属性+虚拟DOM树
变量被修改时: 访问器属性发出通知,虚拟DOM树扫描并仅更新受影响的元素
3. 虚拟DOM树优点:
(1). 小: 只包含可能变化的元素。
(2). 遍历查找快
(3). 修改效率高: 只修改受影响的元素。
(4). 避免重复编码: 已封装DOM增删改查代码
4. Vue功能3步:
(1). 先创建增强版的界面:
a. 整个界面必须包含在一个唯一的父元素下:
通常是
c. 触发事件的元素用@click="自定义处理函数名"标记
(2). 再创建new Vue()对象,其中el:指向new Vue()要监控的页面区域
(3). 在new Vue()对象内定义模型对象data和methods
a.界面所需的所有变量都放在data中
b.界面所需的所有事件处理函数都放在methods中
5. 总结: 绑定语法+13种指令
(1). 如果元素的内容需要随变量自动变化: {{}}
(2). 如果元素的属性值需要随变量自动变化: :
(3). 控制一个元素显示隐藏: v-show //使用display:none隐藏元素
(4). 控制两个元素二选一显示: v-if v-else //使用删除元素方式隐藏元素
(5). 多个元素多选一显示: v-if v-else-if v-else
(6). 只要反复生成多个相同结构的元素组成列表时: v-for :key="唯一标识"
强调: 为什么必须加:key="i"?给每个元素副本添加唯一标识。修改数组中某个元素值时,避免重建整个列表,只需要修改一个DOM元素副本即可!提高修改效率。
(7). 只要绑定事件: @ $event
(8). 防止用户短暂看到{{}}: v-cloak和v-text
(9). 只要绑定原始HTML代码片段内容: v-html
(10). 如果元素的内容只在首次加载时绑定一次,之后都不会改变: v-once
优化: 减少虚拟DOM树中元素个数。
(11). 保护内容中的{{}}不被编译: v-pre
(12). 今后只要想获得表单元素的值或状态: v-model
6. 绑定样式:
(1). 需要精确修改某一个css属性,就绑定style:
a. <元素 style="固定样式" :style="{css属性:变量名, ...}"
data:{
变量名:css属性值
... : ...
}
b. <元素 style="固定样式" :style="变量名"
data:{
变量名:{
css属性名: 属性值,
... : ...
}
}
(2). 只要批量修改一个元素的多个css属性就绑定class
a. <元素 class="固定class" :class="{class名:变量名, ...}"
data:{
变量名:true或false,
... : ...
}
b. <元素 class="固定class" :class="变量名"
data:{
变量名:{
class名:true或false,
... : ...
}
}
如果这篇【文章】有帮助到你,希望可以给【青春木鱼】点个赞👍,创作不易,相比官方的陈述,我更喜欢用【通俗易懂】的文笔去讲解每一个知识点,如果有对【前端技术】感兴趣的小可爱,也欢迎关注❤️❤️❤️【青春木鱼】❤️❤️❤️,我将会给你带来巨大的【收获与惊喜】💕💕!