Vue.js使用了基于HTML的模板语法,允许开发者声明式地将DOM绑定至底层Vue实例的数据。所有Vue.js的模板都是合法的HTML,所以能被遵循规范的浏览器和HTML解析器解析。
在底层的实现上,Vue将模板编译成虚拟DOM渲染函数。结合响应系统,Vue能够智能地计算出最少需要重新渲染多少组件,并把DOM操作次数减到最少。
简单的说:Vue模板语法就是前端渲染,前端渲染即是把数据填充到html标签中。数据(来自服务器)+模板(html标签)=前端渲染(产物是静态html内容)。
插值
插值就是将数据插入到 html 文档中,包含文本、html 元素、元素属性等。
1. 文本插值
文本插值中用得最多的就是用双大括号的形式
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> </head> <body> <div id="app"> <!-- 会与实例中的【data】中的属性绑定在一起,并且数据实现同步--> <h1>{{ message }}</h1> </div> <script> // Vue所做的工作也就是把数据填充把页面的标签里面。 var vm = new Vue({ el: "#app", // data模型数据,值是一个对象。 data: { message: "I LOVE YOU" } }) </script> </body> </html>
上面代码中当 data 中的值更新之后我们不需要操作 html,页面中会自动更新数据。 我们也可以让数据只绑定一次,在以后更新 data 中的属性时不再更新页面数据
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> </head> <body> <div id="app"> <!-- v-once只编译一次。显式内容之后不再具有响应式功能。 --> <!-- v-once的应用场景,如果显式的信息后续不需要再修改,可以使用v-once指令,可以可以提高性能,因为Vue就不需要去监听它的变化了。 --> <h1 v-once>{{message}}</h1> </div> <script> // Vue所做的工作也就是把数据填充把页面的标签里面。 var vm = new Vue({ el: "#app", // data模型数据,值是一个对象。 data: { message: "I LOVE YOU" } }) </script> </body> </html>
2. HTML 插值
双大括号会将数据解释为普通文本,而非 HTML 代码。为了输出真正的 HTML,你 需要使用 v-html
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> </head> <body> <div id="app"> <!-- 内容按普通 HTML 插入 - 不会作为 Vue 模板进行编译,在网站上动态渲染任意 HTML 是非常危险的,因为容易导致 XSS 攻击 --> <h1 v-html="msg"></h1> </div> <script> var vm = new Vue({ el: "#app", data: { msg: "<span style='color:blue'>BLUE</span>"//可以使用v-html标签展示html代码。 } }) </script> </body> </html>
3. 属性插值 在开发的时候,有时候我们的属性不是写死的,有可能是根据我们的一些数据动态地决 定的,比如图片标签(<img>)的 src 属性,我们可能从后端请求了一个包含图片地址的数 组,需要将地址动态的绑定到 src 上面,这时就不能简单的将 src 写死。还有一个例子就是 a 标签的 href 属性。这时可以使用 v-bind:指令,其中,v-bind:可以缩写成:
使用 v-bind:指令绑定属性 <!DOCTYPE html> <html xmlns:v-bind="http://www.w3.org/1999/xhtml"> <head lang="en"> <meta charset="UTF-8"> <title>aa</title> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> </head> <body> <div id="app"> <img v-bind:src="imgUrl" alt=""/> <a :href="searchUrl">百度一下</a> </div> </body> <script> var vm = new Vue({ el: "#app", data: { imgUrl:'F://vuewk//src//assets//1.jpg', searchUrl:'http://www.baidu.com' } }) </script> </html>
服务器请求过来的数据,我们一般都会在 data 那里做一下中转,做完中转过后再把需 要的变量绑定到对应的属性上面。
v-bind 除了在开发中用在有特殊意义的属性外(src, href 等),也可以绑定其他一些 属性,如 Class 与 Style 绑定
<!DOCTYPE html> <html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml" > <head> <meta charset="UTF-8"> <title>v-bind动态绑定属性class</title> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> </head> <body> <div id="app"> <p :class="{fontCol:isName,setBack:!isAge}" class="weight">{{name}}</p> <i :class="addClass">{{name}}真好看!</i> </div> <script> var vm = new Vue({ el:"#app", // 条件比较少 data:{ isName:true, isAge:false, name:"功守道" }, //当v-bind:class的表达式过长或者逻辑复杂(一般当条件多于两个的时候),可以考虑采用计算属性,返回一个对象 computed:{ addClass:function(){ return { checked:this.isName&&!this.isAge } } } }) </script> </body> </html>
既然是一个对象,那么该对象内的属性可能不唯一,但总是每一项为真的时候,对应的 类名就会存在。通过 v-bind 更新的类名和元素本身存在的类名不冲突,可以优雅的共存
v-bind 动态绑定属性 style <!DOCTYPE html> <html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml" > <head> <meta charset="UTF-8"> <title>v-bind动态绑定属性style</title> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> </head> <body> <div id="app"> <div :style="{'color': color,'fontSize':fontSize + 'px'}">修饰文本</div> </div> <script> var vm= new Vue({ el: "#app", data: { color: 'red', fontSize: 24 } }) </script> </body> </html>
大多情况下,标签中直接写一长串的样式不便于阅读和维护,所以一般写在 dada 或 computed 里,代码如下: <div id="app"> <div :style="{'color': color,'fontSize':fontSize + 'px'}">修饰文本</div> </div> <script> var vm= new Vue({1 el: "#app", data: { styles:{ color: 'red', fontSize: 24 } } }) </script>
应用多个样式对象时,可以使用数组语法 <!DOCTYPE html> <html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml" > <head> <meta charset="UTF-8"> <title>v-bind动态绑定属性style</title> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> </head> <body> <div id="app"> <div :style="[styleA,styleB]">文本</div> </div> <script> var vm=new Vue({ el: "#app", data: { styleA:{ color: 'red', fontSize: 24 + 'px' }, styleB: { width: 100 + 'px', border: 1 + 'px ' + 'black ' + 'solid' } } }) </script> </body> </html>
4. 插值中使用 Javascript 表达式 实际上,对 于所有的数据绑定,Vue.js 都提供了完全的 JavaScript 表达式支持 部分 表达式格式代码如下: {{ number + 1 }} {{ ok ? 'YES' : 'NO' }} {{ message.split('').reverse().join('') }} <div v-bind:id="'list-' + id"> </div> 这些表达式会在所属 Vue 实例的数据作用域下作为 JavaScript 被解析。有个限制就 是,每个绑定都只能包含单个表达式,所以下面的表达式都不会生效,代码如下: <!-- 这是语句,不是表达式 --> {{ var a = 1 }} <!-- 流控制也不会生效,请使用三元表达式 --> {{ if (ok) { return message } }}
使用 Javascript 表达式 <!DOCTYPE html> <html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml" > <head> <meta charset="UTF-8"> <title></title> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> </head> <body> <div id="app"> <p>{{ number + 1 }}</p> <hr> <p>{{msg + '~~~~~'}}</p> <hr> <p>{{flag ? '条件为真' : '条件为假'}}</p> <hr> </div> <script> var vm = new Vue({ el:'#app', data:{ msg:'Hello beixi!', flag:true, number:2 } }) </script> </body> </html>
指令 指令其实在上面我们已经使用过了【v-bind:】和【v-html】,指令就是值这些带有 v- 前 缀的特殊属性。 1.参数 一些指令能够接收一个“参数”,在指令名称之后以冒号表示。如 v-bind 指令可以用 于响应式地更新 HTML attribute,代码如下: <a v-bind:href="url">...</a> 在这里 href 是参数,告知 v-bind 指令将该元素的 href attribute 与表达式 url 的值绑定。 2.动态参数 从 2.6.0 开始,可以用方括号括起来的 JavaScript 表达式作为一个指令的参数,响应式 使得 vue 更加灵活多变,其动态参数也是有其含义的,代码如下: <a v-bind:[attributeName] = 'url'>...</a> 同样的,当 eventName 的值为‘focus’时,v-on:[eventName]将等价于 v-on:focus。
当然动态参数的值也是有约束的,动态参数预期会求出一个字符串,异常情况下值为 null。这个特殊的 null 值可以被显性地用于移出绑定。任何其他非字符串类型的值都将会触 发一个警告。 3.修饰符 修饰符(Modifiers)是以半角句号 . 指明的特殊后缀,用于指出一个指令应该以特殊 方式绑定。例如,.prevent 修饰符告诉 v-on 指令对于触发的事件调 event.preventDefault(), 代码如下: <form v-on:submit.prevent="onSubmit">...</form>
过滤器
过滤器分全局过滤器和局部过滤器,全局过滤器在项目中使用频率非常高。
定义过滤器
全局过滤器
Vue.filter('过滤器名称', function (value1[,value2,...] ) {
//逻辑代码
})
局部过滤器
new Vue({
filters: {
'过滤器名称': function (value1[,value2,...] ) {
// 逻辑代码
}
}
})
2. 过滤器使用的地方 Vue.js 允许你自定义过滤器,可被用于一些常见的文本格式化。过滤器可以用在两个 地方:双花括号插值和 v-bind 表达式 (后者从 2.1.0+ 开始支持)。过滤器应该被添加在 JavaScript 表达式的尾部,由“管道”符号指示,格式代码如下: <!-- 在双花括号中 --> <div>{{数据属性名称 | 过滤器名称}}</div> <div>{{数据属性名称 | 过滤器名称(参数值)}}</div> <!-- 在 v-bind 中 --> <div v-bind:id="数据属性名称 | 过滤器名称"></div> <div v-bind:id="数据属性名称 | 过滤器名称(参数值)"></div>
<!DOCTYPE html> <html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml" > <head> <meta charset="UTF-8"> <title></title> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> </head> <body> <div id="app"> <!--文本后边需要添加管道符号( | )作为分隔,管道符 | 后边是文本的处理函数,处理函数的第一个参数是:管道符前边的——文本内容,如果处理函数上边传递参数,则从第二个参数依次往后是传递的参数。--> <p>电脑价格:{{price | addPriceIcon}}</p> </div> <script> var vm = new Vue({ el:"#app", data:{ price:200 }, filters:{ //处理函数 addPriceIcon(value){ console.log(value)//200 return '¥' + value; } } }) </script> </body> </html>
<!DOCTYPE html> <html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml" > <head> <meta charset="UTF-8"> <title></title> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> </head> <body> <div id="app"> <!--过滤器接收多个参数--> <span>{{value1|multiple(value2,value3)}}</span> </div> <script> var vm = new Vue({ el: '#app', data: { msg: 'hello', value1:10, value2:20, value3:30 }, //局部过滤器 filters: { 'multiple': function (value1, value2, value3) { return value1*value2*value3 } } }) </script> </body> </html>
<!DOCTYPE html> <html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml" > <head> <meta charset="UTF-8"> <title></title> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> </head> <body> <div id="app"> <h3>{{viewContent | addNamePrefix}}</h3> </div> <script> /*addNamePrefix是过滤器的名字,也是管道符后边的处理函数;value是参数*/ Vue.filter("addNamePrefix",(value)=>{ return "my name is" + value }) var vm = new Vue({ el:"#app", data:{ viewContent:"贝西" } }) </script> </body> </html>