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

944492468-5e7331608cda8.png
View层:视图层
在前端开发中,通常就是DOM层。主要的作用是给用户展示各种信息。
Model层:数据层
数据可能是我们固定的死数据,更多的是来自我们服务器,从网络上请求下来的数据。
VueModel层:视图模型层
视图模型层是View和Model沟通的桥梁。
一方面它实现了Data Binding,也就是数据绑定,将Model的改变实时的反应到View中。
另一方面它实现了DOM Listener,也就是DOM监听,当DOM发生一些事件(点击、滚动、touch等)时,可以监听到,并在需要的情况下改变对应的Data。

MVVM框架的三大要素

  • 响应式:组件data的数据一旦变化,立刻触发视图的更新。
  • 模板引擎:Vue的模板如何被解析,指令如何处理
  • 渲染:Vue的模板如何被渲染成html,渲染过程是怎样的

响应式原理

响应式原理:组件data的数据一旦变化,立刻触发视图的更新。
响应式原理.png

注意事项:
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的生命周期

生命周期2.png
图片1.png
创建阶段
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 中可能会做哪些事情?

  • 及时解绑自定义事件。
  • 解除绑定
  • 销毁子组件以及事件监听器

梁柱
135 声望12 粉丝