Vue中的指令
{{ }} 被称作大胡子语法、双花括号语法,在 Vue 的使用中很常见
可以存放变量名,存放表达式( 一些运算,只要最终的结果 )
{{x+y}}
<h1>Hello,{{title}}</h1>
但是它有着自身的局限性,只允许出现在内容区域,怎么办?!
我想改 class类名! 想改id名!想改属性名!
Vue 指令
为迎合属性(类名,id,name)变化的需要,Vue 提供了 指令
指令 (Directives) 是特殊的带有前缀 v- 的特性。指令的值限定为绑定表达式
- 指令格式
v-指令名称 = 表达式(不是普通的字符串)
v-text
操作,修改 文本内容
这个方法有一个弊端,会替换掉所有的内容,相当于innerHTML
<h2 v-text="title"></h2>
v-html
为了防止 xss 攻击,默认情况下输出是不会作为 html 解析的 ( 不使用 v-html 就是普通的字符串 )
使用之后 将内容当作一个html标签来解析
覆盖原有的文本内容
<div id="app">
<p v-html="content">测试v-html</p>
</div>
<script>
let app = new Vue({
el:"#app",
data:{
content:"<style>body{color:purple} </style>"
}
})
</script>
v-cloak ( 不需要表达式 )
编译完成才会生效,很少使用的指令
编译结束时效果生效
v-once ( 不需要表达式 )
只渲染生效一次 之后无论再怎么修改都不再改变
<div id="app">
<div v-once>
<p>{{num}}</p>
</div>
</div>
<script>
let app = new Vue({
el:"#app",
data:{
num:"我不变的,你可劲儿改"
}
})
</script>
v-pre ( 不需要表达式 )
直接忽略不加载
标签所在的范围内,全部失效( 视为字符串 )
<div v-pre>
<p>{{title}}</p>
<p>{{num}}</p>
</div>
v-show
控制显示隐藏 ( 操控 display 属性 ) 适用于变化频繁的场景
例如:轮播图
<div v-show="isLogin" > 机密文件 </div>
v-if
创建 / 销毁元素 ( 页面上就不存在 ) 适用于变换不频繁的场景
例如:购物车商品 添加 / 删除
<div v-if="isLogin"> 绝密文件 </div>
v-else
作为 v-if 的结束指令,不可单独存在(否则直接报错)
通常与 v-if 或者 v-else-if
<div v-else> 公开文件 </div>
注意
v-if / v-else-if 及 v-else 之间
不能出现其他的元素
<div id="app">
<div v-show="isLogin" > 机密文件 </div>
<div v-if="isLogin"> 绝密文件 </div>
<div v-else> 公开文件 </div>
<!--
v-if / v-else-if 及 v-else 之间
不能出现其他的元素
-->
</div>
<script>
/**
* v-show 切换元素的显示与隐藏(display 属性)
* v-if 改变的是元素的结构(渲染或删除)
**/
let app = new Vue({
el:"#app",
data:{
isLogin:false
}
})
</script>
v-for
指令中的循环
<div id="app">
<ul>
<!-- of / in 没有实际的区别 -->
<li v-for="user of users">
<input type="checkbox" name="" id="">
{{user.id}} - {{user.name}}
</li>
</ul>
<div v-for="(val,name,index) in object">
<span>索引值:{{index}}</span>
<span>属性名:{{name}}; 值:{{val}}</span>
</div>
</div>
<script>
let app = new Vue({
el:"#app",
data:{
users:[
{id:1,name:"秦"},
{id:2,name:"兟"},
{id:3,name:"秦兟"},
{id:4,name:"秦侁"}
],
object:{
x:"a",
y:"b",
z:"c"
}
}
});
</script>
- 出现这种情况的原因
模板数据传递给 虚拟dom优化处理 然后加载到 HTML( 模板 => Vdom => html )
问题就出在虚拟dom中 每次加载过后,会留一份缓存备份,再次加载时会自行对比前后数据
只加载不同的数据 复选框没有变化,不会重新渲染 - 处理办法
: key 使得数据绑定
<li v-for="user of users" :key="user.id">
<input type="checkbox" name="" id="">
{{user.id}} - {{user.name}}
</li>
属性绑定
- 语法:
v-指令名称 : 参数 = "指令的值"
等号后不是字符串 ,是表达式( 我们需要的是结果 ) - 简写:
v-bind => :
<div id="app">
<div v-bind:class="myclass">v-bind 全写</div>
<div :class="myclass">:简写</div>
<div :id="ID"></div>
</div>
<script>
let app = new Vue({
el:"#app",
data:{
myclass:'box',
ID:"QAQ"
}
});
</script>
属性绑定样式
<div id="app">
<!-- v-bind 简写为 : -->
<div :style="style"></div>
<!--
"style" 不再是简单的字符串
而是成为了一个存储样式的空间
-->
</div>
<script>
let app = new Vue({
el:"#app",
data:{
style:{
width:"120px",
height:"120px",
background:"green"
}
}
});
</script>
- 数组的写法
<div id="app">
<div :style="[box1,box2]"></div>
<!-- 数组写法
拿到的数组中全部元素 的所有属性
"[]" 中就变成了一块儿空间
-->
</div>
<script>
let app = new Vue({
el:"#app",
data:{
box1:{
width:"100px",
height:"100px",
background:"lightblue"
},
box2:{
border:"1px solid red"
}
}
});
</script>
- 对象的写法
<style>
.try1{
width: 100px;
height: 100px;
background-color: red;
}
.try2{
width: 200px;
height: 200px;
opacity: 0.6;
}
</style>
<div id="app">
<div :class="{'try1':new_class,'try2':old_class}"></div>
<!-- 对象写法
控制属性的开启关闭
:new_class :old_class 用来存储 true / false
-->
</div>
<script>
let app = new Vue({
el:"#app",
data:{
new_class:true,
old_class:false
}
});
</script>
注意
: class 获取具体的类名 :style 获取具体的样式
数据流
数据的流向,我理解为数据传递的方向
数据影响视图,还是视图影响数据,或者相互影响
双向数据绑定:v-model
数据 => 视图 ,视图 => 数据
- 不是所有的标签都支持 v-model
---- 默认 交互元素 ( input / textarea / select ) - 不是所有的属性都支持 v-model
---- v-model 只能绑定一个指定好的属性
input:value
textarea : value
select :selected
非交互 : div / p / img 静态类标签(不需要统计信息)
<div id="app">
<!-- 双向数据绑定 -->
<input type="text" v-model="msg">
<div>{{msg}}</div>
</div>
<script>
let app = new Vue({
el:"#app",
data:{
msg:"生活的乐趣"
}
});
</script>
单项数据流
数据 => 视图
<div id="app">
<!-- 单项数据绑定 -->
<input type="text" :value="msg2"></br>
<span>{{msg2}}</span>
</div>
<script>
let app = new Vue({
el:"#app",
data:{
msg2:"挣钱"
}
});
</script>