初识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中的数据变化)

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
入门代码
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> <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.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 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>
|