Vue2 - 23-03-21

First Post:

Last Update:

Vue2 - 23-03-21

总结数据监视

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>总结Vue数据监测</title>
<script src="../resources/js/vue.js"></script>
</head>
<body>
<div id="root">
<h1>学生信息</h1>
<button @click="student.age++">年龄+1岁</button>
<button @click="addGender">添加性别属性,默认值为男</button>
<button @click="addFriend">在列表首位添加一个朋友</button>
<button @click="updateFirstFriendName">修改第一个朋友的名字为“张三”</button>
<button @click="addHobby">添加一个爱好</button>
<button @click="modifyHobby">修改第一个爱好为“开车”</button>
<button @click="filterSmoking">过滤掉爱好中的抽烟</button>
<h2>学生姓名:{{student.name}}</h2>
<h2 v-if="student.gender">学生性别:{{student.gender}}</h2>
<h2>学生年龄:{{student.age}}</h2>
<h2>学生爱好</h2>
<ul>
<li v-for="(h, index) in student.hobby">
{{h}}
</li>
</ul>
<h2>朋友:</h2>
<ul>
<li v-for="(f,index) of student.friends" :key="index">
{{f.name}}--{{f.age}}
</li>
</ul>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false;
const vm = new Vue({
el:"#root",
data:{
student:{
name:'Linzepore',
age:18,
hobby:['抽烟','喝酒','烫头'],
friends:[
{name:'jack',age:30},
{name:'lily',age:20}
]
}
},
methods:{
addGender(){
// 错误写法 vm.set(this,student.gender,'男')
// 另一种方式 Vue.set(this.student,'gender','男'),
this.$set(this.student,'gender','男')
},
addFriend(){
this.student.friends.unshift({name:'tom', age:13})
},
updateFirstFriendName(){
this.student.friends[0].name = '张三'
},
addHobby(){
this.student.hobby.push('打台球')
},
modifyHobby(){
// this.student.hobby.splice(0,1,'开车')
Vue.set(this.student.hobby,0,'开车')
},
filterSmoking(){
const newHobby = this.student.hobby.filter((val)=>{
return val != '抽烟'
})
this.student.hobby = newHobby;
}
}
})
</script>
</html>

补充filter监测不到做不了响应式,那么就可以通过直接将过滤之后的新数组覆盖原数组
数据劫持实际上就是数据代理,通过Object.defineProperty()可以实现数据劫持,让属性在赋值的时候能够触发set方法

收集表单数据

v-model修饰符

v-model.number:将value的值赋给data的属性时候转换成数字类型
v-model.trim:去掉value中前后的空格
v-model.lazy:失去焦点之后再返回数据

一些input里面需要手动配value

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title></title>
<script src="../resources/js/vue.js"></script>
</head>
<body>
<div id="root">
<form @submit.prevent="demo">
<!-- .trim前后去掉空格 -->
账号:<input type="text" v-model="account"><br>
密码:<input type="password" v-model="password"><br>
<!-- 一般来说type="number"和“.number”修饰符会同时使用 -->
年龄:<input type="number" v-model.number="age"><br>
性别:
男<input type="radio" name="gender" v-model="gender" value="male">
女<input type="radio" name="gender" v-model="gender" value="female"><br>
爱好:
学习<input type="checkbox" v-model="hobby" value="study">
打电动<input type="checkbox" v-model="hobby" value="game">
吃饭<input type="checkbox" v-model="hobby" value="eat">
所属校区
<select v-model="city">
<option value="">请选择校区</option>
<option value="beijing">北京</option>
<option value="shanghai">上海</option>
<option value="shenzhen">深圳</option>
<option value="wuhan">武汉</option>
</select><br>
其他信息:
<!-- .lazy失去焦点的时候就会解析 -->
<textarea v-model.lazy="other" cols="30" rows="10"></textarea><br>
<input type="checkbox" v-model="agree"> 阅读并接受<a href="http://baidu.com">《用户协议》</a>
<button >提交</button>
</form>
</div>
<script type="text/javascript">
Vue.config.productionTip = false;
new Vue({
el: '#root',
data:{
account:'',
password:'',
age:null,
gender:'female',
hobby:[],
city:'beijing',
other:'',
agree:''
},
methods:{
demo(){
// console.log(this.account);
// console.log(this.password);
// console.log(this.gender);
// console.log(this.hobby);
// console.log(this.city);
// console.log(this.other);
// console.log(this.agree);
console.log(JSON.stringify(this._data))
}
}
})
</script>
</body>
</html>

过滤器

局部过滤器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!-- 不传参默认只向管道传入time -->
<h3>现在是:{{time | timeFormater}}</h3>

<!-- 传参的话会向管道传入两个参数:time、'YYYY年MM月DD日' -->
<h3>现在是:{{time | timeFormater('YYYY_MM_DD hh:mm:ss')}}</h3>

<!--可以有多个管道-->
<h3>现在是:{{time | timeFormater('YYYY_MM_DD hh:mm:ss') | mySlice}}</h3>

//局部过滤器
filters:{
// ES6中可以有形参默认值
timeFormater(originalTime,str='YYYY年MM月DD日') {
return dayjs(originalTime).format(str)
},
mySlice(value) {
return value.slice(0,4)
}
}

如何证明其为局部?

1
2
3
4
5
6
7
8
9
10
<div id="root2">
<h2>{{msg | mySlice}}</h2>
</div>

new Vue({
el:'#root2',
data:{
msg:"hello, I'm Linzepore!"
}
})

全局过滤器

1
2
3
4
5
6
7
8
9
Vue.filter('mySlice', function(value){
return value.slice(0,4);
})
new Vue({
el:'#root2',
data:{
msg:"hello, I'm Linzepore!"
}
})


也可以用在v-bind属性上,不限于插值语法

v-text

v-html

安全威胁:容易受到XXS攻击(虽然一般会进行HttpOnly保护)

【尚硅谷Vuejs从入门到精通P41_尚硅谷Vue技术_v-html指令】 【精准空降到 19:07】

v-cloak


为了避免由于js未加载出来导致页面混乱,vue提供了一个v-cloak属性,该属性会在Vue接管时候删除,可以配合CSS的属性选择器来使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>v-cloak指令</title>
<style>
[v-cloak] {
display: none;
}
</style>
</head>
<body>
<div id="root">
<h3>{{name}}</h3>
<h3 v-cloak>{{name}}</h3>
<!-- 假如vue.js没出来,h3不会出现 -->
</div>
<script src="./resources/js/vue.js"></script>
<script type="text/javascript">
Vue.config.productionTip = false;
new Vue({
el: '#root',
data:{
name:'Linzepore',
}
})
</script>
</body>
</html>

v-once

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>v-once指令</title>
<script src="../resources/js/vue.js"></script>
</head>
<body>
<div id="root">
<h2 v-once>初始化的n值:{{n}}</h2>
<h2>当前的n值是:{{n}}</h2>
<button @click="n++">点我n+1</button>
<script type="text/javascript">
Vue.config.productionTip = false;
new Vue({
el: '#root',
data:{
n:1
}
})
</script>
</body>
</html>

v-pre

自定义v-big指令

big函数何时会被调用?

  • 1.指令与元素成功绑定时
  • 2.指令所在模板重新解析时(而非依赖的数据被改变时!)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>自定义指令</title>
<script src="../resources/js/vue.js"></script>
</head>
<body>
<div id="root">
<h2>当前的n值是<span v-text="n"></span></h2>
<h2>放大十倍后的n值是<span v-big="n"></span></h2>
<button @click="n++">点我n+1</button>
</div>
<script type="text/javascript">
Vue.config.productionTip = false;
new Vue({
el: '#root',
data:{
n:1
},
directives:{
//big函数何时会被调用?
//1。指令与元素成功绑定时
//2.指令所在模板重新解析时(并非依赖的数据被改变时!)
big:function(element, binding){
// console.dir(element);
// console.log(element instanceof HTMLElement);
element.innerText = binding.value*10
console.log(binding);
}
}
})
</script>
</body>
</html>