vue学习(一)

既然面试上碰到这么多vue的问题,那就来学习一下,不会vue都不敢自称是前端了[汗],毕竟潮流得跟上,不然会拍死在岸上,最近也是深有体会。

Cut the crap,Just do it!

一、先来介绍下vue

1.什么是MVVM

  • M(Model):数据
  • V(View):视图(即页面DOM)
  • VM(ViewModel):监控数据和视图的变化

先这样简单理解下,下次深究。

2.vue的优点

  • 更轻量更快
  • 更容易上手,易学

3.vue的核心

  • 双向数据绑定:只要改变数据,就会自动改变视图
  • 视图组件化:网页由多个组件拼接和嵌套组成的

4.试用场景

  • 频繁的操作DOM来更新页面
  • 项目中多个部分是相同的,并可以封装成一个组件
  • 不用兼容ie8

二、简单的入门Vue

俗话说,一口吃不成一个胖纸,让我们一步一步来,先从简单的入手^_^

1、先来看看数据驱动视图

废话不多说,直接上代码^~^

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>从零开始学习vue</title>
</head>
<body>
<div id="app">看看有什么内容出来:{{message}}</div>

<script src="js/vue.js"></script>
<script>
let app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
})
</script>
</body>
</html>

在这段代码中可以看到网页上显示:
看看有什么内容出来:Hello Vue!Let me have a try...

直接在控制台上试试改变下message的值:
app.message = "You are still you?"

于是乎,神奇的现象出现了,网页上显示:
看看有什么内容出来:You are still you?

在上面的过程中可以看出,我们并没有对DOM进行手动操作,数据自动绑定在了页面上,当数据改变时,也会自动的更新视图。

嗯,神奇>_<

2、再来看看双向绑定

在vue中提供了语法指令(前端界俗称自定义属性),实现视图和数据的双向绑定,也就是说,不但数据发生了变化可以驱动视图,用户在页面上操作,也可以很方便的实现更新model层的数据,可以使用v-model指令来实现。

看,代码上来了~

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">
<title>从零开始学习vue</title>
</head>
<body>
<div id="app">
<p>
<input type="text" v-model="text">
<span>看看输入了什么:{{text}}</span>
</p>
</div>

<script src="js/vue.js"></script>
<script>
let app = new Vue({
el: '#app',
data: {
text: '',
}
})
</script>
</body>
</html>

在上面这段代码中,我们不需要去写代码监听input的内容变化,当用户输入内容时,会实时地更新data中的text属性的值,一旦text更新了,视图也会跟着更新。

3、继续,组件化

什么?组件化都不懂?_?

组件化就是把页面中特定的区块独立抽出来,并封装成一个可方便复用的组件。假设有多个一样的结构,就可以封装成一个组件,在vue中,可以用Vue.component(tagName,options)注册一个组件,这样,在复用的时候只需要使用<tagName></tagName>就可以了,有没有很方便。

先来一个简单的组件,look,code!

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">
<title>从零开始学习vue</title>
</head>
<body>
<div id="app">
<art></art>
<art></art>
<art></art>
</div>

<script src="js/vue.js"></script>
<script>
Vue.component('art', {
template: `<div class="art">
<h1>这是标题</h1>
<p>瞧瞧,这里有很多文案</p>
<p>瞧瞧,这里有很多文案</p>
<p>瞧瞧,这里有很多文案</p>
<p>瞧瞧,这里有很多文案</p>
</div>`
});

let app = new Vue({
el: '#app'
});
</script>
</body>
</html>

从上面的实例中可以看出来 实例化Vue的过程如下:
new Vue() -> 设置数据data -> 挂载元素 -> 成功渲染

继续。。。

4、vue实例常用的四个参数

(1)filters(过滤器)

官方文档上解释:vue.js允许你自定义过滤器,可被用于一些常见的文本格式。可以用在两个地方:双括号插值和v-bind表达式,过滤器应该被添加在javascript表达式的尾部。

什么意思呢?

这里需要上个栗子

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>从零开始学习vue</title>
</head>
<body>
<div id="app">
<section>
<p>num1:{{num1 | toInt}}</p>
<p>num2:{{num2 | toInt}}</p>
<p>num2:{{num3 | toInt}}</p>
</section>
</div>

<script src="js/vue.js"></script>
<script>
let app = new Vue({
el: '#app',
data: {
num1: 22.5657,
num2: 33.3241,
num3: 12.3524,
},
filters: {
toInt(val){
return parseInt(val);
}
}
})
</script>
</body>
</html>

以上代码会在界面上显示:
num1:22
num2:33
num2:12

嗯,没有了小数点@_@

除了数字还有文案的过滤等等,以后接触了再深究。

(2)computed(计算属性)

官方文档上说,模板内设计表达式的初衷是用于简单的运算,但是放入太多的逻辑会让模板过重而且难以维护,于是乎,就出来了这个计算属性,对于任何复杂逻辑,都应该使用计算属性。

下面是计算三个数之和的栗子

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">
<title>从零开始学习vue</title>
</head>
<body>
<div id="app">
<section>
<p>和:{{sum}}</p>
</section>
</div>

<script src="js/vue.js"></script>
<script>
let app = new Vue({
el: '#app',
data: {
n1: 1,
n2: 2,
n3: 3,
},
computed: {
sum(){
return this.n1 + this.n2 + this.n3
}
}
})
</script>
</body>
</html>

我的理解,对于一些复杂的表达式,就可以放在filters里面,这样没那么乱也没那么笨重。

(3)methods(方法)

这就通俗易懂了,在methods中,可以定义一些方法,供组件使用。

如下:

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>从零开始学习vue</title>
</head>
<body>
<div id="app">
<section>
<span>{{a}}</span>
<button v-on:click="plus">+1</button>
</section>
</div>

<script src="js/vue.js"></script>
<script>
let app = new Vue({
el: '#app',
data: {
a: 1
},
methods: {
plus(){
return this.a++;
}
},
})
</script>
</body>
</html>

以上代码,每点击一次按钮+1,a就会加1。

(4)watch(观察)

watch是用来检测指定的数据发生改变的

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>从零开始学习vue</title>
</head>
<body>
<div id="app">
<section>
<p>和:{{sum}}</p>
</section>

<section>
<span>{{a}}</span>
<button v-on:click="plus">+1</button>
</section>
</div>

<script src="js/vue.js"></script>
<script>
let app = new Vue({
el: '#app',
data: {
a: 1
},
methods: {
plus(){
return this.a++;
}
},
watch: {
a(){
console.log('a发生变化了', this.a)
}
}
})
</script>
</body>
</html>

以上代码,点击+1按钮的时候,控制台就会显示改变后a的值

5、vue的声明周期

何为声明周期?大白话就是从出生到死亡的过程,生存还是毁灭,掌握在你手里O+O

(1)beforeCreate(初始化之前)

这个阶段的数据观察和事件配置都没准备好

来看个实例

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>从零开始学习vue</title>
</head>
<body>
<div id="app">
<section>
<p>我:是你吗?</p>
<p>vue:{{answer}}</p>
</section>
</div>

<script src="js/vue.js"></script>
<script>
let app = new Vue({
el: '#app',
data: {
answer: '百分百是我!'
},
beforeCreate(){
console.log('即将创建')
console.log(this.$data) // undefined
console.log(this.$el) // undefined
}
})
</script>
</body>
</html>

可以看到,此时实例中的this.$datathis.$el 输出的是undefined,不可用

(2)created(初始化之后)

beforeCreate之后紧接着的就是创建创建完毕了的created

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>从零开始学习vue</title>
</head>
<body>
<div id="app">
<section>
<p>我:是你吗?</p>
<p>vue:{{answer}}</p>
</section>
</div>

<script src="js/vue.js"></script>
<script>
let app = new Vue({
el: '#app',
data: {
answer: '百分百是我!'
},
created(){
console.log('创建完毕')
console.log(this.$data) // {__ob__: Observer}
console.log(this.$el) // undefined
}
})
</script>
</body>
</html>

此时的实例中能读到data,但是DOM还没声明,所以el还不存在,会返回undefined

(3)beforeMount(挂载之前)

该阶段是成功关联了DOM节点,但是并没有成功的渲染数据

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>从零开始学习vue</title>
</head>
<body>
<div id="app">
<section>
<p>我:是你吗?</p>
<p>vue:{{answer}}</p>
</section>
</div>

<script src="js/vue.js"></script>
<script>
let app = new Vue({
el: '#app',
data: {
answer: '百分百是我!'
},
beforeMount(){
console.log('即将挂载')
console.log(this.$data) // {__ob__: Observer}
console.log(this.$el) // <div id="app"><section><p>我:是你吗?</p><p>vue: {{answer}}</p></section></div>
}
})
</script>
</body>
</html>

以上代码会看到el可以获取到了,但是还没渲染成功。

(4)mounted(挂载之后)

该阶段数据会被成功渲染出来。

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>从零开始学习vue</title>
</head>
<body>
<div id="app">
<section>
<p>我:是你吗?</p>
<p>vue:{{answer}}</p>
</section>
</div>

<script src="js/vue.js"></script>
<script>
let app = new Vue({
el: '#app',
data: {
answer: '百分百是我!'
},
mounted(){
console.log('挂载完毕')
console.log(this.$data) // {__ob__: Observer}
console.log(this.$el) // <div id="app"><section><p>我:是你吗?</p><p>vue: 百分百是我!</p></section></div>
}
})
</script>
</body>
</html>

此时,已被成功渲染成’百分百是我!’

(5)beforeUpdate(更新渲染视图之前)

当修改data时,vue会自动更新渲染视图,在这之前会触发beforeUpdate

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>从零开始学习vue</title>
</head>
<body>
<div id="app">
<section>
<p>我:是你吗?</p>
<p>vue:<em ref="answer" id="answer">{{answer}}</em></p>
</section>
</div>

<script src="js/vue.js"></script>
<script>
let app = new Vue({
el: '#app',
data: {
answer: '百分百是我!'
},
beforeUpdate(){
console.log('即将渲染')
let answer = this.$refs.answer.innerHTML;
console.log('answer:' + answer)
}
})
</script>
</body>
</html>

在控制台上改变answer的值,app.answer = '正是在下,请多指教',会打印出answer:百分百是我!

(6)updated(更新渲染视图之后)

更新渲染视图之后,此时再读取视图上的内容,已经是最新的内容,会触发updated。

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>从零开始学习vue</title>
</head>
<body>
<div ref="app" id="app">
<section>
<p>我:是你吗?</p>
<p>vue:<em ref="answer" id="answer">{{answer}}</em></p>
</section>
</div>

<script src="js/vue.js"></script>
<script>
let app = new Vue({
el: '#app',
data: {
answer: '百分百是我!'
},
updated(){
console.log('渲染成功')
let answer = this.$refs.answer.innerHTML;
console.log('answer:' + answer)
}
})
</script>
</body>
</html>

在控制台上改变answer的值,app.answer = '正是在下,请多指教',会打印出answer:正是在下,请多指教

(7)beforeDestroy(销毁之前)

调用实例的destroy()方法可以销毁当前的组件,在销毁之前会触发beforeDestroy钩子

(8)destroyed(销毁之后)

调用实例的destroy()方法可以销毁当前的组件,在成功销毁后会触发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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>从零开始学习vue</title>
</head>
<body>
<div ref="app" id="app">
<section>
<p>我:是你吗?</p>
<p>vue:<em ref="answer" id="answer">{{answer}}</em></p>
</section>
</div>

<script src="js/vue.js"></script>
<script>
let app = new Vue({
el: '#app',
data: {
answer: '百分百是我!'
},
beforeDestroy(){
console.log('销毁之前')
},
destroyed(){
console.log('销毁成功')
}
})
</script>
</body>
</html>

上面的实例,当在控制台输入 app.answer = '正是在下,有何贵干!',会发现视图跟着改变了,然后app.$destroy(),再次改变data的值 app.answer = '正是在下!',视图就不会跟着改变了。


我要一步一步往上爬~
.
.
.
很晚了,下次再爬,[捂脸],休息休息~


learn from:


说明:本博客的内容纯粹做为个人学习笔记本使用,有些内容可能是其他网站或书本借鉴而来,也是为了帮助自己更好的学习和理解,就跟着敲一敲。若有幸被您看到,对文中有什么建议或者发现文中有什么错误,欢迎骚扰^_^;如果文中有涉及到版权侵权之类的,欢迎留言,本人会及时删掉相关文章。[握手]