vue中组件生命周期( 组件内钩子 )

组件生命周期( 组件内钩子 )

钩子函数,就是options里面的key, 它的值是函数
钩子函数写在其他配置项的后面

  1. 组件的有哪几个阶段?
    • 初始化阶段
    • 运行中阶段
    • 销毁阶段
  2. 初始化阶段
    • 分为两个大阶段, 每一个大阶段包含两个生命周期钩子函数 ---- 生命周期 --》人的一生 钩子函数 --》 (人在某个阶段做得一些事情, 这些事情是自动触发)
    • 有那四个钩子函数呢?每个钩子函数有什么功能?项目中有什么用呢?
      1. beforeCreate
        • 表示组件创建前的准备工作, 为事件的发布订阅 和 生命周期的开始做初始化
        • 这个钩子函数中
          • 数据拿不到, 真实DOM也拿不到
        • 这个钩子在项目中我们没有什么实际用途
      2. **created **
        • 表示组件创建结束
        • 这个钩子函数中
          • 数据拿到了, 但是真实DOM没有拿到
        • 这个钩子函数在项目
          • **数据请求, 然后可以进行一次默认数据的修改 **
      3. beforeMount
        • 表示组件装载前的准备工作
          • 判断 el选项有没有, 判断 template选项有没有 , 如果没有, 那么需要手动装载
          • 如果有,那么通过render函数进行模板的渲染(没有做的,正要进行, VDOM)
        • 这个钩子函数中
          • 数据拿到了, 真实DOM没有拿到
        • 这个钩子函数在项目中,
          • 数据请求, 它也可以进行一次数据修改
      4. mounted
        • 示组件装载结束, 就是我们可以在视图中看到了
        • 这个钩子函数中
          • 数据拿到了, 真实DOM也拿到了
        • 这个钩子函数在项目
          • **DOM操作就可以进行了, 第三方库的实例化 **

例:

<script>
  Vue.component('LifeCircle',{
    template: '#life-circle',
    data () {
      return {
        msg: 'hello vue.js'
      }
    },
    // 初始化阶段钩子函数
    beforeCreate () { //表示组件创建前的准备工作( 初始化事件和生命周期 )     
      /* 
        组件未创建, 所以没有this , 数据拿不到 , DOM也拿不到
      */
      console.log('01-beforeCreate');
      console.log( 'data',this.msg )
      console.log( 'DOM',document.querySelector('p'))
      /*       axios({
              url: './data.json'
            })
              .then( res => {
                this.msg = res 
              })
              .catch( error => console.log(error))
      */
    },
    created () { // 组件创建结束
      console.log('02-created')
      console.log( 'data',this.msg )
      console.log( 'DOM',document.querySelector('p'))
   /*    axios({
        url: './data.json'
      })
        .then( res => {
          this.msg = res 
        })
        .catch( error => console.log(error)) */
      
    },
    beforeMount () { 
      console.log( '03-beforeMounte' )
      console.log( 'data',this.msg )
      console.log( 'DOM',document.querySelector('p'))
/*       axios({
        url: './data.json'
      })
        .then( res => {
          this.msg = res 
        })
        .catch( error => console.log(error)) */
    },
    mounted () {                                        //表示组件装载结束, 就是我们可以在视图中看到了
      console.log('04-mounted')
      console.log('data',this.msg)
      console.log('Real DOM',document.querySelector('p'))
      axios({
        url: './data.json'
      })
        .then( res => {
          this.msg = res 
        })
        .catch( error => console.log(error))
    }
  })
  new Vue({
   
  }).$mount('#app')
</script>
  • 总结: 由上对比,我们可以知道, 数据请求越提前越好一些, created常用于数据的请求和数据的修改, 第三方库的实例化常在mounted中进行书写
  1. 运行中阶段
    • 运行中阶段一共有两个钩子函数
      • beforeUpdate
        • 表示数据更新前的准备工作
        • 这个钩子不主动执行,当数据修改了, 才会执行
        • 这个钩子函数中
          • 数据拿到了, 并且拿到的是修改后的数据
          • DOM也输出了
        • 这个钩子函数更多的工作内容为:生成新的 VDOM , 然后通过diff算法进行两次VDOM 对比
        • 这个钩子在项目中
          • 因为他主要做的事情是内部进行的, 所以对我们而言没有太多的操作意义
      • **updated **
        • 表示数据更新结束, 通过render函数渲染真实DOM
        • 这个钩子函数的执行也是, 当数据修改的时候才执行
        • 这个钩子函数中
          • 数据拿到了, DOM也拿到了
            -** 这个钩子在项目中 **
          • 也是进行第三方库的实例化( DOM是改变的 )
    • 总结: 数据更新, 也要进行DOM操作那么, 我们使用update这个钩子

例:


<script>
  Vue.component('LifeCircle',{
    template: '#life-circle',
    data () {
      return {
        msg: '这是运行阶段'
      }
    },
    beforeUpdate () {     //表示数据更新前的准备工作
      console.log( 'beforeUpdate' )
      console.log( 'data', this.msg)
      console.log( 'DOM', document.querySelector('p') )
    },
    updated () {       //表示数据更新结束, 通过render函数渲染真实DOM
      console.log( 'updated' )
      console.log( 'data', this.msg )
      console.log( 'DOM' , document.querySelector('p') )
      // document.querySelector('p').style.background = 'red'
    }
  })
  new Vue({
    el: '#app'
  })

</script>

  1. 销毁阶段
    • 通过开关销毁
      • 这个组件真实DOM也会被删除掉
    • 通过调用vm.$destroy()
      • 这个组件的被删除了, 但是它的真实DOM的html结构还在
    • 包含两个钩子函数
      • beforeDestroy
      • destroyed
      • 这两个钩子无差别
      • 这两个钩子在项目中
        • 做善后工作 , 手动清除一些计时器, 和一些方法, 还有第三方实例化出来的对象
    • 我们建议大家使用开关的形式来操作组件的销毁和创建
<div id="app">
    <button @click = 'flag = !flag'> 销毁 </button>
    <life-circle v-if = "flag"></life-circle>
  </div>
  <template id="life-circle">
    <div>
      <h3> 销毁阶段 </h3>
      <button @click = 'destroy'> 销毁 </button>
    </div>
  </template>
</body>
<script>
  Vue.component('LifeCircle',{
    template: '#life-circle',
    methods: {
      destroy(){
        this.$destroy()
      }
    },
    created () {
      this.timer = setInterval( () => {
        console.log('1')
      },1000)
    },
    beforeDestroy () {
      console.log('beforeDestory')
    },
    destroyed () {
      console.log('destroyed')
      clearInterval( this.timer )
      // 如果是用$destroy这个方法来清除组件, 那么我们必须手动清除这个组件的外壳
      document.querySelector('#app div').remove()
    }
  })
  new Vue({
    el: '#app',
    data: {
      flag: true
    }
  })
</script>
```<div id="app">
    <button @click = 'flag = !flag'> 销毁 </button>
    <life-circle v-if = "flag"></life-circle>
  </div>
  <template id="life-circle">
    <div>
      <h3> 销毁阶段 </h3>
      <button @click = 'destroy'> 销毁 </button>
    </div>
  </template>
</body>
<script>
  Vue.component('LifeCircle',{
    template: '#life-circle',
    methods: {
      destroy(){
        this.$destroy()  //虽然使用了$destroy()函数删除了这个组件,但真实的HTML中的DOM结构还在
      }
    },
    created () {
      this.timer = setInterval( () => {
        console.log('1')
      },1000)
    },
    beforeDestroy () {
      console.log('beforeDestory')
    },
    destroyed () {
      console.log('destroyed')
      clearInterval( this.timer )
      // 如果是用$destroy这个方法来清除组件, 那么我们必须手动清除这个组件的外壳
      document.querySelector('#app div').remove()
    }
  })
  new Vue({
    el: '#app',
    data: {
      flag: true
    }
  })
</script>
5. 用案例来写一个生命周期       第三方库的实例化来做  swiper
   > 真实DOM存在了, 才能实例化
   2. 直接写死了
        - DOM就没有渲染
        - 数据直接有了
   3. 数据请求
        - 我们常规是往 updated 钩子里面写, 但是遇到问题了?
        - 问题是: 当我们有其他数据更新时,updated钩子就会重复触发, 也就是说第三方库要重复实例化
        - 解决: 
            1. 在updated钩子中添加判断条件, ` if(!this.swiper){} `  
            2. 在数据请求里面写, 但是发现无法获得真实DOM
                  1. 将实例化代码发到异步队列
                     - setTimeout(function(){},0) 将实例化代码发到这里面    [不推荐]
                     - Vue.nextTick() /this.$nextTick      优先使用
                         - 概念: nextTick表示DOM渲染之后执行的业务


### 杂七杂八
1. props属性验证
   - 常用形式:
        ```javascript
            props: {
                key: keyType    // key是从父组件获得的自定义属性, 值是我们期望得到的数据类型
            }
        ```
        - 业务:我现在想要 > 1000 我才要, 没有 > 1000 我就不要
        - 解决: vue提供了一个 :validator
        ```javascript
            props: {
                key: {
                    validator( value ){
                        return value 的条件
                    }
                }
            }
        ```
    - 不常用形式
        ```jvascript
            props: {
                propA: [],
                propB: {
                    type: String,
                    require: true
                },
                propC: {
                    type:String,
                    default: 'yyb'
                },
                propD: {
                    type: String,
                    default: function(){
                        return 'yyb'
                    }
                }
            }
        ```
- 有时候有的项目总也会使用一个叫做 vue-validate   validate这些第三方库 
  1. 过滤器
    • vue 1.x版本一共提供了10个过滤器, 但是不满足人们使用,vue2.x全部不提供了, 交给开发者自己写
    • 但是vue提供饿了定义过滤器的方式
    • 过滤器: 对数据进行格式化的一个函数
    • 过滤器可以用在两个地方:双花括号插值和 v-bind 表达式
    • 过滤器用给一个 ’ | ’ 表示, 我们称之为 ‘管道符’

例:
写一个大小写转换

<body>
    <div id="app">
        <input type="text" v-model="str">
        <p>
            {{ str }} <br>{{ str | strings_up() }}<br> {{ str | strings_low() }}
        </p>
    </div>
</body>
<script>
    new Vue({
        el: '#app',
        data: {
            str: "dear deer"
        },
        filters: {
            strings_up(type) {
                return a = type.toUpperCase()
            },
            strings_low(type) {
                return a = type.toLowerCase()
            }
        },
    })
</script>
  1. 自定义指令

    • 全局自定义指令

    • 局部自定义指令

      • 指令的钩子函数(一共有5个)
        • bind : 指令和元素第一次绑定的时候调用
        • inserted : 指令绑定的元素插入父节点的时候调用
        • update : 指令绑定的元素自身, 或是他的内容(子节点)发生改变的时候出发
        • componentUpdated : 指令绑定的组件自身, 或是他的内容(子节点)发生改变的时候出发
        • unbind : 指令和元素第一次解绑是调用
      • 指令的钩子函数的参数
        • el 当前元素
        • binding 前端指令的所有信息
        • vNode 当前指令绑定的虚拟节点
        • oldVnode 指令绑定前的虚拟节点
  2. 渲染函数 和 jsx

    1. 渲染函数 render函数 — 》 createElment
    2. jsx( javascript + xml )
      • xml 就是一种标签化的数据格式
      • jsx语法浏览器无法解析, 必须靠babel来解析
      • jsx语法出现的原因是为了解决,render函数频繁使用createElement来创建节点
  3. 过渡 & 动画

    过渡指的是 用 css3 的transition来实现动画效果
    动画指的是用 js来实现动画效果
    Vue中一共给了四种解决方案, 但是我们常用的只有一种

    • 在 CSS 过渡和动画中自动应用 class
    • 可以配合使用第三方 CSS 动画库,如 Animate.css 【推荐】
    • 在过渡钩子函数中使用 JavaScript 直接操作 DOM
    • 可以配合使用第三方 JavaScript 动画库,如 Velocity.js

    以下今后再补

  4. slot 插槽

  5. 动态组件 & 异步组件

  6. is属性

  7. 不常用指令

  8. 自定义插件

  9. webpack

  10. cli

  11. router

  12. vuex

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值