初识Vue

概述

​ 渐进式 JavaScript 框架,采用mvvm模式(数据驱动视图),易学易用(指令华操作),性能出色(封装了部分内容,可进行部分优化),适用场景丰富的 Web 前端框架(生态体系完善(阿里巴巴))。

渐进式框架

渐进式可以理解为:用什么拿什么;

​ 因为Vue主张少,不强势。你可以在核心功能的基础上任意选用其他的部件,不一定要全部整合在一起。可以看到,所说的“渐进式”,其实就是Vue的使用方式,同时也体现了Vue的设计的理念,总而言之,你可以有很多选择,并不是非常强制你一定要用那种方式,vue只是为我们提供了视图层,至于底层的实现,还是有非常多的选择的。

代表框架

  • vue(尤雨溪 2016)
  • react(Facebook 2013)
  • angular(Google 2009)

MVVM模式

是Model-View-ViewModel的简写,本质是个MVC的改进版

  • M:模型 Model —>也就是data中的数据

  • V:视图 View —>也就是模板代码

  • VM:视图模型 ViewModel —>也就是Vue实例(vm)

    DOM listeners DOM 监听器(监听DOM )

    Data Bindings 数据绑定器 (负责监听Model中的数据变化)

img

Vue的虚拟DOM及diff算法

虚拟DOM(抽取于实体DOM而生成的虚拟对象)

​ 通过js创建一个Object对象来模拟真实DOM结构,这个对象包含标签名 (tag)、属性 (attrs) 和子元素对象 (children) 三个属性,通过vue中的render()函数把虚拟dom编译成真实dom,在通过appendChild()添加到页面中。

为什么要用虚拟DOM来描述真实DOM呢?

​ 创建真实DOM成本比较高,如果用 js对象来描述一个dom节点,成本比较低,另外我们在频繁操作dom是一种比较大的开销。所以建议用虚拟dom来描述真实dom。

diff算法 (用于比对与虚拟DOM的差异)

diff算法用于比对新旧虚拟dom,利用patch打补丁包的形式来比对的。

Vue的版本

vue2

2015年发布,底层采用Object.defineProperty,全面兼容es5语法

vue3

2020年发布,底层采用Proxy,全面兼容es6,简化了对应了指令操作,提高了对应的效率,全面兼容vue2

Vue入门案例

引入vue.js

  • 通过webpack来构建对应的脚手架,通过模块化导入

    1
    npm i vue -s
  • cdn导入

    1
    <script src="https://unpkg.com/vue@2.7.1/dist/vue.global.js"></script>

入门代码

1
2
3
4
5
6
7
8
9
<div id="app">{{msg}}</div>
<script>
let vm = new Vue({
el:'#app',//挂载点
data:{
msg:'this is vue2'
}//数据 利用递归进行数据劫持
})
</script>

Vue的配置参数

  • el 挂载点
  • data 数据
  • methods 方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<div id="app">
<h1>你好 {{names}}</h1>
</div>
<script src="./lib/vue2.7.1.js"></script>
<script>
Vue.config.productionTip = false

const vm = new Vue({
el: '#app',
data: {
names: '袁同学!',
},
methods: {
sayHi(){
console.log('hello')
}
},
})
console.log(vm.$data);
console.log(vm.$el);
console.log(vm.names);
console.log(vm.sayHi);
</script>

Vue的指令

vue封装了对应的指令去操作dom

v-html

html解析显示,vue做了专门优化,可以防止xss攻击

v-text

文本显示

v-show

一定会渲染,只渲染一次

v-if

不一定渲染 ,可控制重新渲染

v-bind

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<div id="app">
<h1>你好 {{names}}</h1>
<p v-bind:username="name">123</p>
<p :username="name">123</p>
<p :class="isDarkblue?'pink':'darkblue'">123</p>
</div>
<script src="./lib/vue2.7.1.js"></script>
<script>
Vue.config.productionTip = false

const vm = new Vue({
el: '#app',
data: {
names: '袁同学!',
name:'hello',
className:'darkblue',
isDarkblue:true
}
})
</script>

v-for

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
<div id="app">
<!-- 遍历对象 -->
<ul>
<li v-for="(key,value) in obj" :key="key">
{{key}}:{{value}}
</li>
</ul>
<!-- 遍历数组 -->
<ul>
<li v-for="(value,index) in arr" :key="value">
{{value}}[{{index}}]
</li>
</ul>
<!-- 根据number对象的值遍历个数 -->
<ul>
<li v-for="v in number" :key="value">
{{v}}
</li>
</ul>
</div>
<script src="./lib/vue.js"></script>
<script>
Vue.config.productionTip = false

const vm = new Vue({
el: '#app',
data: {
obj: {
username: '张三',
password: '123456',
age: 18,
email: '123@123email'
},
arr:[1,2,'a','b','c','d'],
number:20,
}
})
</script>

v-if和v-for的优先级问题

  • vue2 v-for要高于v-if
  • vue3 v-if 要高于v-for 且会报错

vue官方文档提示:不建议两者在同一个标签上使用

v-on事件绑定

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
<div id="app">
<h1>{{msg}}</h1>
<!-- 事件绑定 -->
<button v-on:click="handlerClick()">带括号的点击</button>
<!-- 简写 -->
<button @click="handlerClick">点击</button>

<div @click="handlerParent">
<!-- 阻止事件冒泡 -->
<button @click.stop="handlerChild">子元素按钮</button>
</div>
<!-- 阻止默认事件 -->
<a @click.prevent="aClick" href="https://www.baidu.com">百度</a>
</div>
<script src="./lib/vue.js"></script>
<script>
Vue.config.productionTip = false

const vm = new Vue({
el: '#app',
data: {
msg: '袁同学!',
},
methods: {
// 函数不能是箭头函数
handlerClick(){
// 这里的this指向vue实例
this.msg = '袁同学 点击了'
console.log(arguments);
},
handlerChild(){
console.log('子元素点击了');
},
handlerParent(){
console.log('父元素点击了');
},
aClick(){
console.log('a点击了');
}
},
})
</script>
事件修饰符
  • .stop 停止冒泡
  • .prevent 阻止默认事件
  • .capture 捕获
  • .self 自身触发
  • .once 只执行一次
  • .passive会 告诉浏览器你不想阻止事件的默认行为

辅助相关指令

v-pre

跳过这个元素和它的子元素的编译过程。可以用来显示原始 Mustache 标签。跳过大量没有指令的节点会加快编译。

v-cloak

这个指令保持在元素上直到关联实例结束编译。和 CSS 规则如 [v-cloak] { display: none } 一起用时,这个指令可以隐藏未编译的 Mustache 标签直到实例准备完毕。

v-once

只渲染元素和组件一次。随后的重新渲染,元素/组件及其所有的子节点将被视为静态内容并跳过。这可以用于优化更新性能。

这三个指令都不需要表达式,直接用即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<div id="app">
<p v-pre>{{names}}</p>
<p v-cloak>{{names}}</p>
<p v-once>{{names}}</p>
<button @click="handClick">点击</button>
</div>
<script src="./lib/vue.js"></script>
<script>
Vue.config.productionTip = false

const vm = new Vue({
el: '#app',
data: {
names: '袁同学',
},
methods: {
handClick(){
this.names = '袁同学 点击了'
}
},
})
</script>

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
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
<div id="app">
<h3>v-model的双向数据绑定</h3>
<!-- 监听input框的change事件 -->

<!-- 普通输入框 -->
<input v-model="msg" type="text">
{{msg}}<br><br>

<!-- 文本区 -->
<textarea v-model="text" name="" id="" cols="30" rows="10"></textarea>
{{text}}<br><br>

<!-- 拖拉条 -->
<input v-model="number" type="range" name="" id="">
{{number}}<br><br>

<!-- 复选框 -->
<input v-model="list" type="checkbox" name="city" value="长沙">
<input v-model="list" type="checkbox" name="city" value="北京">
<input v-model="list" type="checkbox" name="city" value="上海">
<input v-model="list" type="checkbox" name="city" value="深圳">
<input v-model="list" type="checkbox" name="city" value="杭州">
{{list}}<br><br>

<!-- 单选框 -->
<input v-model="sex" type="radio" name="sex" value="男">
<input v-model="sex" type="radio" name="sex" value="女">
{{sex}}<br><br>

<!-- 下拉框 -->
<select name="" id="" v-model="option">
<option value="前端开发">前端开发</option>
<option value="后端开发">后端开发</option>
<option value="c++开发">c++开发</option>
<option value="算法工程师">算法工程师</option>
<option value="嵌入式工程师">嵌入式工程师</option>
</select>
{{option}}<br><br>

</div>
<script src="./lib/vue.js"></script>
<script>
Vue.config.productionTip = false

const vm = new Vue({
el: '#app',
data: {
msg:'msg',
text: '袁同学!',
number:5,
list:['长沙'],
sex:'男',
option:'前端开发'
}
})
</script>