模板语法的插值操作
(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