一、模板语法
Vue 使用一种基于 HTML 的模板语法,使我们能够声明式地将其组件实例的数据绑定到呈现的 DOM 上。所有的 Vue 模板都是语法层面合法的 HTML,可以被符合规范的浏览器和 HTML 解析器解析。
在底层机制中,Vue 会将模板编译成高度优化的 JavaScript 代码。结合响应式系统,当应用状态变更时,Vue 能够智能地推导出需要重新渲染的组件的最少数量,并应用最少的 DOM 操作。
二、插值
2.1 文本
最基本的数据绑定形式是文本插值,它使用的是“Mustache”语法 (即双大括号):
<div id="app">{{ message }}</div> </body> <script type="text/javascript"> new Vue({ el:'#app', data() { return { message: 'Hello Vue!' } } }) </script>
双大括号标签会被替换为相应组件实例中 message属性的值。同时每次 message 属性更改时它也会同步更新。
2.2 原始 HTML
若想插入 HTML,你需要使用 v-html 指令:
<div v-html='html'></div> html:'<p style="color:red;">我是红色的Hello Vue</p>'
这里看到的 v-html
attribute 被称为一个指令。指令由 v- 作为前缀,表明它们是一些由 Vue 提供的特殊 attribute
2.3 表达式
Vue 实际上在所有的数据绑定中都支持完整的 JavaScript 表达式:
<p>表达式</p> {{ number + 1 }} {{ ok ? 'YES' : 'NO' }} {{ message.split('').reverse().join('') }} //--------------------------------- data() { return { message: 'Hello Vue!', html:'<p style="color:red;">我是红色的Hello Vue</p>', number:5, ok:'YES' } }
2.4 样式绑定
一个是class,一个是style:
.f200{ font-size: 200px; } <p>样式绑定</p> <p :class="font" :style="color">{{message}}</p> color:'color:yellow', font:'f200'
全部代码:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title></title> <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.10/vue.js"></script> <style> .f200{ font-size: 200px; } </style> </head> <body> <div id="app"> <p>{{ message }}</p> <div v-html='html'></div> <p>表达式</p> {{ number + 1 }} {{ ok ? 'YES' : 'NO' }} {{ message.split('').reverse().join('') }} <p>样式绑定</p> <p :class="font" :style="color">{{message}}</p> </div> </body> <script type="text/javascript"> new Vue({ el:'#app', data() { return { message: 'Hello Vue!', html:'<p style="color:red;">我是红色的Hello Vue</p>', number:5, ok:'YES', color:'color:yellow', font:'f200' } } }) </script> </html>
三、指令
指令是带有 v- 前缀的特殊 attribute。Vue 提供了许多内置指令,包括上面我们所介绍的 v-bind 和 v-html。
3.1 v-if/v-else/v-else-if
v-if|v-else|v-else-if:根据其后表达式的bool值进行判断是否渲染该元素,他们只能是兄弟元素v-else-if上一个兄弟元素必须是v-if,v-else上一个兄弟元素必须是v-if或者是v-else-if
<body> <div id="app"> <p>v-if/v-else/v-else-if</p> 分数:<input v-model="score" /> <div v-if="score>=80">优秀</div> <div v-else-if="score>60">良好</div> <div v-else="score<60">辣鸡</div> </div> </body> <script type="text/javascript"> new Vue({ el:'#app', data() { return { score:33 } } }) </script>
()/v-show/v-for/v-bind/v-on/v-model
3.2 v-show
与v-if类似,只是会渲染其身后表达式为false的元素,而且会给这样的元素添加css代码:style=“display:none”
<p>v-show</p> <div v-show="score>=90">牛逼</div>
3.3 v-for
类似JS的遍历,
- 遍历数组: v-for=“item in items”, items是数组,item为数组中的数组元素
- 遍历对象: v-for=“(value,key,index) in stu”, value属性值,key属性名,index下标
<p>v-for</p> <select v-model="hobbySelected"> <option v-for="h in hobby" :value="h.id">{{h.name}}</option> </select> <div v-for="h in hobby"> <input :value="h.id" type=checkbox />{{h.name}} </div> hobby:[ {id:"1",name:"唱"}, {id:"2",name:"跳"}, {id:"3",name:"rap"}, {id:"4",name:"篮球"} ], hobbySelected:4
3.4 v-model
用来在 input、select、textarea、checkbox、radio 等表单控件元素上创建双向数据绑定,根据表单上的值,自动更新绑定的元素的值。
<div id="app"> <button @click="add">count is: {{ count }}</button> </div> <script type="text/javascript"> new Vue({ el:'#app', data() { return { count:0 } }, methods: { add() { this.count++ } } }) </script>
四、过滤器
全局过滤器 Vue.filter('filterName', function (value) { // value 表示要过滤的内容 });
局部过滤器 new Vue({ filters:{'filterName':function(value){}} });
<body> <!-- 定义边界 --> <div id="app"> {{msg|all}},{{msg|single}},{{msg|all|single}},{{msg|param(4,5)}} </div> </body> <script type="text/javascript"> // 全局过滤器 Vue.filter('all', function(value) { return value.substring(1, 4); }); // 绑定边界 new Vue({ el: '#app', data() { return { msg:"Java最牛" }; }, filters:{ 'single':function(val){ return val.substring(2,3); }, 'param':function(val,start,end){ return val.substring(start,end); } } }) </script>
五、监听、计算属性
5.1 监听属性
我们可以通过 watch选项 来响应数据的变化
<body> <div id="app"> <p>监听属性</p> 千米:<input v-model="km" /> 米:<input v-model="m" /> </div> </body> <script type="text/javascript"> new Vue({ el:'#app', data() { watch:{ // v指的是m变量 m: function(v){ this.km = parseInt(v)/1000; }, // v指的是km变量 km: function(v){ this.m = parseInt(v)*1000; } } } }) </script>
5.2 计算属性
计算属性。我们可以使用 computed 选项声明一个响应式的属性,它的值由其他属性计算而来:
<!DOCTYPE html> <html> <head> <title>购物车</title> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script> </head> <body> <div id="app"> <table> <thead> <tr> <th>商品</th> <th>价格</th> <th>数量</th> <th>小计</th> </tr> </thead> <tbody> <tr v-for="(item, index) in cartItems" :key="index"> <td>{{ item.name }}</td> <td>{{ item.price }}</td> <td> <div class="quantity-input"> <button @click="decrementQuantity(item)">-</button> <input type="number" v-model="item.quantity" @change="updateSubtotal(item)"> <button @click="incrementQuantity(item)">+</button> </div> </td> <td>{{ item.subtotal }}</td> </tr> </tbody> <tfoot> <tr> <td colspan="3">总计</td> <td>{{ total }}</td> </tr> </tfoot> </table> </div> <script> new Vue({ el: '#app', data: { cartItems: [ { name: '商品1', price: 10, quantity: 1, subtotal: 10 }, { name: '商品2', price: 20, quantity: 2, subtotal: 40 }, { name: '商品3', price: 30, quantity: 3, subtotal: 90 } ] }, computed: { total: function() { return this.cartItems.reduce((sum, item) => sum + item.subtotal, 0); } }, methods: { updateSubtotal: function(item) { item.subtotal = item.price * item.quantity; }, incrementQuantity: function(item) { item.quantity++; this.updateSubtotal(item); }, decrementQuantity: function(item) { if (item.quantity > 1) { item.quantity--; this.updateSubtotal(item); } } } }); </script> </body> </html>