1️⃣ 创建一个 Vue 实例

image.png
每个 Vue 应用都是通过用 Vue 函数创建一个新的 Vue 实例开始的

  1. 1. el:方式是在创建时直接挂载实例对象
  2. 2. $mount:手动挂载实例,可以在挂载之前处理一些事情,处理后在挂载
  1. // el - 自动挂载
  2. const vm = new Vue({
  3. el: "#app",
  4. })
  5. // $mount - 手动挂载
  6. const vm = new Vue({})
  7. vm.$mount()

image.png

2️⃣ vm.$options

用于当前 Vue 实例的初始化选项。需要在选项中包含自定义 property 时会有用处:

  1. new Vue({
  2. customOption: 'foo', // 自定义选项
  3. created: function () {
  4. console.log(this.$options.customOption) // => 'foo'
  5. }
  6. })

image.png

1️⃣ 数据与方法

  1. // 非组件可以使用 data 对象
  2. const vm = new Vue({
  3. el: "#app",
  4. data: {}
  5. })
  6. // 组件内必须使用 data 函数( 组件内使用 data 函数是为了防止组件被复用时 data 数据互相影响 )
  7. vm.template('my-component', {
  8. data() {
  9. return {}
  10. },
  11. })

当一个 Vue 实例被创建时,Vue 将会递归将 data 的 property 转换为 getter/setter,从而让 data 的 property 能够响应数据变化,data 应该只能是数据 - 不推荐观察拥有状态行为的对象。当这些 property( 属性 ) 的值发生改变时,视图将会产生“响应”,即匹配更新为新的值。
当 data 中的数据改变时,视图会进行重渲染。值得注意的是只有当实例被创建时就已经存在于 data 中的 property 才是响应式的。也就是说如果你添加一个新的 property,那么对新的 property 的改动将不会触发任何视图的更新。
如果你知道你会在晚些时候需要一个 property,但是一开始它为空或不存在,那么你仅需要设置一些初始值.
当一个组件被定义,data 必须声明为返回一个初始数据对象的函数,因为组件可能被用来创建多个实例。如果 data 仍然是一个纯粹的对象,则所有的实例将共享引用同一个数据对象!通过提供 data 函数,每次创建一个新实例后,我们能够调用 data 函数,从而返回初始数据的一个全新副本数据对象。

2️⃣ 不需要响应式的数据应该怎么处理

在我们的 Vue 开发中,会有一些数据,从始至终都未曾改变过,这种死数据,既然不改变,那也就不需要对他做响应式处理了,不然只会做一些无用功消耗性能,比如一些写死的下拉框,写死的表格数据,这些数据量大的死数据,如果都进行响应式处理,那会消耗大量性能。

  1. // 方法一:将数据定义在data之外
  2. data () {
  3. this.list1 = { xxx }
  4. this.list2 = { xxx }
  5. this.list3 = { xxx }
  6. this.list4 = { xxx }
  7. this.list5 = { xxx }
  8. return {}
  9. }
  10. // 方法二:Object.freeze()
  11. data () {
  12. return {
  13. list1: Object.freeze({xxx}),
  14. list2: Object.freeze({xxx}),
  15. list3: Object.freeze({xxx}),
  16. list4: Object.freeze({xxx}),
  17. list5: Object.freeze({xxx}),
  18. }
  19. }

1️⃣ 虚拟 DOM 树

直接操作真实的 DOM 会引发严重的效率问题,vue 使用虚拟 DOM(vnode)的方式来描述要渲染的内容
vnode 是一个普通的 JS 对象,用于描述界面上应该有什么,比如:

  1. var vnode = {
  2. tag: "h1",
  3. children: [
  4. { tag: undefined, text: "第一个vue应用:Hello World"}
  5. ]
  6. }

上面的对象描述了:

有一个标签名为 h1 的节点,它有一个子节点,该子节点是一个文本,内容为【 第一个vue应用:Hello World 】

vue 模板并不是真实的 DOM,它会被编译为虚拟 DOM

  1. <div id="app">
  2. <h1>第一个vue应用:{{title}}</h1>
  3. <p>作者:{{author}}</p>
  4. </div>

上面的模板会被编译为类似下面结构的虚拟 DOM

  1. {
  2. tag: "div",
  3. children: [
  4. { tag: "h1", children: [ { text: "第一个vue应用:Hello World" } ] },
  5. { tag: "p", children: [ { text: "作者:陈" } ] }
  6. ]
  7. }

虚拟 DOM 树会最终生成为真实的 DOM 树
image.png
当数据变化后,将引发重新渲染,vue 会比较新旧两棵 vnode tree,找出差异,然后仅把差异部分应用到真实 dom tree 中
image.png
可见,在 vue 中,要得到最终的界面,必须要生成一个 vnode tree
vue 通过以下逻辑生成 vnode tree:
image.png

1️⃣ 生命周期

2️⃣ 嵌套组件的创建和挂载生命周期钩子的执行顺序

父组件 —- beforeCreate
父组件 —- created

  1. 1. 父组件创建完成后,可以获取到自身的 data 数据,如果需要获取 data 数据发送请求这一步就可以做

父组件 —- beforeMount

  1. 1. 父组件挂载之前,可以获取到自身的 el 绑定信息

子组件 —- beforeCreate
子组件 —- created

  1. 1. 子组件创建完成后,可以获取到父组件传递过来的 prop 数据

子组件 —- beforeMount
孙子组件 —- beforeCreate
孙子组件 —- created

  1. 1. 孙子组件创建完成后,可以获取到子组件传递过来的 prop 数据

孙子组件 —- beforeMount
孙子组件 —- mounted
子组件 —- mounted
父组件 —- mounted

2️⃣ 更新的生命周期钩子执行顺序

父组件 —- beforeUpdate
子组件 —- beforeUpdate
子组件 —- updated
父组件 —- updated
lifecycle2.png