Vue2 - 23-03-22

First Post:

Last Update:

Vue2 - 23-03-22

自定义v-fbind指令

如果要写一个一上来就能够自动获取焦点的指令,就会涉及到插入页面,
但是默认函数式写法只包括元素与指令绑定时和模板重新解析时

此时就需要时候对象式写法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<button @click="n++">点我n+1</button>
<hr>
<input type="text" v-fbind:value="n">
fbind:{
bind(element, binding){
element.value = binding.value;
},
inserted(element, binding){
element.focus();
},
update(element, binding){
element.value = binding.value
}
}

回顾DOM操作顺序

自定义指令容易踩的坑

指令名称多个单词组成

1
2
3
4
5
6
<h2>放大十倍后的n值是<span v-big-number="n"></span></h2>

'big-number'(element, binding){
element.innerText = binding.value*10
}

自定指令的this

指令里面的this都是Windows,需要什么属性通过binding传

定义全局指令

做法与全局过滤器类似

1
2
3
4
5
<h2>放大十倍后的n值是<span v-bigg="n"></span></h2>
//定义全局指令
Vue.directive('bigg',function(element, binding){
element.innerText = binding.value*10
});

总结自定义指令

Vue生命周期

  • 生命周期又名生命周期回调函数、生命周期函数、生命周期钩子
  • 是什么:Vue在关键时刻帮我们调用的一些特殊名称的函数
  • 生命周期函数的名字不可更改,但函数的具体内容是程序员根据需求编写的
  • 生命周期函数中的 this 指向是vm或组件实例对象
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
beforeCreate(){
// 生成数据代理前
console.log("beforeCreate");
},
created(){
// 生成数据代理后
console.log("created");
},
beforeMount() {
// 虚拟dom覆盖原来dom之前
console.log("beforeMount");
},
mounted(){
// 虚拟dom覆盖原来dom之后
console.log("mounted");
console.log(this.$el);
},
beforeUpdate(){
// 数据已经变了,页面更新前
console.log("beforeUpdate");
},
updated(){
// 数据页面同步
console.log("updated");
},
beforeDestroy(){
// 收尾
console.log("beforedestroy");
},
destroyed(){
//对页面残留结果进行操作
console.log("destroyed");
}

生命周期总结

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
<!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 :style="{opacity}">欢迎学习Vue</h2>
<button @click="opacity = 1">透明度变为1</button>
<button @click="stop">停止变换</button>
</div>
<script type="text/javascript">
Vue.config.productionTip = false;
const vm = new Vue({
el: '#root',
data:{
opacity:1
},
methods:{
stop(){
this.$destroy();
}
},
mounted(){
//开发中常用的给当前实例追加属性
this.timer = setInterval(()=>{
this.opacity-=0.01;
// if(this.opacity==0) this.opacity=1 js没办法与零比较
if(this.opacity<=0) this.opacity=1
},16)
},
beforeDestroy(){
clearInterval(this.timer)
}
})
</script>
</body>
</html>

模块化与组件化

模块化是指将js文件进行拆分
组件化是指一系列代码和资源的集合

组件的基本使用

  • 创建组件(一般包括data、template)
  • 注册组件
  • 使用组件标签

为什么要将data的data写成函数式?

1
2
3
4
5
6
7
8
9
10
11
12
13
let data = {a: 1, b: 2}
const d1 = data;
const d2 = data;
d1.a = 10;
console.log(d2)//returns {a: 10, b: 2}
-----
let data(){
return {a: 1, b: 2}
}
const d1 = data;
const d2 = data;
d1.a = 10;
console.log()//returns {a: 1, b: 2}

全局组件

全局组件要放在最开头处,否则容易未被解析出现错误

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 全局组件
// 创建组件
const test = Vue.extend({
template:`
<div>
<h2>{{test}}</h2>
</div>
`,
data(){
return {
test:'test successfully! '
}
},
})
// 全局注册组件
Vue.component('test',test);

局部组件

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
// 注册局部组件
//第一步:创建组件
const school = Vue.extend({
template:`
<div>
<h2>学校名称:{{schoolName}}</h2>
<h2>学校地址:{{address}}</h2>
</div>
`,
// 只能写成函数式
data(){
return {
schoolName: 'gdip',
address:'foshan'
}
}
})
const student = Vue.extend({
template:`
<div>
<h2>学生姓名:{{studentName}}</h2>
<h2>学生年龄:{{age}}</h2>
<test></test>
</div>`,
data(){
return {
studentName:'linzepore',
age:20
}
}
})
//第二步:创建vm,注册组件
new Vue({
el:'#root',
data:{
hello:'hello'
},
components:{
school: school,
// student: student
student
}
})

组件的使用

1
2
3
4
5
6
7
8
<div id="root">
<!-- 第三步:编写组件标签 -->
<h1>{{hello}}</h1>
<school></school>
<hr>
<student></student>
<test></test>
</div>

组件标签名称大小写

  • 注册组件名称写成以-连接会自动形成大写(如'my-school':school
  • 注册的时候用的什么名字,使用标签就要用什么名字;如果组件定义了名字,开发者工具会随之变化,但是使用标签时候还是要用注册的名字
  • 创建组件的时候可以先不写Vue.extend,直接写成对象的形式,注册的时候Vue会进行调用

组件的嵌套以及书写规范

详见->第57集

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
<div id="root"></div>

//定义student组件
const student = Vue.extend({
//定义school组件,嵌套了student
const school = Vue.extend({
template:`
<div>
<h2>学校名称:{{schoolname}}</h2>
<h2>学校地址: {{address}}</h2>
<student></student>
</div>
`,
data(){
return {
schoolname:'gdip',
address:'foshan'
}
},
components:{
student
}
})
//定义了hello组件,与school平级
const hello = Vue.extend({
template:`
<h2>欢迎来到Linzepore的博客</h2>
`
})
const app = Vue.extend({
template:`
<div>
<hello></hello>
<school></school>
</div>
`,
components:{
hello,
school
}
})
new Vue({
template:`<app></app>`,
el: '#root',
components:{
app
}
})

一个bug————忘记把标签包裹成为一个根标签

Vue报错:[Vue warn]: Error compiling template:
Component template should contain exactly one root element. If you are using v-if on multiple elements, use v-else-if to chain them instead.