Vue引入
1. Vue.js
Vue是一个渐进式的框架,渐进式意味着你可以将Vue作为你应用的一部分嵌入其中。
2. Vue 安装
方式一:直接CDN引入
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!-- 生产环境版本,优化了尺寸和速度 -->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
方式二:下载和引入
开发环境 https://vuejs.org/js/vue.js
生产环境 https://vuejs.org/js/vue.min.js
方式三:NPM安装
3. Vue的options
在创建Vue实例的时候,传入了一个对象options。options中可以包含的选项:
el:
类型:string | HTMLElement
作用:决定之后Vue实例会管理哪一个DOM。
data:
类型:Object | Function (组件当中data必须是一个函数)
作用:Vue实例对应的数据对象。
methods:
类型:{ [key: string]: Function }
作用:定义属于Vue的一些方法,可以在其他地方调用,也可以在指令中使用。
Vue中的MVVM
View层:视图层
在前端开发中,通常就是DOM层。主要的作用是给用户展示各种信息。
Model层:数据层
数据可能是我们固定的死数据,更多的是来自我们服务器,从网络上请求下来的数据。
VueModel层:视图模型层
视图模型层是View和Model沟通的桥梁。
一方面它实现了Data Binding
,也就是数据绑定,将Model的改变实时的反应到View中。
另一方面它实现了DOM Listener
,也就是DOM监听,当DOM发生一些事件(点击、滚动、touch等)时,可以监听到,并在需要的情况下改变对应的Data。
MVVM框架的三大要素
- 响应式:组件
data
的数据一旦变化,立刻触发视图的更新。 - 模板引擎:
Vue
的模板如何被解析,指令如何处理 - 渲染:
Vue
的模板如何被渲染成html
,渲染过程是怎样的
响应式原理
响应式原理:组件data的数据一旦变化,立刻触发视图的更新。
注意事项:
Vue无法检测到对象属性的添加或删除。由于 Vue 会在初始化实例时对属性执行 getter/setter 转化,所以属性必须在 data 对象上存在才能让 Vue 将它转换为响应式的。
var vm = new Vue({
data:{
a:1
}
})
// `vm.a` 是响应式的
vm.b = 2
// `vm.b` 是非响应式的
可以使用 Vue.set(object, propertyName, value) 方法向嵌套对象添加响应式属性。
Vue.set(vm.someObject, 'b', 2)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<p>{{ message }}</p>
<p>{{ message }}</p>
<p>{{ message }}</p>
</div>
<script>
new Vue({
el: '#app',
data: {
message: 'Hello Vue.js!'
}
})
</script>
</body>
</html>
响应式原理涉及两方面的问题:
1.如何跟踪变化?(app.message修改数据,Vue内部是如何监听message数据的变化?)
答:通过Object.defineProperty来监听对象属性的变化。
Vue 将遍历data对象所有的属性,并使用 Object.defineProperty 把这些属性全部转为 getter/setter。为每一个属性指定一个dep(发布者)对象
//伪代码解释
Object.keys(obj).forEach(key => {
let value = obj[key];
Object.defineProperty(obj, key, {
//通过解析html代码,获取哪些人在使用该属性
//const dep = new Dep();
set(v) {
value = v;
//当数据发生变化时,调用dep.notify()通知该属性的所有订阅者,更新他们自己的update()。
},
get() {
//谁调用了get(),就为谁创建一个watcher(订阅者)
// const w1 = new Watcher("张三");
// dep.push(w1) // 把该订阅者添加到属性对应的发布者中。
return value;
}
})
});
2.当数据发生改变,Vue是如何知道要通知哪些人?
答:通过发布者订阅者模式:谁调用了某个属性的get()
,就为谁创建一个watcher(订阅者)
,将所有的订阅者(watcher)
添加到发布者(Dep)
里面,当发布者(Dep)
调用自己的notify()
,就立即通知所有的订阅者(watcher)
更新他们自己的update()
。
//发布者订阅者
//发布者
class Dep {
constructor() {
this.subs = []
}
addSub(watcher) {
this.subs.push(watcher);
}
notify() {
this.subs.forEach(item => {
item.update();
})
}
}
//订阅者
class Watcher {
constructor(name) {
this.name = name;
}
update() {
console.log(`${this.name}发生update`);
}
}
Vue的生命周期
创建阶段
beforeCreate()
created()
挂载阶段
beforeMount()
mounted()
更新阶段
beforeUpdate()
updated()
销毁阶段
beforeDestroy()
destroyed()
created(初始化) 和mounted(渲染) 有什么区别?
created
是指实例化了vue后存于js内存中的一个变量.页面还没有被渲染。 mounted
是页面渲染完成了。
父子组件生命周期调用顺序
父beforeCreate → 子beforeCreate → 父created → 子created → 子mounted → 父mounted → 父 beforeUpdate → 子beforeUpdate → 子updated → 父updated → 父beforeDestory → 子beforeDestroy → 子destroyed → 父destroyed
在 创建、挂载、更新、销毁阶段,总是父组件先开始,子组件先完成。
在beforeDestroy 中可能会做哪些事情?
- 及时解绑自定义事件。
- 解除绑定
- 销毁子组件以及事件监听器
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。