Vue

  |   0 评论   |   0 浏览

Vue

1.基本介绍

1.Vue 是什么?

  1. Vue (读音 /vjuː/,类似于 view) 是一个前端框架, 易于构建用户界面
  2. Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或项目整合
  3. 支持和其它类库结合使用
  4. 开发复杂的单页应用非常方便
  5. Vue 是 Vue.js 的简称

2.官网

https://cn.vuejs.org/

2.git地址

https://github.com/vuejs

2.MVVM

VUE 的 MVVM

image-20220710221434997

MVVM 思想(上图)

​ 1.M∶即 Model,模型,包括数据和一些基本操作

​ 2.V∶即View,视图,页面渲染结果

​ 3.VM∶即 View-Model,模型与视图间的双向操作(无需开发人员干涉)

​ 4.在 MVVM之前,开发人员从后端获取需要的数据模型,然后要通过 DOM 操作 Model 渲染到View 中。而后当用户操作视图,我们还需要通过 DOM获取 View 中的数据, 然后同步到Model 中。

5.而 MVVM中的VM 要做的事情就是把DOM 操作完全封装起来,开发人员不用再关心 Model 和View 之间是如何互相影响的

​ 6.只要我们 Model 发生了改变,View上自然就会表现出来

​ 7. 当用户修改了View,Model 中的数据也会跟着改变。。

​ 8.结果:把开发人员从繁琐的 DOM操作中解放出来,把关注点放在如何操作 Model上, 大 大提高开发效率

3.快速入门

1.官网文档

https://cn.vuejs.org/v2/guide/index.html

2.下载

https://cn.vuejs.org/v2/guide/installation.html

image-20220710221756011

3.需求分析/图解

  1. 需求: 初步体会 Vue.js 的数据绑定功能
  2. 体会 Vue.js 开发框架的主体结构

4.小技巧

小技巧:为了让 IDEA 识别 Vue 代码,需要安装插件 Vue.js

image-20220710221934631

5.代码实现

0. 需求说明/图解

1)使用 vue 完成显示

image-20220710230555999

  1. 创建新文件夹 D:\idea_java_projects\vue , 直接拖到 Idea 工具,使用 idea 打开
  2. 将下载好的 vue.js 拷贝到 D:\idea_java_projects\vue\vue.js
  3. 创建 D:\idea_java_projects\vue\vue_quick_start.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vue快速入门</title>
</head>
<body>
<!--
1. div元素不是必须的,也可以是其它元素,比如span,但是约定都是将vue实例挂载到div
2. 因为div更加适合做布局
3. id 不是必须为app , 是程序员指定,一般我们就使用app
-->
<div id="app">
    <!--
        1. {{message}} : 插值表达式
        2. message 就是从 model 的 data 数据池来设置
        3. 当我们的代码执行时,会到 data{} 数据池中去匹配数据, 如果匹配上, 就进行替换 , 如果没有匹配上, 就是输出空
    -->
    <h1>欢迎你{{message}}--{{name}}</h1>
</div>

<!--引入vue.js-->
<script src="vue.js">

</script>
<script>
    //创建vue对象
    let viewModel = new Vue({
        //创建的vue实例挂载到id=app的div
        el: "#app",
        //data{}表示数据池(model有了数据),有很多数据,以k-v的形式设置(根据业务需要来设置)
        data: {
            message: "Hello Vue",
            name: "llp"
        }
    })

    console.log("viewModel=>", viewModel);
    console.log(viewModel._data.message);
    console.log(viewModel._data.name);
    console.log(viewModel.name);
    console.log(viewModel.message);
</script>
</body>
</html>
  1. 完成测试

image-20220710231049095

6.Vue 数据绑定机制分析

  1. 通过查看浏览器的控制台, 可以分析 Vue 数据绑定机制/MVVM

image-20220711223923175

7.注意事项和使用细节

  1. 注意代码顺序,要求 div 在前,script 在后,否则无法绑定数据

    1. 从案例可以体会声明式渲染:Vue.js 采用简洁的模板语法来声明式地将数据渲染进 DOM 的系统, 做到数据和显示分离
    2. Vue 没有繁琐的 DOM 操作,如果使用 jQuery,我们需要先找到 div 节点,获取到 DOM 对象,然后进行节点操作, 显然 Vue 更加简洁

4.数据单向渲染

1.基本说明

1.v-bind 指令可以完成基本数据渲染/绑定

2.v-bind 简写形式就是一个冒号(:)

1.需求分析/图解

  1. 需求: 演示 v-bind 的使用, 可以绑定元素的属性(如图)

image-20220711230259252

2.代码实现

  1. 把准备好的 1.jpg 拷贝到 D:\idea_java_projects\vue\1.jpg

    1. 创建 D:\idea_java_projects\vue\单向数据渲染.html
<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>单向数据渲染</title>
</head>
<body>
<div id="app">
    <h1>{{message}}</h1>
    <!--
    1. 使用插值表达式引用 data数据池数据是在标签体内
    2. 如果是在标签/元素 的属性上去引用data数据池数据时,不能使用插值表达式
    3. 需要使用v-bind, 因为v-bind是vue来解析, 默认报红,但是不影响解析
    4. 如果不希望看到报红, 直接 alt+enter 引入 xmlns:v-bind
    -->
    <img src="{{img_src}}">
    <img v-bind:src="img_src" v-bind:width="img_width">
    <img :src="img_src" :width="img_width">
</div>
<script src="vue.js"></script>
<script>
    let vm = new Vue({
        el: "#app", //创建的vue实例挂载到 id=app的div
        data: { //data{} 表示数据池(model的有了数据), 有很多数据 ,以k-v形式设置(根据业务需要来设置)
            message: "hello, 耗子精",
            img_src: "1.jpg",
            img_width: "100px"
        }
    })
    console.log("vm=>", vm);
</script>
</body>
</html>

2.注意事项和使用细节

1.插值表达式是用在标签体的

2.如果给标签属性绑定值,则使用 v-bind 指令

5.数据双向绑定

1.基本说明v-model 可以完成双向数据绑定

2.应用实例

1.需求分析/图解

  1. 需求在输入框中输入信息,会更新到相应绑定的位置

image-20220711230932513

2.代码实现

  1. 创建 D:\idea_java_projects\vue\双向数据绑定.html
<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>双向数据渲染</title>
</head>
<body>
<div id="app">
    <h1>{{message}}</h1>
    <!--
    1. v-bind是数据单向渲染: data数据池绑定的数据变化,会影响view
    2. v-model="hobby.val" 是数据的双向渲染,
        (1)data数据池绑定的数据变化,会影响view 【底层的机制是 Data Bindings】
        (2)view 关联的的元素值变化, 会影响到data数据池的数据【底层机制是Dom Listeners】
    -->
    <!--双向绑定-->
    <input type="text" v-model="hobby.val"><br/><br/>

    <!--单向绑定简写 :属性 -->
    <input type="text" :value="hobby.val"><br/><br/>
    <!--单向绑定  v-bind:属性-->
    <input type="text" v-bind:value="hobby.val"><br/><br/>
    <p>你输入的爱好是: {{hobby.val}}</p>
</div>
<script src="vue.js"></script>
<script>
    let vm = new Vue({
        el: "#app", //创建的vue实例挂载到 id=app的div
        data: { //data{} 表示数据池(model的有了数据), 有很多数据 ,以k-v形式设置(根据业务需要来设置)
            message: "hi, 输入你的爱好",
            hobby: {
                val: "购物"
            }
        }
    })
    console.log("vm=>", vm);
</script>
</body>
</html>

2. 完成测试

可以看到双向绑定view关联的属性值变化,会影响到data数据池的数据【底层机制是Dom Listeners】

image-20220712223601726

6.事件绑定

1.基本说明

1.使用 v-on 进行事件处理,比如: v-on:click 表示处理鼠标点击事件

2.事件调用的方法定义在 vue 对象声明的 methods 节点中

3.v-on:事件名 可以绑定指定事件

4.官方文档:https://cn.vuejs.org/v2/guide/events.html

2.应用实例

1.需求分析/图解

  1. 需求: 演示 Vue 事件绑定操作

image-20220713223933287

2.代码实现&分析机制

  1. 需求说明

image-20220713223950425

2. 创建 D:\idea_java_projects\vue\event.html
<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>事件处理</title>
</head>
<body>
<!--视图-->
<div id="app">
    <h1>{{message}}</h1>
    <!--
    1. v-on:click 表示我们要给button元素绑定一个click的事件
    2. sayHi() 表示绑定的方法, 在方法池 methods{} 定义的
    3. 底层仍然是dom处理
    4. 如果方法不需要传递参数,可以省略()
    5. v-on:click可以简写@, 但是需要浏览器支持
    -->
    <button v-on:click="sayHi()">点击输出</button>
    <button v-on:click="sayOk()">点击输出</button>

    <button v-on:click="sayHi">点击输出</button>
    <button @click="sayOk">点击输出</button>
</div>
<!--引入vue.js-->
<script src="vue.js"></script>
<!--创建一个vue实例,并挂载到id=app的div-->
<script>
    //说明:这里创建的Vue实例, 你可以不去接收, 也可以接收,这里接收只是方便我们调试信息
    let vm = new Vue({
        el: "#app", //创建的vue实例挂载到 id=app的div, el 就是element的简写
        data: { //data{} 表示数据池(model中的数据), 有很多数据 ,以k-v形式设置(根据业务需要来设置)
            message: "Vue事件处理的案例",
            name: "llP"
        },
        // 1. 是一个methods属性, 对应的值是对象{}
        // 2. 在{} 中, 可以写很多的方法, 你可以这里理解是一个方法池
        methods: {
            sayHi() {
                console.log("hi, 银角大王~");
            },
            sayOk() {
                console.log("ok, 金角大王~");
            }
        }
    })
</script>
</body>
</html>

3.注意事项和使用细节

1.如果方法没有参数,可以省略()[需要浏览器支持]

2.v-on 指令的简写形式 @ [需要浏览器支持]

3.查看可以绑定的事件

image-20220713225452680

image-20220713225459277

7.修饰符

1.基本说明

修饰符 (Modifiers) 是以(.)指明的后缀,指出某个指令以特殊方式绑定

官方文档

https://cn.vuejs.org/v2/guide/events.html#%E4%BA%8B%E4%BB%B6%E4%BF%AE%E9%A5%B0%E7%AC%A6

image-20220713225755451

2.应用实例

1.需求分析/图解

  1. 需求: 演示 v-on:submit.prevent 的使用, 如果没有输入名字,控制台输出 "请输入名 字",否则输出 "提交表单"

image-20220713225955374

2.为什么在开发中, 有时需要 , 让某个指令以特殊方式绑定, 比如表单提交

1)我们不希望将这个表单进行整体提交, 而是 Ajax 的方式进行提交

2)因为表单整体提交会导致重载页面, 而 Ajax 方式可以有选择性提交数据,并且局部刷新

2.代码实现

  1. 创建 D:\idea_java_projects\vue\vue_modifier.html

<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Vue修饰符使用</title>
</head>
<body>
<div id="app">
    <!-- 
            1. 修饰符用于指出一个指令应该以特殊方式绑定。
            2. v-on:submit.prevent的.prevent 修饰符表示阻止表单提交的默认行为
            3. 执行 程序员指定的方法
     -->
    <form action="http://www.baidu.com" v-on:submit.prevent="onMySubmit">
        妖怪名: <input type="text" v-model="monster.name"><br/><br/>
        <button type="submit">注册</button>
    </form>
    <p>服务返回的数据是{{count}}</p>
    <h1>修饰符扩展案例</h1>
    <button v-on:click.once="onMySubmit">点击一次</button><br/>
    <input type="text" v-on:keyup.enter="onMySubmit">
    <input type="text" v-on:keyup.down="onMySubmit">
    <input type="text" v-model.trim="count">
</div>
<script src="vue.js"></script>
<script>
    let vm = new Vue({
        el: '#app',
        data: {//数据池
            monster: {//数据双向绑定时,monster数据(对象)的属性, 可以动态生成
            },
            count: 0
        },
        methods: {//方法池
            onMySubmit() {
                //console.log("我们自己的表单提交处理...");
                //"", null, undefined都是false
                if(this.monster.name) {
                    console.log("提交表单 name=", this.monster.name);
                    //这里,程序员就可以根据自己的业务发出ajax请求到后端
                    //得到数据后,在进行数据更新
                    this.count = 666;
                } else {
                    console.log("请输入名字..");
                }
            }
        }
    })
</script>
</body>
</html>

​ 2. 完成测试

image-20220716133815737

3.扩展一下

image-20220713230509649

image-20220713230524631

image-20220716133835532

8.条件渲染/控制: v-if v-show

1.基本说明

Vue 提供了 v-if 和 v-show 条件指令完成条件渲染/控制

1、v-if 介绍

image-20220716134416791

2、v-show 介绍

image-20220716134056129

官方文档:https://cn.vuejs.org/v2/guide/conditional.html

2.应用实例

1.需求分析/图解

image-20220716134236223

2.代码实现

v-if.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>条件渲染 v-if</title>
</head>
<body>
<div id="app">
    <!--通过v-model双向渲染改变data池中sel的值,当选中时sel=true -->
    <input type="checkbox" v-model="sel">是否同意条款[v-if实现]
    <!--
     v-if/v-else 会根据 返回的值,来决定是否动态创建对应的子组件
     sel=true 你同意调控
     sel=false 你不同意条款
    -->
    <h1 v-if="sel">你同意条款</h1>
    <h1 v-else>你不同意条款</h1>
</div>
<script src="vue.js"></script>
<script>
    //为了调试方便, 使用vm接收Vue实例
    let vm = new Vue({
        el: '#app',
        data: {
            sel: false
        }
    })
</script>
</body>
</html>

v-if.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>条件渲染 v-show</title>
</head>
<body>
<div id="app">
    <input type="checkbox" v-model="sel">是否同意条款[v-show实现]
    <h1 v-show="sel">你同意条款</h1>
    <h1 v-show="!sel">你不同意条款</h1>
</div>
<script src="vue.js"></script>
<script>
    //为了调试方便, 使用vm接收Vue实例
    let vm = new Vue({
        el: '#app',
        data: {//data数据池
            sel: false
        }
    })
</script>
</body>
</html>

3.测试

image-20220716140131018

image-20220716140332313

3.v-if VS v-show

1.v-if 会确保在切换过程中,条件块内的事件监听器和子组件销毁和重建

image-20220716141525446

image-20220716141554923

2.v-show 机制相对简单, 不管初始条件是什么,元素总是会被渲染,并且只是对 CSS 进行切换

image-20220716141626825

动态的切换style=display:none;

image-20220716141657085

使用建议:如果要频繁地切换,建议使用 v-show ;如果运行时条件很少改变,使用 v-if 较好

9.列表渲染: v-for

1.基本说明

1.Vue 提供了 v-for 列表循环指令

2.官方文档:https://cn.vuejs.org/v2/guide/list.html

1、对数组进行遍历

image-20220716141906885

image-20220716141928655

image-20220716141953424

2、用 v-for 来遍历一个对象的 property

image-20220716142005389

image-20220716142013836

image-20220716142020886

image-20220716142045811

2.应用实例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>v-for 列表渲染</title>
</head>
<body>
<div id="app">
    <!--
        基本语法:
        <li v-for="变量 in 数字">{{ 变量 }}</li>-->
    <h1>简单的列表渲染</h1>
    <ul>
        <li v-for="i in 3">{{i}}</li>
    </ul>
    <!--
        基本语法:
        <li v-for="(变量, 索引) in 值">{{ 变量 }} - {{ 索引 }}</li>
    -->
    <h1>简单的列表渲染-带索引</h1>
    <ul>
        <li v-for="(i,index) in 3">{{i}}-{{index}}</li>
    </ul>
    <h1>遍历数据列表</h1>
    <!-- 语法:
        <tr v-for="对象 in 对象数组">
            <td>{{对象的属性}}</td>
        </tr>
     -->
    <table width="400px" border="1px">
        <tr v-for="(monster,index) in monsters">
            <td>{{index}}</td>
            <td>{{monster.id}}</td>
            <td>{{monster.name}}</td>
            <td>{{monster.age}}</td>
        </tr>
    </table>
</div>
<script src="vue.js"></script>
<script>
    new Vue({
        el: '#app',
        data: { //数据池
            monsters: [
                {id: 1, name: '牛魔王', age: 800},
                {id: 2, name: '黑山老妖', age: 900},
                {id: 3, name: '红孩儿', age: 200}
            ]
        }
    })
</script>
</body>
</html>

3.完成测试

image-20220716155551516

10.组件化编程

1.基本说明

  1. 在大型应用开发的时候,页面可以划分成很多部分,往往不同的页面,也会有相同的部 分。例如可能会有相同的头部导航。
  2. 但是如果每个页面都独自开发,这无疑增加了我们开发的成本。所以我们会把页面的不 同部分拆分成独立的组件,然后在不同页面就可以共享这些组件,避免重复开发(如图)

image-20220716155655847

3.解读上图

​ 组件(Component) 是 Vue.js 最强大的功能之一(可以提高复用性[1.界面2.业务处理])

组件也是一个Vue实例,也包括∶ data、methods、生命周期函数等

​ 组件渲染需要 html模板,所以增加了template 属性,值就是 HTML 模板

​ 对于全局组件,任何vue 实例都可以直接在 HTML 中通过组件名称来使用组件

​ data 是一个函数,不再是一个对象, 这样每次引用组件都是独立的对象/数据

2.应用实例

  1. 需求如下, 点击一个按钮, 可以显示点击的次数

image-20220716155916677

1.实现方式 1-普通方式

<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>组件化编程</title>
</head>
<body>

<div id="app">
    <!--非组件化方式-普通方式-->
    <button v-on:click="click1()">点击次数= {{count}} 次【非组件化方式】</button><br/><br/>
    <!--需求是,有多个按钮,都要进行点击统计
    1. 其实三个按钮界面其实一样, 但是目前我们都重新写了一次, 复用性低
    2. 点击各个按钮的业务都是对次数+1, 因此业务处理类似,但是也都重新写了一个方法, 复用性低
    3. 解决===> 组件化编程
    -->
    <button v-on:click="click2()">点击次数= {{count2}} 次【非组件化方式】</button><br/><br/>
    <button v-on:click="click3()">点击次数= {{count3}} 次【非组件化方式】</button><br/>
</div>
<script src="vue.js"></script>
<script>
    new Vue({
        el: "#app",
        data: {//data数据池
            count: 10,
            count2: 10,
            count3: 10
        },
        methods: {//methods属性, 可以定义相应的方法
            click1() {
                this.count++;
            },
            click2() {
                this.count2++;
            },
            click3() {
                this.count3++;
            }
        }
    })
</script>
</body>
</html>

image-20220716161200887

问题分析

  1. 点击次数会共享
  2. 如果要解决, 需要我们定义不同的点击次数变量(比如 count、count2、count3 等)来记录不同
  3. 也就是复用性差

2.实现方式 2-全局组件方式

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>组件化编程-全局组件</title>
</head>
<body>
<div id="app">
    <h1>组件化编程-全局组件</h1>
    <!--使用全局组件 ,<counter></counter>
    vue解析时会用teamplate的模板进行替换:<button v-on:click="click()">点击次数= {{count}} 次【全局组件化】</button>-->
    <counter></counter>
    <br/>
    <counter></counter>
</div>

<div id="app2">
    <h1>组件化编程-全局组件-app2</h1>
    <!--使用全局组件-->
    <counter></counter>
    <counter></counter>
</div>
<script src="vue.js"></script>
<script>
    //可以理解为创建了多个component-counter对象
    //1、定义一个全局组件, 名称为 counter
    //2. {} 表示就是我们的组件相关的内容
    //3. template 指定该组件的界面, 因为会引用到数据池的数据,所以需要是模板字符串
    //4. 要把组件视为一个Vue实例,也有自己的数据池和methods
    //5. 对于组件,我们的数据池的数据,是使用函数/方法返回[目的是为了保证每个组件的数据是独立], 不能使用原来的方式
    //6. 这时我们达到目前,界面通过template实现共享,业务处理也复用
    //7. 全局组件是属于所有vue实例,因此,可以在所有的vue实例使用
    Vue.component("counter", {
        template: `<button v-on:click="click()">点击次数= {{count}} 次【全局组件化】</button>`,
        data() {//这里需要注意,和原来的方式不一样!!!!
            return {
                count: 10
            }
        },
        methods: {
            click() {
                this.count++;
            }
        }
    })
    //创建Vue实例,必须有
    let vm = new Vue({
        el: "#app"//Vue实例的挂载点
    })

    let vm2 =  new Vue({
        el: "#app2"//Vue实例的挂载点
    })
</script>
</body>
</html>

image-20220716164119107

3.实现方式 3-局部组件方式

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>组件化编程-局部组件</title>
</head>
<body>
<div id="app">
    <h1>组件化编程-局部组件</h1>
    <!--使用局部组件 ,该组件是从挂载到app的vue中的-->
    <my_counter></my_counter><br/>
    <my_counter></my_counter><br/>
    <my_counter></my_counter><br/>
</div>

<div id="app2">
    <h1>组件化编程-局部组件-app2</h1>
    <!--使用局部组件 -->
    <llp_counter></llp_counter><br/>
    <llp_counter></llp_counter><br/>
</div>
<script src="vue.js"></script>
<script>

    //定义一个组件, 组件的名称为 buttonCounter
    //1. 可以把常用的组件,定义在某个commons.js中 export
    //2. 如果某个页面需要使用, 直接import
    const buttonCounter = {
        template: `<button v-on:click="click()">点击次数= {{count}} 次【局部组件化】</button>`,
        data() {//这里需要注意,和原来的方式不一样!!!!
            return {
                count: 10
            }
        },
        methods: {
            click() {
                this.count++;
            }
        }
    }

    //创建Vue实例,必须有
    let vm = new Vue({
        el: "#app",//Vue实例的挂载点
        components: { //引入/注册某个组件, 此时my_counter就是一个组件, 是一个局部组件,他的使用范围在当前vue
            'my_counter': buttonCounter
        }
    })

    let vm2 = new Vue({
        el: "#app2",//Vue实例的挂载点
        components :{//引入/注册组件buttonCounter
            'llp_counter': buttonCounter
        }
    })

</script>
</body>
</html>

image-20220716164425362

4.注意事项和细节说明

  1. 如果方法体, 只有简单的语句,比如 count++, 那么可以进行简写

    1. 组件定义需要放置在 new Vue() 前,否则组件注册会失败

3.组件化小结

  1. 组件也是一个 Vue 实例,因此它的定义是也存在∶ data、methods、生命周期函数等
  2. data 是一个函数,不再是一个对象, 这样每次引用组件都是独立的对象/数据
  3. 组件渲染需要 html 模板,所以增加了 template 属性,值就是 HTML 模板

11.生命周期和监听函数(钩子函数)

1.基本说明

  1. Vue 实例有一个完整的生命周期,也就是说从开始创建、初始化数据、编译模板、挂载 DOM、渲染-更新-渲染、卸载等一系列过程,我们称为 Vue 实例的生命周期
  2. 钩子函数(监听函数): Vue 实例在完整的生命周期过程中(比如设置数据监听、编译模 板、将实例挂载到 DOM 、在数据变化时更新 DOM 等), 也会运行叫做生命周期钩子的函数
  3. 钩子函数的 作用就是在某个阶段, 给程序员一个做某些处理的机会

2.Vue实例的生命周期示意图

地 址 : https://cn.vuejs.org/v2/guide/instance.html#%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C %9F%E5%9B%BE%E7%A4%BA

image-20220716164927039

解读上图

  1. new Vue() new 了一个 Vue 的实例对象,此时就会进入组件的创建过程。

  2. Init Events & Lifecycle 初始化组件的事件和生命周期函数

  3. beforeCreate 组件创建之后遇到的第一个生命周期函数,这个阶段 data 和 methods 以及 dom 结构都未 被初始化,也就是获取不到 data 的值,不能调用 methods 中的函数

  4. Init injections & reactivity 这个阶段中, 正在初始化 data 和 methods 中的方法

  5. created - 这个阶段组件的 data 和 methods 中的方法已初始化结束,可以访问,但是 dom 结构未 初始化,页面未渲染,在这个阶段,经常会发起 Ajax 请求

  6. 编译模板结构(在内存)

  7. beforeMount 当模板在内存中编译完成,此时内存中的模板结构还未渲染至页面上,看不到真实的数据

  8. Create vm.$el and replace ‘el’ with it 这一步,再在把内存中渲染好的模板结构替换至真实的 dom 结构也就是页面上

  9. mounted 此时,页面渲染好,用户看到的是真实的页面数据, 生命周期创建阶段完毕,进入到了运行中的阶段

  10. 生命周期运行中

    1)beforeUpdate 当执行此函数,数据池的数据新的,但是页面是旧的
    2)Virtual DOM re-render and patch 根据最新的 data 数据,重新渲染内存中的模板结构,并把渲染好的模板结构,替换至页面 上

    3)updated 页面已经完成了更新,此时,data 数据和页面的数据都是新的

11.beforeDestroy 当执行此函数时,组件即将被销毁,但是还没有真正开始销毁,此时组件的 data、methods数据或方法 还可被调用

12.Teardown…… 注销组件和事件监听

13.destroyed 组件已经完成了销毁

3.应用实例-展示 VUE 实例生命周期和钩子函数执行时机

1.需求分析/图解

需求: 展示 VUE 实例生命周期和 钩子函数/监听函数/生命周期函数 执行时机

  1. 重点研究几个重要的钩子函数 (beforeCreate, created, beforeMount, mounted, beforeUpdate, updated)

  2. 在这几个钩子函数中, 数据模型是否加载/使用? 自定义方法是否加载/可用? html 模 板是否加载/使用? html 模板是否完成渲染

  3. 如图

    image-20220716170050982

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <span id="num">{{num}}</span>
    <!--@click="add" 这里只是对num进行++可以携程 num++ -->
    <button @click="num++">赞!</button>
    <h2>{{name}},有{{num}}次点赞</h2>
</div>
<script src="vue.js"></script>
<script>
    let vm = new Vue({
        el: "#app",
        data: {//数据池
            name: "kristina",
            num: 0
        },
        methods: {
            show() {
                return this.name;
            },
            add() {
                this.num++;
            }
        },
        beforeCreate() {//生命周期函数-创建vue实例前
            console.log("=============beforeCreate==========");
            console.log("数据模型/数据池的数据是否加载/使用?[no]", this.name, " ", this.num);
            //console.log("自定义方法是否加载/使用?[no]", this.show());
            console.log("用户页面dom是否加载/使用?[yes]", document.getElementById("num"));
            console.log("用户页面dom是否被渲染?[no]", document.getElementById("num").innerText);
        },
        created() {//生命周期函数-创建vue实例
            console.log("=============created==========");
            console.log("数据模型/数据池的数据是否加载/使用?[yes]", this.name, " ", this.num);
            console.log("自定义方法是否加载/使用?[yes]", this.show());
            console.log("用户页面dom是否加载/使用?[yes]", document.getElementById("num"));
            console.log("用户页面dom是否被渲染?[no]", document.getElementById("num").innerText);
            //可以发出Ajax
            //接收返回的数据
            //再次去更新data数据池的数据
            //编译内存模板结构
            //.....

        },
        beforeMount() {//生命周期函数-挂载前
            console.log("=============beforeMount==========");
            console.log("数据模型/数据池的数据是否加载/使用?[yes]", this.name, " ", this.num);
            console.log("自定义方法是否加载/使用?[yes]", this.show());
            console.log("用户页面dom是否加载/使用?[yes]", document.getElementById("num"));
            console.log("用户页面dom是否被渲染?[no]", document.getElementById("num").innerText);

        },
        mounted() {//生命周期函数-挂载后
            console.log("=============mounted==========");
            console.log("数据模型/数据池的数据是否加载/使用?[yes]", this.name, " ", this.num);
            console.log("自定义方法是否加载/使用?[yes]", this.show());
            console.log("用户页面dom是否加载/使用?[yes]", document.getElementById("num"));
            console.log("用户页面dom是否被渲染?[yes]", document.getElementById("num").innerText);

        },
        beforeUpdate() {//生命周期函数-数据池数据更新前
            console.log("=============beforeUpdate==========");
            console.log("数据模型/数据池的数据是否加载/使用?[yes]", this.name, " ", this.num);
            console.log("自定义方法是否加载/使用?[yes]", this.show());
            console.log("用户页面dom是否加载/使用?[yes]", document.getElementById("num"));
            console.log("用户页面dom数据是否被更新?[no]", document.getElementById("num").innerText);
            //验证数据==>修正
            // if(this.num < 10 ) {
            //     this.num = 8;
            // }
        },
        updated() {//生命周期函数-数据池数据更新后
            console.log("=============updated==========");
            console.log("数据模型/数据池的数据是否加载/使用?[yes]", this.name, " ", this.num);
            console.log("自定义方法是否加载/使用?[yes]", this.show());
            console.log("用户页面dom是否加载/使用?[yes]", document.getElementById("num"));
            console.log("用户页面dom数据是否被更新?[yes]", document.getElementById("num").innerText);
            
        }

    })
</script>
</body>
</html>

image-20220716180726635