分享一下我一年前端自学路上的学习笔记。
MVVM
- MVVM各字母的理解:
M--Model,VM--ViewModel,V--View
- Model是数据部分,View是视图部分,ViewModel就是他们两个之间的核心枢纽。Model和ViewModel,以及View和ViewModel之间是双向的。ViewModel负责Model到View的映射,同时也对View到Model的事件监听,这样我们Model会随着View触发事件而改变。
双向绑定
- 极简的双向绑定的实现
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>极简的双向绑定实现</title>
</head>
<body>
<input type="text" id="a"/>
<span id="b"></span>
<script>
var obj = {};
Object.defineProperty(obj, 'hello', {
set: function(newval) {
document.getElementById('a').value = newval;
document.getElementById('b').innerHTML = newval;
}
});
document.addEventListener('keyup', function(e) {
obj.hello = e.target.value;
})
</script>
</body>
</html>
上面就是极简的双向绑定的实现。代码运行效果为:在文本框输入文字的变化,span
中会显现相同的内容,在JS中或控制台修改obj.hello
的值,在视图中会得到响应的更新。
双向绑定原理
VUE中是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()
来劫持各个属性的set,get
,在数据变动时发布消息给订阅者,触发相应的监听回调。
- 当开始创建一个实例之后,
observe
将劫持监听各项属性,也就是observe
将所有的属性进行遍历,包括对其子属性对象也进行递归遍历,遍历完成后,在每个属性上都加上set,get
,数据变化就会触发set
,这样就实现劫持并监听各项属性。 - 在
observe
将劫持监听各项属性时,compile
会解析模板指令。将模板中的变量替换成数据,然后初始化渲染页面视图,同时对每个指令对应的节点绑定更新函数,添加监听数据的订阅者,一旦数据有变动,收到通知,更新视图。 Watcher
是Observer
和Compile
之间通信的桥梁。Watcher
将Compile
添加的订阅者添加到Dep
里,同时Observer
监听的到数据变化将会通知Dep
。当数据变化时,Observer
通知Dep
,Dep
通知Watcher
。Watcher
调用update()
方法,触发Compile
中绑定的回调,然后更新视图。这样就实现了双向绑定。
组件传值通信
- 父组件向子组件传值。父组件通过标签传值,子组件通过
props
接受 - 子组件向父组件传值。VUE只允许单项传递。子组件可以通过触发事件,将需要传的值作为$emit的第二个参数传递。父组件通过监听子组件触发事件,调用change方法从而改变数据。
- 非父子组件传值。通过eventHub来实现通信。所谓eventHub就是创建一个事件中心,相当于中转站,可以用它来传递事件和接收事件
VUE生命周期
简单说VUE生命周期就是VUE实例从创建到销毁的过程。VUE实例经历创建、初始化数据、模板编译/挂载、更新、销毁这几个过程,在这几个过程中有一系列的生命周期钩子函数与之对应。
- 实例创建之后,触发
beforeCreate
钩子函数。此时实例刚被创建,不能访问到data,methods
上的数据和方法。 - 实例进行初始化数据,也就是对
data
进行双向绑定,初始化方法。完成之后触发created
钩子函数,此时组件实例创建完成,属性也绑定成功,但还没有挂载到DOM
,不能访问$el
属性。 - 实例进行模板编译,将模板
template
编译成render
函数。然后触发beforeMount
钩子函数,此时还没有对数据进行渲染,我们访问到只是虚拟DOM
内容。 - 实例进行挂载,触发
mounted
钩子函数,这时就将数据渲染到真实DOM
上。 - 然后对我们对数据进行更新,触发
beforeUpdate
钩子函数,重新渲染虚拟DOM
,对比差异,然后更新真实DOM
,触发updated
钩子函数。此时元素真实DOM
内容就已经更新改变了。 - 然后我们对组件进行销毁,触发
beforeDestroy
钩子函数。进行销毁数据监听,销毁子组件,解除事件监听。销毁后触发destroy
钩子函数,此时组件已经被销毁,但它的DOM和属性方法都还存在,只是我们改变它们不会在生效。
vue生命周期的作用是什么?
它的生命周期中有多个事件钩子,让我们在控制整个Vue实例的过程时更容易形成好的逻辑。
vue生命周期总共有几个阶段?
它可以总共分为8个阶段:创建前/后, 载入前/后,更新前/后,销毁前/销毁后
第一次页面加载会触发哪几个钩子?
第一次页面加载时会触发 beforeCreate, created, beforeMount, mounted
这几个钩子
DOM 渲染在 哪个周期中完成?
DOM 渲染在 mounted 中完成
简单描述每个周期具体适合哪些场景?
生命周期钩子的一些使用方法:
beforecreate
: 可以在这加个loading事件,在加载实例时触发
created
: 初始化完成时的事件写在这里,如在这结束loading事件,异步请求也适宜在这里调用
mounted
: 挂载元素,获取到DOM节点
updated
: 如果对数据统一处理,在这里写上相应函数
beforeDestroy
: 可以做一个确认停止事件的确认框
VUE基础知识
- 计算属性 放在computed中
- v-bind:class :class 绑定
- v-if v-else-if v-else 条件渲染
- v-for 列表渲染
- v-on:click @click 事件处理
- v-model 双向绑定
- vue-router 页面跳转
- vuex 状态管理
this.$store.dispatch() //修改数据 this.$store.state //获取数据
- vue-resource 请求
this.$http.get() this.$http.post()
- slot 插槽
- mint UI 移动组件库
- assets文件夹是放静态资源;components是放组件;router是定义路由相关的配置;view视图;app.vue是一个应用主组件;main.js是入口文件