一、Vue简介
1.Vue是一个响应式的web视图层框架
响应式: 我们写代码只关注数据,视图随数据变化而变化。
视图层:UI层面的内容
框架和库:
框架是整个应用程序的设计方案,我们要做到一些功能,就必须遵照框架的规则去实现
库是很多方法的集合,是项目中功能的解决方案。我们要实现一些功能,可以自主的去调用库里的方法,还可以自己去定义一个方法实现。
2.MVVM(Model-View-ViewModel)
Model-数据结构 View-视图
- 数据会绑定在ViewModel层并自动渲染到页面中
- 视图发生变化时,会通知ViewModel更新数据
面试题:MVC? Model-View-Controller语义化模板
3.Vue中MVVM写法(vue是如何利用mvvm思想进行项目开发 ?)
数据双向绑定
- 利用花括号,构筑了数据与视图的绑定 —— 若干正则
- 通过视图绑定事件,来处理数据
二、生命周期
beforeCreate => created => beforeMount => mounted => beforeUpdate => updated => beforeDestroy => destroyed
bC: new Vue() - 实例挂载功能 c: data、props、method、computed - 数据操作、不涉及到vdom和dom
bM: vDom - 数据操作,但是不可涉及dom m: Dom - 任何操作
bU: vDom更新了的,dom未更新是旧的 - 可以更新数据 u: dom已经更新了 — 谨慎操作数据
bD: 实例vm尚未被销毁 — 清空eventBus、reset store、clear计时器 d: 实例已经被销毁 - 收尾
三、定向监听(computed 和 watch)
1.相同点:
- 基于vue的依赖收集机制
- 都是被依赖的变化触发,进行改变进而进行处理计算
2.不同点:
入和出
- computed: 多入单出 —— 多个值变化,组成一个值的变化
- watch: 单入多出 —— 单个值的变化,进而影响一系列的状态变更
性能
- computed: 会自动diff依赖,若依赖没有变化,会改从缓存中读取当前计算值
- watch: 无论监听值变化与否,都会执行回调
写法上
- computed: 必须有return返回值,并且computed的值不用在data里面声明
- watch: 不一定
时机上
- computed: 从首次生成赋值,就开始计算运行了
- watch: 首次不会运行,除非——immediate:true
computed使用
<div id="app">
<p>{{message}}</p>
<input v-model="message"></input>
<input v-model="message2"></input>
<p v-if="getLen">长度大于11</p>
<p v-else>长度小于等于11</p>
<p>{{len()}}</p>
</div>
<script>
new Vue({
el: '#app',
data: {
message: 'Hello-World',
message2: 'Hello-World2'
},
computed: {
getLen: function () {
console.log('computed')
return this.message.length > 11;
}
},
methods: {
len: function() {
console.log('function')
return this.message.length;
}
}
})
</script>
执行上述代码可见
1.改变message,computed和function都会触发
2.改变message1,computed不会触发,而function依旧会触发
所以,computed只会在依赖发生改变时触发更新值。
组件
<div id="app">
<hello-world v-for="item in items" :item="item"></hello-world>
</div>
<script>
Vue.component('hello-world', {
props: ['item'],
render: function(createElement) {
return createElement('p', this.item)
}
})
new Vue({
el: '#app',
data: {
items: [1,2,3,4,5,6],
},
})
</script>
四、条件指令 v-if & v-show & v-else & v-else-if
v-if 无dom,不会渲染实际节点及其子节点 v-show 存在实际节点及其子节点,但不展示,不占据位置
循环
面试题: v-for 和 v-if 循优先级 v-for > v-if 先循环 再判断 key的作用:
- 模板编译原理 —— template => dom template => 正则匹配语法 —— 生成AST:静态 + 动态 => 转换AST为可执行方法 => render() => dom
dom diff
[1 2 3 4 5 6]
[6 5 7 3 2 1]
层级:只考虑单层复用,多层级遍历实现
顺序:双向指针,首尾向中间移动
替换:移动、新增、删除 优先复用 —— key => 快速识别顺序
- key作用 —— 尽可能复用节点 常见问题:尽量不用index做key、随机数做key
五、常用指令
1.v-bind绑定属性
<div id="app">
<p v-bind:title="title">{{message}}</p>
<!-- 缩写格式 -->
<p :title="title">{{message}}</p>
</div>
<script>
new Vue({
el: '#app',
data: {
message: 'hello-world',
title: 'world-title',
},
})
</script>
2.v-on绑定事件
使用
<div id="app">
<p v-on:click="changeMessage()">{{message}}</p>
<!-- 缩写格式 -->
<p @click="changeMessage()">{{message}}</p>
</div>
<script>
new Vue({
el: '#app',
data: {
message: 'hello-world',
},
methods: {
changeMessage: function() {
if (this.message === 'hello-world') {
this.message = 'world';
} else {
this.message = 'hello-world'
}
}
}
})
事件修饰符
.stop .prevent .capture .self .once .passive
按钮修饰符
enter delete
事件设计 - 为何vue把事件写在模板上,而不是js中
模板定位事件触发源 + 触发源寻找触发事件逻辑 —— 更方便定位问题 js与事件本身解耦 —— 更便于测试隔离 viewModel销毁,自动解绑事件 —— 更便于回收
3.v-model双向绑定,语法糖
<div id="app">
<p v-for="item in items">{{item}}</p>
</div>
<script>
new Vue({
el: '#app',
data: {
items: [1,2,3,4,5,6],
},
})
</script>
4.v-once - 只渲染一次
5.v-text - 渲染字符串
<div id="app">
<p v-text="text"></p>
</div>
<script>
new Vue({
el: '#app',
data: {
text: 'Hello-World'
},
})
</script>
6.v-html
<div id="app" v-html="html">
</div>
<script>
new Vue({
el: '#app',
data: {
html: '<p>Hello-World</p>'
},
})
</script>
7.自定义指令
directives:{
output: {
update: function() {
...
}
}
}
<div v-output/>
v-model重配置
:value + @input
model: {
prop: 'selected',
event: 'change'
}