绑定class样式
:class=""
字符串内是表达式,可以是属性值、数组、对象
<div class="basic" :class="mood"></div>
//Vue实例中
data: {
mood:"happy"
}
数组形式:
<div class="basic" :class="classArr">class修改样式</div>
//Vue实例中
data: {
classArr:["happy","good"]
}
对象形式:
<div class="basic" :class="classObj">class修改样式</div>
//Vue实例中
data: {
classObj:{
happy:true,
good:false
}
}
绑定style样式
:style=""
字符串内是表达式,可以是对象(一般这样写)、数组(数组中多个对象)
一般形式:
<div class="basic" :style="styleObj">class修改样式</div>
//Vue实例中
data: {
styleObj:{
color:"orange",
backgroundColor:"#ff0000"
}
}
数组形式:
<div class="basic" :style="styleArr">class修改样式</div>
//Vue实例中
data: {
styleArr: [
{
color: "orange",
backgroundColor: "#ffcfad"
},
{
fontSize:"20px",
border:"1px solid #000000"
}
]
}
条件渲染
1、v-show=""
字符串内是表达式,表达式结果是布尔值
<div v-show="isShow" class="basic">渲染</div>
2、v-if=""
用法与v-show=""
相同,区别是修改频率高的用v-show
,频率低的用v-if
另外v-if
还可以配合v-else-if
v-else
<div v-if="n==1">1</div>
<div v-else-if="n==1">2</div>
<div v-else>3</div>
注意:
v-if
、v-else-if
(可以多个)、v-else
必须是连续的,不能被打断,不然会报错
列表渲染
v-for="x in xxx"
<ul>
<li v-for="p in persons" :key="p.id">
编号:{{p.id}} 名字:{{p.name}} 年龄:{{p.age}}
</li>
</ul>
//Vue实例中
data: {
persons:[
{id:'001',name:'张三',age:18},
{id:'002',name:'李四',age:19},
{id:'003',name:'王五',age:21}
]
}
有两个参数,第一个是item第二个是索引下标index
<li v-for="(p,index) in persons" :key="index">
还可以遍历对象、字符串、数字(次数)
遍历对象是遍历对象的value值
<li v-for="(value,index) in person" :key="index">
{{value}}
</li>
key的作用和原理
1、虚拟DOM中key的作用:
key是虚拟DOM对象的标识,当数据发生变化时,Vue会根据【新数据】生成【新的虚拟DOM】;
2、对比规则:
(1).旧虚拟DOM中找到了与新虚拟DOM相同的key:
①.若虚拟DOM中内容没变,直接使用之前的真实DOM!
②.若虚拟DOM中内容变了,则生成新的真实DOM,随后替换掉页面中之前的真实DOM.
(2).旧虚拟DOM中未找到与新虚拟DOM相同的key
创建新的真实DOM,随后渲染到到页面。
3、用index作为key可能会引发的问题:
1,若对数据进行:逆序添加、逆序删除等破坏顺序操作:
会产生没有必要的真实DOM更新==>界面效果没问题,但效率低。
2.如果结构中还包含输入类的DOM:
会产生错误DOM更新 ==>界面有问题。
4、开发中如何选择key?:
1.最好使用每条数据的唯一标识作为key,比如id、手机号、身份证号、学号等唯一值。
2.如果不存在对数据的逆序添加、逆序删除等破坏顺序操作,仅用于渲染列表用于展示使用index作为key是没有问题的。
Vue.set()
Vue.set(target, propertyName/index, value)
等价于vm.$set()
target
: 目标对象或数组(需为响应式对象)
propertyName/index
: 属性名(对象)或索引(数组)
value
: 属性值
Vue.set(this.person, "school", "山东大学")
Vue.set(this.persons, this.persons.length, {name:'王五',age:21})
vm.$set(vm.persons,vm.persons.length,{name:'王五',age:21})
表单收集技巧
若:<input type="text"/>
,则v-model
收集的是value
值,用户输入的就是value
值;
若:<input type="radio"/>
,则v-model
收集的是value
值,且要给标签配置value
值;
若:<input type="checkbox"/>
1.没有配置input
的value
属性,那么收集的就是checked
(勾选or未勾选,是布尔值)
2.配置input
的value
属性:
(1)v-model
的初始值是非数组,那么收集的就是checked
(勾选or 未勾选,是布尔值)
(2)v-model
的初始值是数组,那么收集的的就是value
组成的数组
备注:v-model
的三个修饰符:
lazy
:失去焦点再收集数据
number
:输入字符串转为有效的数字
trim
:输入首尾空格过滤
推荐个第三方库地址:https://www.bootcdn.cn/
过滤器
过滤器语法:参数 | 过滤器
、参数 | 过滤器 | 过滤器
,可以写多个过滤器,第二个过滤器的参数是第一个过滤器的返回值;
<div>现在是:{{time | timeFormater('YYYY-MM-DD HH:mm:ss') | slice}}</div>
局部过滤器
filters: {
timeFormater(value, mater = 'YYYY-MM-DD HH:mm:ss') {
return dayjs(value).format(mater)
},
slice(value) {
return value.slice(0, 10)
}
}
全局过滤器
Vue.filter('slice', function (value) {
return value.slice(0, 10)
})
注意:过滤器可以用在插值语法和
v-bind
上
其他内置指令
前面学过整理下:
指令 | 说明 |
---|---|
v-bind |
单向绑定解析表达式,可简写为::x="表达式"
|
v-model |
双向数据绑定 |
v-for |
遍历数组/对象/字符串 |
v-on |
绑定事件监听,可简写为@
|
v-if 、v-else
|
条件渲染(动态控制节点是否存在) |
v-show |
条件渲染(动态控制节点是否展示) |
一、v-text
与插值语法一致,但没有插值语法灵活,会整个替换text的内容
<div>{{name}}</div>
<div v-text="name"></div>
注意:
v-text
会把所有的字符串当做正常字符串处理,内嵌标签不会解析成标签。
二、v-html
可以将内嵌标签解析成标签
str:'<h1>你好啊</h1>'
<div v-text="str"></div>
<div v-html="str"></div>
注意:
v-html
有安全性问题
1、在网站上动态渲染任意HTML是非常有危险的,容易导致CSS攻击;
2、一定要在可信的内容上使用v-html
,永远不要用在用户提交的内容上。
三、v-cloak
当vue还没有接管,插值语法还没有返回值的时候,使用v-cloak
配合CSS可以隐藏标签;
当vue接管,插值语法有值的时候,vue会自动删除v-cloak
[v-cloak] {
display: none;
}
<div v-cloak>现在是:{{time | timeFormater('YYYY-MM-DD HH:mm:ss') | slice}}</div>
注意:
1、SPA 项目:通常无需使用,可通过 v-text 或加载动画替代。
2、优先级问题:若样式被覆盖,可通过 !important 强制生效。
3、Vue 3 兼容性:Proxy 已解决动态响应问题,v-cloak 使用频率降低。
四、v-once
只允许插值语法执行一次
<div v-once>{{name}}</div>
五、v-pre
跳过其所在节点的编译过程;
用于没有使用指令语法,没有使用插值语法的节点,会加快编译。
<div v-pre>{{name}}</div>//解析结果{{name}}
自定义指令
使用directives
自定义指令;
指令接收两个参数:
element
:指令绑定的原生 DOM 元素,即div
binding
:包含 value
(绑定值)、arg
(参数)、modifiers
(修饰符)等
函数形式
<div v-big="n+1"></div>
n:10,
directives: {
big(element, binding) {
element.innerText = binding.value * 10
}
}
对象形式,相比函数形式,函数形式是简写形式,相当于省略了inserted
时机
fbind: {
//指令与元素绑定时
bind(element, binding) {
element.value = binding.value
},
//指令所在元素被插入页面时
inserted(element, binding) {
element.focus()
},
//指令所在模版被重新解析时
update(element, binding) {
element.value = binding.value
}
}
全局指令
Vue.directive('big', function (element, binding) {
element.innerText = binding.value * 10
})
注意:指令命名如果需要多个单词不要用驼峰形式,会报错,官方建议用下划线连接,定义的时候写成字符串形式即可。