• vue学习笔记


    vue学习过程中问题点记录。

    在这里插入图片描述

    1.created()和mounted()的区别及其用法

    Vue.js中,created()和mounted()是两个常见的生命周期钩子函数。具体用法和区别如下:

    created()方法:在Vue实例被创建之后立即执行。在这个阶段,Vue实例的数据观测和事件配置已完成,但尚未挂载到DOM上。通常在这个阶段执行一些数据初始化、事件监听、异步请求等逻辑,但不涉及DOM操作。

    mounted()方法:在Vue实例挂载到DOM之后执行。在这个阶段,Vue实例已经完成了数据观测、编译渲染、创建虚拟DOM和真实DOM等所有过程,可以进行DOM操作。通常在这个阶段执行一些需要依赖DOM元素的逻辑,如获取元素尺寸、绑定事件、设置定时器等。

    <script>
    export default {
      data() {
        return {
          message: 'Hello, World!'
        }
      },
      created() {
        console.log('created:', this.message); // 'created: Hello, World!'
        // 执行一些数据初始化、事件监听等逻辑
      },
      mounted() {
        console.log('mounted:', this.$el.textContent); // 'mounted: Hello, World!'
        // 执行一些需要依赖DOM元素的逻辑,如获取元素尺寸、绑定事件、设置定时器等
      }
    }
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    总结:需要注意的是,created()和mounted()只有在Vue实例被成功创建和挂载后才会执行,如果中间发生了错误或中止,那么这两个函数也不会执行。在使用这两个函数时,要避免过多的依赖全局状态或其他模块,以保证逻辑的灵活性和可重用性。

    2.vue生命周期函数

    1.什么是生命周期

    vue的生命周期是指:从vue实例产生开始到vue实例被销魂这段时间所经历的过程。

    vue实例的创建和销毁过程好比人的一生从出现到死亡过程。在其中一些重大经历,也就是特殊时间点,我们可以做什么事情。

    在vue的一生中,从vue组件创建开始一直到其被销毁时的时间段中,也被建立了几个特殊的时间点,为了方便开发者实现在特定的时候让vue在特定的时间做特定的事情。通过一个叫做“生命周期钩子函数”的方法进行设置。在vue中,vue的一生被8个生命周期钩子函数给支配着。

    也可以理解为回调函数,当我们写了周期函数后,在规定的时间点,vue会自动执行这个函数。

    钩子函数:可以简单理解为是一种系统在不同的阶段自动执行、用户无须干预的函数。

    2.生命周期简介

    vue的生命周期事件主要被分为2个钩子:事件之前和事件之后调用。具体来说,可分为4种类型的事件:

    ● 创建–在组件创建时执行 。
    ● 挂载–DOM被挂载时执行 。
    ● 更新–当响应数据被修改时执行 。
    ● 销毁–在元素被销毁之前立即执行。

    函数简介
    beforeCreate在 VUE 实例生成之前会自动执行的函数。
    created在 VUE 实例生成之后会自动执行的函数。
    beforeMount在组件内容被渲染到页面之前自动执行的函数。
    mounted在组件内容被渲染到页面之后自动执行的函数。
    beforeUpdate当data中的数据发生变化前执行的函数。
    updated当data中的数据发生变化后执行的函数。
    beforeUnmountVUE实例与元素解除绑定前执行的函数。
    unmountedVUE实例与元素解除绑定后执行的函数。

    代码举例:

    <script src="../vue.global.js"></script>
    </head>
    <body>
        <div id="myDiv"></div>
    </body>
    <script>
     
        // 生命周期函数:在某一时刻会自动执行的函数
        const app = Vue.createApp({     // 创建一个vue应用实例
            data() {
                return {
                    message : "hello"
                }
            },
            //在实例生成之前会自动执行的函数
            beforeCreate() {
                alert("beforeCreate")
            },
            //在实例生成之后会自动执行的函数
            created() {
                alert("created")
            },
            // 在组件内容被渲染到页面之前自动执行的函数
            beforeMount() {
                alert("beforeMount:" + document.getElementById("myDiv").innerHTML)
            },
            // 在组件内容被渲染到页面之后自动执行的函数
            mounted() { // 绑定后自动执行
                alert("mounted:" + document.getElementById("myDiv").innerHTML)
            },
            // 当data中的数据发生变化前执行
            beforeUpdate() {
                
                alert("beforeUpdate:" + document.getElementById("myDiv").innerHTML);
            },
            // 当data中的数据发生变化后执行
            updated() {
                alert("updated:" + document.getElementById("myDiv").innerHTML);
            },
            // 解除绑定前执行的函数
            beforeUnmount() {
                alert("beforeUnmount:" + document.getElementById("myDiv").innerHTML);
            },
            // 解除绑定后执行的函数
            unmounted() {
                alert("unmounted:" + document.getElementById("myDiv").innerHTML);
            },
            // 如果没有 template ,则取绑定元素下面的子元素作为 template
            template : "
    {{message}}
    "
    }); // vm 就是vue应用的根组件 const vm = app.mount('#myDiv'); // 绑定id为myDiv的元素 // 更新数据 vm.$data.message = 'hello world!!!'; // 解除绑定 app.unmount(); </script>
    • 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
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60

    3.vue中动态添加的元素点击事件失效

    今天遇到了个问题,经过查找资料,排查了3个小时才解决,功夫不负有心人,记录下问题和解决方法。

    在vue的mounted方法中,有这样一段动态插入元素并设置点击事件的方法:

    mounted(){
     var td = document.createElement("td")
     td.innerHTML = `删除 修改`
    }
    

    vue的methods方法定义了Delete方法和Modify方法,如下:

     methods: {
     Detete(){
     consolg.log("删除了");
     },
     Modify(){
      consolg.log("修改了");
     }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    但是,奇怪的是,2个a标签里的点击事件并没有生效,即点击删除和修改标签的时候,Delete方法和Modify方法没有被调用。

    vue中动态添加的元素点击事件之所以不能被触发是因为,vue中动态生成的页面元素,是在Vue文件编译之后插入到页面中的,不会被Vue编译,只会作为普通的html代码被插入,所以无法识别vue事件。既然是普通的html代码,那我们可以使用原生的事件去代替vue事件,原生事件一定会被触发,但此时又出现一个新问题,那就是原生事件被触发后,无法访问到vue实例的data中的数据和methods中的方法,究其原因还是由于没有被vue编译的问题。

    既然问题出现了,那就想办法解决问题。既然访问不到vue实例中的数据和方法,那么我们可以将事件所需要使用的数据和方法,挂载在window对象上,这样就可以被原生事件访问到了。

    解决方法:

    1. 在vue的created方法中添加如下代码来挂载Delete方法和Modify方法:
            created() {
                let _this = this;
                window.Delete = _this.Delete;
                window.Modify = _this.Modify;
            },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    1. mounted方法更新为:
    mounted(){
     var td = document.createElement("td")
     td.innerHTML = `删除 修改`
    }
    

    这样就可以实现,动态添加的元素并绑定点击事件的效果了。

    4.vue如何获取数据值

    Vue提供了一系列的方法来获取数据值,包括获取data中的值、获取computed中的值和获取props中的值。

    1.获取data中的值

    在Vue实例中,可以通过this.$data来访问data对象。例如:

    <template>
      <div>
        <p>{{msg}}</p>
        <button @click="getData">获取数据</button>
      </div>
    </template>
     
    <script>
    export default {
      data() {
        return {
          msg: 'Hello World!'
        }
      },
      methods: {
        getData() {
          console.log(this.$data.msg)
        }
      }
    }
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    上述代码中,在data中定义了msg属性,并且通过this.$data.msg来访问它。通过这种方式,我们可以获取data对象中所有的属性值。

    2.获取computed中的值

    computed在Vue中是一个十分有用的概念。computed属性是响应式的,当它所依赖的属性发生变化时,它会自动重新计算。在获取computed属性的值时,我们可以直接访问它们。例如:

    <template>
      <div>
        <p>{{msg}}</p>
        <button @click="getData">获取数据</button>
      </div>
    </template>
     
    <script>
    export default {
      data() {
        return {
          name: 'Lucy',
          age: 18
        }
      },
      computed: {
        msg() {
          return `我的名字是${this.name},我今年${this.age}岁了。`
        }
      },
      methods: {
        getData() {
          console.log(this.msg)
        }
      }
    }
    </script>
    
    • 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

    在上述代码中,定义了一个computed属性msg,用来计算一段字符串。可以直接通过this.msg来访问这个计算属性的值。

    3.获取props中的值

    在使用Vue开发组件时,可以在组件中定义props属性,并通过它来传递数据。在获取props中的值时,我们可以直接通过props对象访问。例如:

    <template>
      <div>
        <p>{{msg}}</p>
      </div>
    </template>
     
    <script>
    export default {
      props: {
        name: String,
        age: Number
      },
      computed: {
        msg() {
          return `我的名字是${this.name},我今年${this.age}岁了。`
        }
      }
    }
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    在上述代码中,我们定义了两个props属性name和age,分别是字符串和数字类型。我们通过this.name和this.age来访问它们的值。

    4.总结

    在Vue中,获取数据值是非常重要的一个概念。可以通过this.$data来访问data对象中的所有属性值,通过直接访问computed属性来获取计算属性的值,通过props对象来获取父组件传递过来的数据。这些方法可以帮助我们更方便地获取数据值。

    5.动态 import

    以前我们import导入模块是在一开始的时候就全部导入了,这样在模块很多的时候,会显得网页速度加载很慢,在ES11中就提供了一种动态import,案例演示如下:

    m1.js:

    //分别暴露
    export let school = "西北工业大学";
    
    export function study() {
        console.log("我们要学习!");
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    index.html:

    DOCTYPE html>
    <html>
    <head>
        <meta charset="UTF-8">
        <title>title>
    head>
    <body>
    
    <button id="btn">点击我,加载m1.js模块button>
    
    
    <script type="module">
        const btn = document.getElementById("btn");
    
        btn.onclick = function(){
            import("./m1.js").then(module => {
                module.study();
            });
        };
    script>
    body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    6.关于let和var的区别

    1. 作用域不同:
    • let定义的变量作用域仅限于定义该变量的代码块中。比如:if … else,for…in…,switch…case…等等。
    • var定义的变量作用域为定义该变量的函数范围中(当在函数中定义时),或者为全局的范围(当定义为全局变量时)。

    比如以下面一段if条件判断代码为例:

    (function(){
      if (true) {
        var a = 13
      }
      console.log(a) //控制台输出:13
    })()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在if代码块内使用var定义的变量a,在代码块外仍然可以访问,控制台打印出了a的值。

    (function(){
      if (true) {
        let a = 13
      }
      console.log(a) //控制台输出:ReferenceError: a is not defined
    })()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    当我们将var替换成let时,在if代码块外访问时,会直接报错。

    1. 访问顺序的要求不同:
    • var定义变量,可以在未定义前访问。
    • let定义变量,必须先定义,后访问。
    (function(){
        console.log(a)
        console.log(b)
        var a = 10
        let b = 11
    })()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    控制台输出:

    undefined
    ReferenceError: Cannot access 'b' before initialization
    
    • 1
    • 2

    a可以在var未定义前访问,值为undefined,b在let未定义前访问直接报错。

    1. 是否可被重复定义:
    • let:同一代码块中,同名变量不可被重复定义。
    • var:同一作用域下,同名变量可以被重复定义。

    还是以if条件语句为例:

    let:

    (function(){
        if (true) {
            let a = 11
            let a = 12
            console.log(a) // 控制台:SyntaxError: Identifier 'a' has already been declared
        }
    })()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    var:

    (function(){
        if (true) {
            var a = 11
            var a = 12
            console.log(a) // 控制台:12
        }
    })()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    js中的let相比var更严谨,也更符合我们的编程思维和习惯。应更偏向使用let而不是var。

    7.js中dom元素的classList.toggle(“”)方法

    classList.toggle()方法用于在元素的class属性中添加或删除指定的类名。具体来说,该方法会检查元素的class属性中是否含有指定的类名,如果没有则添加该类名,如果有则删除该类名。

    方法的语法:element.classList.toggle(“classname”);

    其中,element为要操作的元素,classname为要添加或删除的类名。执行该方法后,如果元素中已经包含了该类名,则该方法会将该类名从元素的class属性中删除;如果元素中不包含该类名,则该方法会将该类名添加到元素的class属性中。例如:

    HTML代码:

    <div id="myDiv" class="box">div>
    
    • 1

    JS代码:

    var myDiv = document.getElementById("myDiv");
    myDiv.classList.toggle("box"); //删除box类名
    myDiv.classList.toggle("container"); //添加container类名
    
    • 1
    • 2
    • 3

    执行后,HTML代码为:

    <div id="myDiv" class="container">div>
    
    • 1

    可以看到,原先元素中的box类名已经被删除,同时添加了container类名。如果再次执行该方法,container类名将被删除,恢复原先的状态。

    28.

  • 相关阅读:
    GRS认证里 “收货人问题” 的最新解读
    Dapr(一) 基于云原生了解Dapr
    Java EE基础练习题(上)
    理论和实践详解RabbitMQ惰性/延迟队列(lazy queues)(带测试样例及分析)
    NTT的Another Me技术助力创造歌舞伎演员中村狮童的数字孪生体,将在 “Cho Kabuki 2022 Powered by NTT”舞台剧中首次亮相
    653 · 添加运算符
    AUTOSAR汽车电子嵌入式编程精讲300篇-基于CAN总线的温度场测量装置的研究与设计
    Tomcat
    Kafka topic分区增加副本
    Perfetto分析进阶
  • 原文地址:https://blog.csdn.net/weixin_48239221/article/details/133846763