初始vue(上)

初识Vue

vue是什么?

image-20230820110850516.png

在vue官网的简介是:用于 构建用户界面1 的 渐进式2 框架3

image-20230820111223712.png

构建用户界面:基于数据动态渲染出用户看到的页面

渐进式:循序渐进逐步学习,使用

框架:一套完整的项目解决方案,可以极大地提高开发的效率

既然那么好用,让我们来盘一盘这个vue

vue中的MVVM

image-20230826201735352.png

  • M指的是model(模型),对应data中的数据。
  • V指的是view(视图),一个展示用户界面的模板,可以简单的理解为HTML标签页面。
  • MV指的是ViewModel(视图模层),它是Vue的实例对象,一个连接view和model的桥梁,负责把model对象封装成可以显示和接受输入的界面对象。

vue的基本使用

核心步骤(4步):

  1. 准备容器

  2. 引包(官网) — 开发版本/生产版本

  3. 创建Vue实例 new Vue()

  4. 指定配置项,渲染数据

    1. el:指定挂载点
    2. data提供数据

创建vue实例,初始化渲染

image-20230820115249589.png

来到vue2的官网看看该如何使用

vue2

依照上面的顺序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//准备容器 (Vue所管理的范围)
       <div id="app">{{ message }}</div>
      //引包 (开发版本包 / 生产版本包) 官网
       <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
       <script>
           //创建实例
           const box = new Vue({
             // 制定 vue 托管的区域
               el: '#app',
               // 渲染的数据
               data: {
                   message: 'Hello Vue!'
              }
          })

这样的话data里面的数据就被渲染到页面上了

只能渲染由vue托管的区域,没有托管的区域不会动态渲染

插值表达式

数据绑定最常见的形式就是使用Mustache语法 (小胡子语法) 的文本插值

作用:利用表达式进行插值,渲染到页面上

语法:{{ 表达式}}

<span>Message: {{ msg }}</span>

所谓的表达式,就是一段可以被求值的代码,js引擎会将其计算并最终得出一个结果

money + 100
money - 100
money * 10
money / 10 
price >= 100 ? '真贵':'还行'
obj.name
arr[0]
fn()
obj.fn()

以上这些都是表达式

可以简单的直接渲染数据,既然支持表达式那么也可以往里面写一些复杂的计算表达式,就像这样

<h3>{{title}}<h3>
<p>{{nickName.toUpperCase()}}</p>
<p>{{age >= 18 ? '成年':'未成年'}}</p>
<p>{{obj.name}}</p>
<p>{{fn()}}</p>

当msg里面的数据发生变化的时候,对应页上的信息也会进行动态的渲染和更新

通过使用 v-once 指令,你也能执行一次性地插值,当数据改变时,插值处的内容不会更新。但请留心这会影响到该节点上的其它数据绑定:

<span v-once>这个将不会改变: {{ msg }}</span>

注意:

数据必须存在

插值表达式,只能支持表达式,而非语句: if ,for…

不能够在标签中使用

响应式特性

当data里面的数据发生变化的时候,对应页上的信息也会进行动态的渲染和更新

image-20230820124523229.png

data中的数据, 最终会被添加到实例上

① 访问数据: “实例.属性名”

② 修改数据: “实例.属性名”= “值”

vue指令

v-html

作用:设置元素的innerHTML

语法: v-html = 表达式

双大括号会将数据解释为普通文本,而非 HTML 代码。为了输出真正的 HTML,你需要使用 v-html 指令

 <div id="app">
    <div v-html="msg"></div>
      </div>
       <script> 
           const app = new Vue({
         el: '#app',
          data: {
                msg: '<h1>燕子,你别走!!!没了你我可怎么活啊!</h1>'
               }
           })
       </script>

v-if

image-20230820130841220.png

v-if 底层原理:通过创建 / 删除 dom 元素来实现盒子的显示隐藏,当表达式的值为 true 时就显示,为 false 时就隐藏

适用于初始状态就决定了显示隐藏的场景

v-show

v-show 底层原理: 通过设置 display:none,来改变盒子的显示隐藏

当表达式的值为 true 时就显示,为 false 时就隐藏

适用于频繁切换显示隐藏的场景

v-else ,v-else-if

  1. 作用:辅助v-if进行判断渲染
  2. 语法:v-else v-else-if=”表达式”
  3. 需要紧接着v-if使用
  <div id="app">
    <p v-if="gender===0">性别:♂ 男</p>
    <p v-else>性别:♀ 女</p>
    <hr>
    <p v-if="score>=90">成绩评定A:奖励电脑一台</p>
    <p v-else-if="score>=70">成绩评定B:奖励周末郊游</p>
    <p v-else-if="score>=60">成绩评定C:奖励零食礼包</p>
    <p v-else>成绩评定D:惩罚一周不能玩手机</p>
  </div>
​
  <script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script>
  <script>
    // 目标:
    // 1. 根据条件渲染姓名
    // 2. 根据成绩来渲染奖励
    const app = new Vue({
      el: '#app',
      data: {
        gender: 0,
        score: 95
      }
    })
  </script>

image-20230820134529444.png

v-on

作用: 注册事件 = 添加监听 + 处理逻辑

语法:

  1. v-on :事件名 = “内联语句”
  2. v-on: 事件名 = “methods中的函数名”

简写形式

@事件名

        <div id="app">
            <button @click={{count--}}>-</button>
            <span>{{ count }}</span>
            <button @click={{count++}}>+</button>
        </div>
        <script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script>
        <script>
            // 目标: 点击 - 让数字减一, 点击 + 让数字加一
            const app = new Vue({
                el: '#app',
                data: {
                    count: 100
                }
            })
        </script>

methods 中存放函数

只要是定义在 methods 中的函数,最终都会放到实例对象上,所以内部的 this 指向实例对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
  <div id="app">
   <button @click="isShow = !isShow">切换显示隐藏</button>
   <button @click="change">切换显示隐藏</button>
   <h1 v-show="isShow">我又出来了</h1>
 </div>
 <script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script>
 <script>
   /**
    * 目标:
    *   点击切换 h1 标签显示隐藏
    */
   const app = new Vue({
     el: '#app',
     data: {
       isShow: true
    },
     methods: {
       change() {
         this.isShow = !this.isShow
      }
    }
  })

v-on调用传参

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
  <div id="app">
           <div class="box">
               <h3>小黑自动售货机</h3>
               <button @click="buy(5)">可乐5元</button>
               <button @click="buy(10)">咖啡10元</button>
           </div>
           <p>银行卡余额:{{ money }}元</p>
       </div>

       <script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script>
       <script>
           /**
            * 目标:
            * 点击不同按钮, 银行卡余额减少对应的金额
            */
           const app = new Vue({
               el: '#app',
               data: {
                   money: 100
              },
               methods: {
                   buy(price) {
                       this.money -= price
                  }
              }
          })

v-bind

作用:动态设置标签的属性值

语法: v-bind:属性名=”表达式”

简写:

:属性名 = “表达式”

以下是一些常见的HTML标签属性

1.src 属性(用于图像、音频、视频等):

<img :src="imageSource">
<audio :src="audioSource"></audio>
<video :src="videoSource"></video>

2.href 属性(用于链接):

<a :href="externalLink">Visit Website</a>

3.title 和 alt 属性(用于提示信息):

<img :title="imageTitle" :alt="imageAlt" src="imageSource">

4.disabled 属性(用于禁用表单元素):

<button :disabled="isDisabled">Submit</button>

5.placeholder 属性(用于表单元素的占位符文本):

<input :placeholder="inputPlaceholder">

6.value 属性(用于表单元素的值):

<input :value="inputValue">

7.readonly 属性(用于设置表单元素为只读):

<input :readonly="isReadOnly">

8.checked 属性(用于复选框和单选按钮):

<input type="checkbox" :checked="isChecked">
<input type="radio" :checked="isSelected">

9.data-属性(用于存储自定义数据):

<div :data-custom-value="customData"></div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 <div id="app">
   <img :src="imgUrl" :title="msg" alt="">
 </div>
 <script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script>
 <script>
   /**
    * 目标:
    * 使用 v-bind 指令动态绑定标签属性
    */
   const app = new Vue({
     el: '#app',
     data: {
       imgUrl: './imgs/10-02.png',
       msg: 'hello'
    }
  })

v-bind 操作 class 类名

语法 :class =”{对象}”

设置对象使用布尔值控制是否使用这个类名,比较常用动态设置类名

1
2
3
4
5
6
7
8
9
10
11
12
<div id="app">
   <div class="box" :class="{pink:flag}">键盘敲烂,月薪过万</div>
       </div>
       <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
       <script>
           const app = new Vue({
               el: '#app',
               data: {
                   flag: true
              }
          })
       </script>

语法 :class=”[数组]”

使用数组一次性设置多个类名,或删除多个类名

1
2
3
4
5
6
7
8
9
10
11
12
<div id="app">
           <div class="box" :class="['pink','big']">今天天气真不挫!</div>
       </div>
       <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
       <script>
           const app = new Vue({
               el: '#app',
               data: {
                   flag: true
              }
          })
       </script>

v-bind 操作 style 类名

语法 :style = “{ 样式属性 }”

1
2
3
4
5
6
7
8
9
10
11
12
  <div id="app">
   <div class="box" :style="{width: '50rem',height: '18.75rem'}"></div>
 </div>
 <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
 <script>
   const app = new Vue({
     el: '#app',
     data: {

    }
  })
 </script>

v-for

作用:基于数组循环,多次整个渲染整个元素

语法: v-for =”(item,index) in list”

  • item 是数组中的每一项
  • index 是每一项对应的索引,不需要可以省略
  • list是被遍历的数组
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
    const app = new Vue({
       el: '#app',
       data: {
          booksList: [
          { id: 1, name: '《红楼梦》', author: '曹雪芹' },
          { id: 2, name: '《西游记》', author: '吴承恩' },
          { id: 3, name: '《水浒传》', author: '施耐庵' },
          { id: 4, name: '《三国演义》', author: '罗贯中' }
          ]
            },
           methods: {
           del(id) {
           this.booksList =this.booksList.filter(item=> {
                         this.booksList = item.id !== id
                      })
                  }
              }
          })

key属性

当使用 v-for 来渲染一个列表时,Vue 需要一个唯一的 key 值来追踪每个循环项。这有助于 Vue 在更新列表时识别出哪些项被添加、删除或移动了,从而提供更快速的 DOM 更新以及更精准的变化追踪。

1
2
3
4
5
6
7
<template>
 <ul>
   <li v-for="(item, index) in items" :key="item.id">
     {{ item.name }}
   </li>
 </ul>
</template>

v-modal

作用:双向数据绑定,快速获取或设置表单元素内容

什么是双向数据绑定?

Vue是一个MV VM框架, 即数据双向绑定, 即当数据发生变化的时候, 视图也就发生变化, 当视图发生变化的时候,数据也会跟着同步变化。这也算是Vue的精髓之处了。

v-model 会根据控件类型自动选取正确的方法来更新元素。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<div id="app">
   账户:<input type="text"> <br><br>
   密码:<input type="password"> <br><br>
   <button>登录</button>
   <button>重置</button>
 </div>
 <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
 <script>
   const app = new Vue({
     el: '#app',
     data: {
       username: '',
       password: ''
    },
  })
 </script>

1681913125738.png

复选框的数据绑定

复选框如果是一个为逻辑值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue 测试实例</title>
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
</head>
<body>
<div id="app">
 <p>单个复选框:</p>
 <input type="checkbox" id="checkbox" v-model="checked">
 <label for="checkbox">{{ checked }}</label>
</div>

<script>
new Vue({
 el: '#app',
 data: {
checked : false,
}
})
</script>
</body>
</html>

如果是多个则绑定到同一个数组,会把选中的选项里面的 value 值,添加到数组中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue 测试实例</title>
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
</head>
<body>
<div id="app">
 <p>多个复选框:</p>
 <input type="checkbox" id="runoob" value="苹果" v-model="checkedNames">
 <label for="runoob">苹果</label>
 <input type="checkbox" id="google" value="香蕉" v-model="checkedNames">
 <label for="google">香蕉</label>
 <input type="checkbox" id="taobao" value="荔枝" v-model="checkedNames">
 <label for="taobao">荔枝</label>
 <br>
 <span>选择的值为: {{ checkedNames }}</span>
</div>

<script>
new Vue({
 el: '#app',
 data: {
   checkedNames: []
}
})
</script>
</body>
</html>

单选框的数据绑定

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<div id="app">
 <!-- 1.name: 给单选框加上 name 属性可以分组,同一组互相会互斥 -->
 <!-- 2.value: 给单选框加上 value 属性,用于提交给后台的数据 -->
 性别:
   <input v-model="gender" name="gender" value="male" type="radio">男
   <input v-model="gender" name="gender" value="female" type="radio">女
   <br><br>
</div>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.7.14/vue.js"></script>
<script>
 const app = new Vue({
   el: '#app',
   data: {
     gender: 'female',
  }
})
</script>

下拉菜单的数据绑定

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<div id="app">
 <!-- 1. option 需要设置 value 值,提交给后台 -->
 <!-- 2. select 的 value 值,关联了选中的 option 的 value 值 -->
 <!-- 注意: 下拉选择框使用 v-model 要绑定在 select 上 -->
 所在城市:
 <select v-model="city">
   <option value="beijing">北京</option>
   <option value="shanghai">上海</option>
 </select>
</div>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.7.14/vue.js"></script>
<script>
 const app = new Vue({
   el: '#app',
   data: {
     city: 'beijing',
  }
})
</script>

指令修饰符

1.v-model修饰符

.lazy

在默认情况下, v-model 在 input 事件中同步输入框的值与数据,但你可以添加一个修饰符 lazy ,从而转变为在 change 事件中同步:

<!-- 在 "change" 而不是 "input" 事件中更新 -->
<input v-model.lazy="msg" >

.number

如果想自动将用户的输入值转为 Number 类型(如果原值的转换结果为 NaN 则返回原值),可以添加一个修饰符 number 给 v-model 来处理输入值:

<input v-model.number="age" type="number">

.trim

如果要自动过滤用户输入的首尾空格,可以添加 trim 修饰符到 v-model 上过滤输入:

<input v-model.trim="msg">

2.按键修饰符

Vue 允许为 v-on 在监听键盘事件时添加按键修饰符:

<!-- 只有在 keyCode 是 13 时调用 vm.submit() -->
<input v-on:keyup.13="submit">

记住所有的 keyCode 比较困难,所以 Vue 为最常用的按键提供了别名:

<!-- 同上 -->
<input v-on:keyup.enter="submit">
<!-- 缩写语法 -->
<input @keyup.enter="submit">

全部的按键别名:

  • .enter
  • .tab
  • .delete (捕获 “删除” 和 “退格” 键)
  • .esc
  • .space
  • .up
  • .down
  • .left
  • .right

系统修饰键:

  • .ctrl
  • .alt
  • .shift
  • .meta

鼠标按钮修饰符:

  • .left
  • .right
  • .middle

3.事件修饰符

Vue 为 v-on 提供了事件修饰符来处理 DOM 事件细节,如:event.preventDefault() 或 event.stopPropagation()。

Vue 通过由点 . 表示的指令后缀来调用修饰符。

  • .stop - 阻止冒泡
  • .prevent - 阻止默认事件
  • .capture - 阻止捕获
  • .self - 只监听触发该元素的事件
  • .once - 只触发一次
  • .left - 左键事件
  • .right - 右键事件
  • .middle - 中间滚轮事件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!-- 阻止单击事件冒泡 -->
<a @click.stop="doThis"></a>
<!-- 提交事件不再重载页面 -->
<form @submit.prevent="onSubmit"></form>
<!-- 修饰符可以串联 -->
<a @click.stop.prevent="doThat"></a>
<!-- 只有修饰符 -->
<form @submit.prevent></form>
<!-- 添加事件侦听器时使用事件捕获模式 -->
<div @click.capture="doThis">...</div>
<!-- 只当事件在该元素本身(而不是子元素)触发时触发回调 -->
<div @click.self="doThat">...</div>

<!-- click 事件只能点击一次,2.1.4版本新增 -->
<a @click.once="doThis"></a>

计算属性 computed

计算属性,字如其名,首先它是属性,其次有计算的“功能”

说的官方一点:计算属性就是当其依赖属性的值发生变化时,这个属性的值会自动变化,与之相关的DOM部分也会同步自动更新。

在computed配置项中添加我们的计算属性,在属性里面写我们的逻辑代码

注意:计算属性其实是属性,在页面上使用只需要用属性值,不要带(),不然就变成方法了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<div id="app">
   <h3>小黑的礼物清单</h3>
   <table>
     <tr>
       <th>名字</th>
       <th>数量</th>
     </tr>
     <tr v-for="(item, index) in list" :key="item.id">
       <td>{{ item.name }}</td>
       <td>{{ item.num }}个</td>
     </tr>
   </table>

   <!-- 目标:统计求和,求得礼物总数 -->
   <p>礼物总数:{{totalCount}} 个</p>
 </div>
 <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
 <script>
   const app = new Vue({
     el: '#app',
     data: {
       // 现有的数据
       list: [
        { id: 1, name: '篮球', num: 1 },
        { id: 2, name: '玩具', num: 2 },
        { id: 3, name: '铅笔', num: 5 },
      ]
    },
     computed: {
       totalCount() {
         return this.list.reduce((sum,item)=>sum+item.num,0)
      }
    }
  })
计算属性computedmethods的区别

computed是一个方法,而methods里面也是一个方法,那么他们之间的区别是什么呢?

我们可以使用 methods 来替代 computed,效果上两个都是一样的,但是 computed 是基于它的依赖缓存,只有相关依赖发生改变时才会重新取值。而使用 methods ,在重新渲染的时候,函数总会重新调用执行。

我们可以通过多次调用,打印出来看看结果有什么不一样

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
 <div id="app">
   <h3>小黑的礼物清单🛒<span>?</span></h3>
   <table>
     <tr>
       <th>名字</th>
       <th>数量</th>
     </tr>
     <tr v-for="(item, index) in list" :key="item.id">
       <td>{{ item.name }}</td>
       <td>{{ item.num }}个</td>
     </tr>
   </table>

   <p>礼物总数:{{ getNum() }} 个</p>
   <p>礼物总数:{{ getNum() }} 个</p>
   <p>礼物总数:{{ getNum() }} 个</p>
   <p>礼物总数:{{ getNum() }} 个</p>
   <p>礼物总数:{{ getNum() }} 个</p>
 </div>
 <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
 <script>
   const app = new Vue({
     el: '#app',
     data: {
       // 现有的数据
       list: [
        { id: 1, name: '篮球', num: 3 },
        { id: 2, name: '玩具', num: 2 },
        { id: 3, name: '铅笔', num: 5 },
      ]
    },
     computed: {
       totalCount () {
         console.log('我是 computed 里的求和属性');
         let total = this.list.reduce((sum, item) => sum + item.num, 0)
         return total
      }
    },
     methods: {
       getNum() {
         console.log('我是 methods 里的求和属性');
         return this.list.reduce((sum, item) => sum + item.num, 0)
      }
    }
  })

image-20230823114418161.png

可以清晰地看到,用methods方法数据每更新一次就会被调用一次,而computed方法只被调用了一次

优点:计算属性最重要的特性: 带缓存

在第一次使用了该属性时进行计算,计算完了后他就会把结果存起来,后面有用到会直接在缓存里面把结果取出来

只在相关响应式依赖发生改变(相关的属性变化)时它们才会重新求值

这样做的主要目的也是为了提高性能

计算属性的完整写法

计算属性都包含有一个get和一个set,计算属性会默认使用 get函数,如果你要使用 set函数,那么你必须要手动写出 set 函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
    const app = new Vue({
     el: '#app',
     data: {
       firstName: '李',
       lastName: '雷',
    },
     methods: {
       change() {
         this.fullName = '韩梅梅'
      }
    },
     computed: {
       fullName: {
         // 当访问这个计算属性时, get 函数会自动执行,并将返回值作为计算属性的值
        get() {
         return this.firstName + this.lastName
        },
       // 当修改这个计算属性时, set 函数会自动执行, 并将修改的新值作为参数传递过来
        set(val) {
         this.firstName = val.substring(0,1)
         this.lastName = val.substring(1)
        }
      }
    }
  })

watch侦听器

作用:监视数据变化,执行业务逻辑或是异步操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
            const app = new Vue({
               el: '#app',
               data: {
                   words: ''
              },
               watch: {
                   //要监听什么数据,就以什么数据命名,定义函数
                   // 该函数会在数据变化时自动执行,并携带两个参数
                   // 参数一:新值
                   // 参数二:旧值 ,不常用
                   words(newValue,oldValue) {
                       console.log(value)
                  }
              }
             
          })

完整写法:

  • deep: true 对复杂类型深度监视
  • immediate: true 初始化立刻执行一次handler方法
1
2
3
4
5
6
7
8
9
watch: {// watch 完整写法
数据属性名: {
 deep: true, // 深度监视(针对复杂类型)
 immediate: true, // 是否立刻执行一次handler
 handler (newValue) {
console.log(newValue)
}
  }
}

生命周期

一个Vue实例从 创建销毁 的整个过程

vue的生命周期分为四个阶段:

①创建 ②挂载 ③更新 ④销毁

image-20230826115137667.png

Vue生命周期过程中,会自动运行一些函数,被称为【生命周期钩子】

这个时候我们就可以在【特定阶段】运行自己的代码

  1. 实例、组件通过new Vue() 创建出来之后会初始化事件和生命周期,然后就会执行beforeCreate钩子函数,这个时候,数据还没有挂载,只是一个空壳,无法访问到数据和真实的dom,一般不做操作
  2. 挂载数据,绑定事件等等,然后执行created函数,这个时候已经可以使用到数据,也可以更改数据,在这里更改数据不会触发updated函数,在这里可以在渲染前倒数第二次更改数据的机会,不会触发其他的钩子函数,一般可以在这里做初始数据的获取
  3. 接下来开始找实例或者组件对应的模板,编译模板为虚拟dom放入到render函数中准备渲染,然后执行beforeMount钩子函数,在这个函数中虚拟dom已经创建完成,马上就要渲染,在这里也可以更改数据,不会触发updated,在这里可以在渲染前最后一次更改数据的机会,不会触发其他的钩子函数,一般可以在这里做初始数据的获取
  4. 接下来开始render,渲染出真实dom,然后执行mounted钩子函数,此时,组件已经出现在页面中,数据、真实dom都已经处理好了,事件都已经挂载好了,可以在这里操作真实dom等事情…
  5. 当组件或实例的数据更改之后,会立即执行beforeUpdate,然后vue的虚拟dom机制会重新构建虚拟dom与上一次的虚拟dom树利用diff算法进行对比之后重新渲染,一般不做什么事儿
  6. 当更新完成后,执行updated,数据已经更改完成,dom也重新render完成,可以操作更新后的虚拟dom
  7. 当经过某种途径调用$destroy方法后,立即执行beforeDestroy,一般在这里做一些善后工作,例如清除计时器、清除非指令绑定的事件等等
  8. 组件的数据绑定、监听…去掉后只剩下dom空壳,这个时候,执行destroyed,在这里做善后工作也可以

image-20230826115225732.png

生命周期图示

20190725165224557.png

生命周期钩子 实例阶段 说明 能否获取到data 能否获取到 methods
beforeCreate 创建前 实例已初始化,但数据观测,watch/event 事件回调还未配置 NO NO
created 创建后 已完成如下配置,数据观测 (data observer),property 和方法的运算,watch/event 事件回调 NO OK
beforeMount 挂载前 dom已初始化,但并未挂载和渲染 OK OK
mounted 挂载后 dom已完成挂载和渲染 OK OK
beforeUpdate 更新前 数据已改变,但dom为更新 OK OK
updated 更新后 dom已更新 OK OK
beforeDestroy 销毁前 实例销毁前,实例仍然可用 OK OK
destroyed 销毁后 实例已销毁,所有指令被解绑,事件监听器被移除,子实例都被销毁 OK OK