模板语法
一、概要
Vue.js 使用了基于 HTML 的模板语法,允许开发者声明式地将 DOM 绑定至底层 Vue 实例的数据。所有 Vue.js 的模板都是合法的 HTML ,所以能被遵循规范的浏览器和 HTML 解析器解析。
在底层实际上是,Vue将模板编译成虚拟DOM渲染函数。结合响应系统,Vue能够智能的计算出最少需要重新渲染多少组件,并把DOM操作次数减少到最少
二、插值
1、说明
将数据插入到html文档中,包含 文本、html元素、元素属性等相当于我们Jquery里的DOM操作
2、文本插值
-
说明
文本插值中用得最多的就是用双大括号
{{变量}}
的形式 -
示例代码
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="html" cid="n17" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background: rgb(51, 51, 51); position: relative !important; padding: 10px 10px 10px 30px; width: inherit;"><div id="app">
<h1>{{title}}</h1>
</div>
<script>
new Vue({
el: "#app",
//数据绑定区
data: {
title: "就是这么简单",
},
});
</script> </pre>
3、HTML插值
-
说明
是在HTML标签中插入内容,被插入的内容都会被当做 HTML 数据绑定会被忽略。语法格式 v-html="变量" 的方式
-
示例代码
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="html" cid="n25" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background: rgb(51, 51, 51); position: relative !important; padding: 10px 10px 10px 30px; width: inherit;"><div id="app">
<p v-html="msg"></p>
</div>
<script>
new Vue({
el: "#app",
data: {
msg: "<span>在标签中插入的内容</span>",
}
})
</script></pre> -
渲染效果图
-
注意
你不能使用
v-html
来复合局部模板,因为 Vue 不是基于字符串的模板引擎。组件更适合担任 UI 重用与复合的基本单元
三、其它指令(v-)
1、说明
指令 (Directives) 是带有
v-
前缀的特殊属性当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM
语法格式 v-指令 : [参数.[修饰符] ]= "值", 大部分指令接受一个参数,值的话就是Vue实例data中的变量,也支持简单js表达式
2、v-text
-
说明
更新元素的的内容,作用等同于{{ }}
-
语法格式
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="vue" cid="n45" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background: rgb(51, 51, 51); position: relative !important; padding: 10px 10px 10px 30px; width: inherit;">v-text="val"</pre>
-
参数说明
对应Vue对象中的中data的属性
-
示例代码
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="html" cid="n51" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background: rgb(51, 51, 51); position: relative !important; padding: 10px 10px 10px 30px; width: inherit;"><div id="app">
<p>价格:{{ price }}</p>
<p v-text="'价格:' + price"></p>
</div>
<script>
let vm = new Vue({
el: "#app",
data: {
price: 99.00,
}
})
</script>
</pre> -
注意
在Vue中要想输出字符串,必须添加单引号,否则会报错。比如
<h1 v-text="'文本内容:' +text"></h1>
。{{}}
代表的就是""
,所以在v-text=""
中,我们在内容里面就不需要再写{{}}
了,直接写数据属性就行了。
-
区别
{{text}}:将数据解析为纯文本,不能输出真正的html,在页面加载时显示{{}},所以通常使用v-html和v-text代替,且花括号方式在以后可能被取消
v-html="html":输出真正的html
v-text="text":将数据解析为纯文本,不能输出真正的html,与花括号的区别是在页面加载时不显示{{}}
3、v-bind
-
说明
当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM
-
语法格式
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="vue" cid="n75" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background: rgb(51, 51, 51); position: relative !important; padding: 10px 10px 10px 30px; width: inherit;">v-bind:property="val"
// 或者简写方式
:property="val"</pre> -
参数
-
property
html元素的属性
-
val
对应vue对象里的data的变量名
-
-
示例代码
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="html" cid="n87" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background: rgb(51, 51, 51); position: relative !important; padding: 10px 10px 10px 30px; width: inherit;"><div id="app">
<a v-bind:href="url" v-text="content"></a>
<a :href="url" v-text="content"></a>
<img :img="img" >
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
content:"百度一下",
url: 'https://www.baidu.com',
img:"http://ts.51ui.cn/pc/9-160Q2215F4.jpg"
}
})
</script></pre> -
后接值
对于
v-bind:
后接的属性值,不同的表单控件是不同的,如:input的checkbox,使用
true-value
和false-value
input的radio,使用
pick
select的情况下,使用
selected
其他的文本类,使用
value
4、v-on
-
说明
给元素绑定事件,绑定的事件从
methods
中获取. -
语法格式
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="vue" cid="n107" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background: rgb(51, 51, 51); position: relative !important; padding: 10px 10px 10px 30px; width: inherit;">v-on:event="fun"
// or
v-on:event="fun(param,...)"
// or 简写方式
@event="fun"
//绑定多个事件,多个事件以‘,’号隔开
v-on={event:fun,event:fun,....}</pre> -
参数说明
-
event
事件名
-
fun
定义在vue对象里methods里的方法,如果方法没有参数,可以省略()
-
param
方法中的参数
-
-
备注
常见的事件有@click ,@focus,@blur,@submit,@mousemove,@mouseleave,@mouseout等
-
示例代码
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="html" cid="n126" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background: rgb(51, 51, 51); position: relative !important; padding: 10px 10px 10px 30px; width: inherit;"><div id="app">
<p>
<span v-text="'价格:' + price"></span>
<span v-text="'数量:' + num"></span>
</p>
<button v-on:click="btn">结算</button>
<button @click="btn">结算</button>
<p>小计: {{ total }}</p>
<button @click="multip(num,price)">传递参数</button>
</div>
<script>
new Vue({
el: '#app',
data: {
total: 0,
num: 1,
price: 20.00,
numbers: 1
},
methods: {
btn: function () {
this.total = this.num * this.price
},
multip: function (num, price) {
this.total=num * price
}
}
})
</script></pre> -
事件修饰符
.stop
阻止冒泡,调用 event.stopPropagation().prevent
阻止默认事件,调用 event.preventDefault().capture
添加事件侦听器时使用事件捕获模式.self
只当事件在该元素本身(比如不是子元素)触发时触发回调.once
事件只触发一次
-
示例代码
<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="html" cid="n142" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background: rgb(51, 51, 51); position: relative !important; padding: 10px 10px 10px 30px; width: inherit;">
<button @click.stop="do"></button>
<button @click.prevent="do"></button>
<form @submit.prevent></form>
<button @click.stop.prevent="do"></button>
<button v-on:click.once="do"></button></pre>
5、v-model
-
说明
在表单元素上创建双向数据绑定, 监听用户的输入事件以更新数据
v-model会忽略所有表单元素的value/checked/selected特性的初始值,应该通过js在组件的data中声明初始值
-
语法格式
<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="" cid="n151" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background: rgb(51, 51, 51); position: relative !important; padding: 10px 10px 10px 30px; width: inherit;">v-model="val"</pre>
-
参数
- val
-
示例代码
<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="html" cid="n159" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background: rgb(51, 51, 51); position: relative !important; padding: 10px 10px 10px 30px; width: inherit;"><div id="app">
<span v-text="msg"></span>
<input type="text" v-model="msg">
</div><script>
new Vue({
el: "#app",
data: {
msg: "msg",
}
})
</script></pre> -
修饰符
-
lazy
v-model.lazy:自动延迟事件作用
-
number
v-model.number:自动将用户输入的值转为Number类型
-
trim:
v-model.trim:自动过滤用户输入的首尾空格
-
6、v-for
-
说明
当需要将一个数组或者对象循环遍历显示的时候可以使用v-for指令
也支持用在templete(包裹元素)元素上的,以此来进行多个元素的渲染
-
语法格式
<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="" cid="n180" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background: rgb(51, 51, 51); position: relative !important; padding: 10px 10px 10px 30px; width: inherit;">// 遍历数组 index 可选
v-for = "item in items"
v-for = "(item,[index]) in items"
// 遍历对象
v-for =" (item,[key],[index]) in items"</pre> -
参数说明
-
括号及其内的遍历结果信息(item, key, index)
item 是遍历得到的属性值,key 是遍历得到的属性名,index 是遍历次序,这里的 key/index 都是可选参数,如果不需要,这个指令其实可以写成 v-for="item in items";
-
遍历关键词 in
in 可以使用 of 替代,官方的说法是它是最接近 JavaScript 迭代器的语法,但其实使用上并没有任何区别;
-
被遍历对象items
items 是绑定在实例 data 属性上的一个属性
-
-
示例代码
<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="html" cid="n195" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background: rgb(51, 51, 51); position: relative !important; padding: 10px 10px 10px 30px; width: inherit;">
<div id="app">
<p v-for="(item,index) in nums">
{{index + ' : ' + item}}
</p>
<p v-for="(item, key, index) in user">
{{index + ' : ' + key + ' : ' + item}}
</p>
<p v-for="item in name">
{{item}}
</p>
<p v-for="item in num">
{{item}}
</p>
</div>
<script>
new Vue({
el: '#app',
data: {
nums: [10, 20, 30, 40, 50],
user: {name: '娇娇', age: 18},
name: '小明',
num: 4
}
})
</script></pre><pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="html" cid="n196" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background: rgb(51, 51, 51); position: relative !important; padding: 10px 10px 10px 30px; width: inherit;">
<div id="app">
<ul>
<li v-for="num in nums">
<p v-text="num"></p>
</li>
</ul>
</div><script>
let app = new Vue({
el: '#app',
data: {
nums: [10, 20, 30, 40, 50],
}
})
</script></pre> -
增强数组更新的方法
Vue 包含一组观察数组的变异方法,所以它们也将会触发视图更新
-
push()
向数组的末尾添加一个或更多元素
-
pop()
删除并返回数组的最后一个元素
-
shift()
数组的第一个元素从其中删除
-
unshift()
向数组的开头添加一个或更多元素
-
splice()
向/从数组中添加/删除
-
sort()
对数组的元素进行排序
-
reverse()
颠倒数组中元素的顺序
注意: 通过数组下标来修改或者添加是无效的,页面不会重新渲染,即使数据已经改变了。
<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="" cid="n224" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background: rgb(51, 51, 51); position: relative !important; padding: 10px 10px 10px 30px; width: inherit;">app.numbs.push(6)
其它方法跟js的数组操作方法一样</pre>
-
-
关于设置key
使用
v-for
更新已渲染的元素列表时,默认使用复用策略;当列表数据修改的时候,他会根据key值去判断某个值是否修改,如果修改,则重新渲染这一项,否则复用之前的元素;<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="html" cid="n228" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background: rgb(51, 51, 51); position: relative !important; padding: 10px 10px 10px 30px; width: inherit;"><div id="app">
<ul>
<li v-for="(shop,index) in shops" :key="shop.id" >
<p v-text="index + shop.name"></p>
</li>
</ul>
</div>
<script>
let app = new Vue({
el: '#app',
data: {
shops: [
{
id: 1,
name: "Apple iPhone XS Max"
},
{
id: 2,
name: "小米8"
},
]
}
})</pre>
7、v-if
-
说明
v-if
是条件渲染指令,它根据表达式的真假来删除和插入元素 -
语法格式
<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="vue" cid="n236" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background: rgb(51, 51, 51); position: relative !important; padding: 10px 10px 10px 30px; width: inherit;">v-if="expression"
v-else-if="expression"
v-else</pre> -
参数说明
-
expression
是一个返回bool值的表达式,表达式可以是一个bool属性,也可以是一个返回bool的运算式
-
-
示例代码
<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="html" cid="n245" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background: rgb(51, 51, 51); position: relative !important; padding: 10px 10px 10px 30px; width: inherit;"><div id="app">
<!--登录成功后显示--> <div v-if="isLogin"> <p v-text="user.name"></p> </div> <!--未登录显示--> <div v-else> <a href="#">登录</a> <a href="#">注册</a> </div>
</div>
<script>
let app = new Vue({
el: "#app",
data: {
isLogin: false,
user: {
name: 'vue'
},
}
})
</script></pre>
8、v-show
-
说明
与v-if语句一样都是简单的理解都是用来做显示隐藏元素,
vue-show通过标签display属性设置为none,控制隐藏,
v-if动态的向DOM树内添加或者删除DOM元素
-
语法格式
<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="" cid="n255" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background: rgb(51, 51, 51); position: relative !important; padding: 10px 10px 10px 30px; width: inherit;">v-show="expression"</pre>
-
参数说明
是一个返回bool值的表达式,表达式可以是一个bool属性,也可以是一个返回bool的运算式
-
示例代码
<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="html" cid="n261" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background: rgb(51, 51, 51); position: relative !important; padding: 10px 10px 10px 30px; width: inherit;"><div id="app">
<h1 v-show="ok">条件为TRUE,输出</h1>
<h1 v-show="error">条件为false,不输出</h1>
<h1 v-show="10>5">10大于5,输出!</h1>
<h1 v-show="2>10">不大于10,不输出!</h1>
</div>
<script>
new Vue({
el: '#app',
data: {
ok: true,
error: false
}
})
</script></pre> -
区别
1、实现本质方法区别
vue-show本质就是标签display设置为none,控制隐藏
vue-if是动态的向DOM树内添加或者删除DOM元素
2、编译的区别
v-show其实就是在控制css
v-if切换有一个局部编译/卸载的过程,切换过程中合适地销毁和重建内部的事件监听和子组件
3、编译的条件
v-show都会编译,初始值为false,只是将display设为none,
v-if初始值为false,就不会编译了
4、性能
- v-show只编译一次,后面其实就是控制css,而v-if不停的销毁和创建,故在某些情况下v-show性能更好一点。
9、v-once
-
说明
只渲染元素和组件一次,当数据改变时,插值处的内容不会继续更新,使用了此指令的元素/组件及其所有的子节点,不会在渲染,这可以用于优化更新性能
-
语法格式
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n293" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background: rgb(51, 51, 51); position: relative !important; padding: 10px 10px 10px 30px; width: inherit;">v-once</pre>
-
示例代码
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="html" cid="n296" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background: rgb(51, 51, 51); position: relative !important; padding: 10px 10px 10px 30px; width: inherit;"><div id="app">
<p v-text="msg"></p>
<p v-once v-text="'v-once:' + msg"></p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var vm = new Vue({
el: "#app",
data: {
msg: '先定个小目标,一天撸1万行代码'
}
})
</script></pre>