模板语法的插值操作
(1)v-html 往标签内部插入html文本;
(2)v-text 往标签内部插入普通文本(解析不了标签);
(3)v-pre 在界面上直接展示胡子语法;
(4)v-cloak 隐藏数据渲染到页面之前,胡子语法在界面上的展示。
代码如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <style> [v-cloak] { display: none; } </style> </head> <body> <div id="app"> <div v-html="htmlTxt"></div> <div v-text="textTxt"></div> <div v-pre>{{123}}</div> <div v-cloak>hello {{textTxt}}</div> </div> </body> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> let vm = new Vue({ el: '#app', data: { htmlTxt: '<p><strong>我是html</strong></p>', textTxt: 'Vue' } }) </script> </html>
v-for中的key属性
<div id="app"> <input type="text" v-model="txtVal"> <button @click="handleClick">按钮</button> <ul> <li v-for="i,k in list" :key="i"> <input type="checkbox"> {{ i }} </li> </ul> </div> <script> var vm = new Vue({ el:"#app", data:{ list:['html', 'css', 'javascript', 'jquery'], txtVal:"" }, methods:{ handleClick(){ this.list.unshift(this.txtVal) } } }) </script>
官方推荐我们使用v-for时,给对应的元素或组件添加一个key属性。
为什么需要这个key属性呢
(1)这个其实和Vue的虚拟DOM的Diff算法有关系。
当某一层有很多相同节点时,也就是列表节点时,我们插入一个新的节点到列表中
(2)在B和C之间加一个F,Diff算法默认执行起来时这样的:
即把C更新成F,D更新成C,E更新成D,最后再插入一个新的E,这样的效率也太低了。
编辑
编辑
当我们使用key来为每一个节点做唯一标识:Diff算法会以key作为标识来识别此节点,找到正确的位置区插入新的节点,所以key的作用是为了高效的更新虚拟DOM。
注意:
(1)key属性是判断需不需要更新DOM节点的依据,这个key的值的内容变了,则需要更新DOM(删除后重建DOM),内容没变则不需要操作到DOM节点;
(2)key的作用是为了高效的更新虚拟DOM。
reduce方法的使用
利用reduce方法遍历数组的每一个元素,reduce()调用结果最后返回一个最终值(最后一次return值)。
var arr = [ {name: 'Vuejs入门', price: 99, count: 3}, {name: 'Vuejs底层', price: 89, count: 1}, {name: 'Vuejs从入门到放弃', price: 19, count: 5}, ] //数组名.reduce(回调函数,pre的初始值) arr.reduce(function(pre, current){ // reduce这个方法被调用时,会遍历arr这个数组的每一个元素,每遍历一个元素,就执行一次这里的代码 // current表示当前正在遍历的这个元素 // pre 是上一次的这个函数return的值 // !!!因为第一次遍历没有上一个return值,所以,交给了第二个参数,设置pre的初始值 console.log(pre, current) return 10 },0) //!!!并且reduce方法最终会返回最后一次的return值
控制台输出:
0 {name: "Vuejs入门", price: 99, count: 3} 10 {name: "Vuejs底层", price: 89, count: 1} 10 {name: "Vuejs从入门到放弃", price: 19, count: 5}
Vue的计算属性computed的使用
<div id="app"> {{total}} </div> <script> var vm = new Vue({ el:"#app", data:{ arr: [ {name: 'Vuejs入门', price: 99, count: 3}, {name: 'Vuejs底层', price: 89, count: 1}, {name: 'Vuejs从入门到放弃', price: 19, count: 5}, ] }, computed:{ //computed里面的方法必须有返回值!这个return值将来在视图中被{{total}}引用 total(){ var a = this.arr.reduce(function(pre, current){ console.log(pre, current) // var total = 当前这次的 price*count + 上一次的total var total = current.price*current.count + pre return total },0) return a } } }) </script>
computed内部方法有缓存的作用
以下代码total调用了三遍,却只执行了1遍,这是computed内部方法的缓存起了作用
<div id="app"> {{total}} {{total}} {{total}} {{getTotal()}} {{getTotal()}} {{getTotal()}} </div> <script> var vm = new Vue({ el:"#app", data:{ arr: [ {name: 'Vuejs入门', price: 99, count: 3}, {name: 'Vuejs底层', price: 89, count: 1}, {name: 'Vuejs从入门到放弃', price: 19, count: 5}, ] }, methods:{ getTotal(){ console.log("getTotal") var a = this.arr.reduce(function(pre, current){ // var total = 当前这次的 price*count + 上一次的total var total = current.price*current.count + pre return total },0) return a } }, computed:{ //computed里面的方法必须有返回值!这个return值将来在视图中被{{total}}引用 total(){ console.log("total") var a = this.arr.reduce(function(pre, current){ // var total = 当前这次的 price*count + 上一次的total var total = current.price*current.count + pre return total },0) return a } } }) </script>
computed内部方法的另一种写法(get和 set)
.... computed:{ //computed里面的方法必须有返回值!这个return值将来在视图中被{{total}}引用 total:{ get(){ console.log("total_get") var a = this.arr.reduce(function(pre, current){ // var total = 当前这次的 price*count + 上一次的total var total = current.price*current.count + pre return total },0) return a }, set(){ console.log("total_set") }, } } ... vm.total = 3 //触发调用set方法
总结:
1.定义:要用的属性不存在,要通过已有属性计算得来。
2.原理:底层借助了objcet.defineproperty方法提供的getter和lsetter。
3.get函数什么时候执行? (1)初次读取时会执行一次。 (2)当依赖的数据发生改变时会被再次调用。
4.优势:
与methods实现相比,内部有级存机制(复用),效率更高,调试方便。
5.注意:
(1)计算属性最终会出现在vm上,直接读取使用即可。
(2)如果计算属性要被修改,那必须写set函数去响应修改,且set中要引起计算时依赖的数据发生变化。
v-model的原理
v-model 本质上包含了两个操作:
(1)v-bind 绑定input元素的value属性
(2)v-on指令绑定input元素的input事件
即::value="txtVal" 和 @input="handleInput"
<div id="app"> <!-- <input type="text" v-model="txtVal"> --> <input type="text" :value="txtVal" @input="handleInput"> <p>{{ txtVal }}</p> </div> <script> var vm = new Vue({ el:"#app", data:{ txtVal:"" }, methods:{ handleInput(e){ console.log(e) this.txtVal = e.target.value } } }) </script>
即:
<input type="text" v-model="textVal"/> <!-- 等同于 --> <input type="text" v-bind:value="textVal" v-on:input="textVal = $event.target.value"/>
数组常用的操作
push(返回数组长度)
unshift(返回数组长度)
shift(返回删除的值)
pop(返回删除的值)
splice、concat(返回新数组)
var arr = [1, 2, 3] // 往数组最后一位添加一个数字 arr.push(4) // [1, 2, 3, 4] // 删除数组最后一个数字 arr.pop() // [1, 2, 3] console.log(arr) // 往数组第一位添加一个数字 arr.unshift(0) console.log(arr) // 删除数组第一个元素 arr.shift() console.log(arr) // splice // 删除第一个元素 arr.splice(1, 2) console.log(arr) arr.splice(1, 2, 2, 4, 5) console.log(arr) // 合并数组 console.log([1, 6].concat([5, 7]))
reduce(计算)
filter(过滤)
map(集合)
var arr = [1, 2, 3] // 计算总数 var ret1 = arr.reduce((pre, current)=>{ pre += current return pre }, 0) console.log(ret1) // 6 // filter (过滤) var ret2 = arr.filter(item =>{ return item > 2 }) console.log(ret2) // [3] // map var ret3 = arr.map(item =>{ return {id:item} }) console.log(ret3) // [{id: 1}, {id: 2}, {id: 3}]
数组去重
var arr2 = [1, 2, 3, 1, 6, 2, 3] //ES6 consoloe.log([...new Set(arr2)]) console.log(Array.from(new Set(arr2))) var newArray = []; for(var i=0; i<arr2.length; i++){ if(newArray.indexOf(arr2[i])==-1){ newArray.push(arr2[i]) } } console.log(newArray) var newArray2 = []; var obj = {}; for(var i=0; i<arr2.length; i++){ if(!obj[arr2[i]]){ //如果不在obj中,就表示不重复的数据,就在对象中添加键值对 obj[arr2[i]] = arr2[i] newArray2.push(arr2[i]) } } console.log(newArray2)
Vue的过滤器和全局过滤器
使用
Vue的过滤器用来对数据展示之前做一定的处理
<div id="app"> <!-- {{ 变量名 | 过滤器名 }} --> <p>{{ num | formatNum }}</p> </div> <script> var vm = new Vue({ el:"#app", data:{ num:10 }, filters:{ formatNum(val){ // 这个形参接收 | 符号前面的变量数据 return val + 50 //return后面的值就是将来展示在页面上的值(即过滤之后的值) } } }) </script>
过滤一个时间戳:
<div id="app"> <!-- {{ 变量名 | 过滤器名 }} --> <p>{{ timestamp | formatDate }}</p> </div> <script> // var timestamp = new Date().getTime() // 获取时间戳 // console.log("日期是:",timestamp) var vm = new Vue({ el:"#app", data:{ timestamp:new Date().getTime() }, filters:{ formatDate(val){ // 这个形参接收 | 符号前面的变量数据 var now = new Date(val) var year=now.getFullYear(); var month=now.getMonth()+1; var date=now.getDate(); var hour=now.getHours(); var minute=now.getMinutes(); var second=now.getSeconds(); return year+"-"+month+"-"+date+" "+hour+":"+minute+":"+second; } } }) </script>
全局过滤器
多个app共用的过滤器可以作为全局过滤器来书写
<div id="app"> <!-- {{ 变量名 | 过滤器名 }} --> <p>{{ timestamp | formatDate }}</p> </div> <div id="app2"> <!-- {{ 变量名 | 过滤器名 }} --> <p>第二个: {{ timestamp | formatDate }}</p> </div> <script> //全局过滤器 // Vue.filter("过滤器名字",(val)=>{}) Vue.filter("formatDate",(val)=>{ var now = new Date(val) var year=now.getFullYear(); var month=now.getMonth()+1; var date=now.getDate(); var hour=now.getHours(); var minute=now.getMinutes(); var second=now.getSeconds(); return year+"-"+month+"-"+date+" "+hour+":"+minute+":"+second; }) var vm2 = new Vue({ el:"#app2", data:{ timestamp:new Date().getTime() } }) // var timestamp = new Date().getTime() // 获取时间戳 // console.log("日期是:",timestamp) var vm = new Vue({ el:"#app", data:{ timestamp:new Date().getTime() }, // filters:{ // formatDate(val){ // 这个形参接收 | 符号前面的变量数据 // var now = new Date(val) // var year=now.getFullYear(); // var month=now.getMonth()+1; // var date=now.getDate(); // var hour=now.getHours(); // var minute=now.getMinutes(); // var second=now.getSeconds(); // return year+"-"+month+"-"+date+" "+hour+":"+minute+":"+second; // } // } }) </script>
以上就是Vue入门第二天的全部内容了。
资料文档地址:前端开发Vue基础篇:Day02Vue基础知识.pdf