2021.11.28 vue 生命周期 (9)

生命周期的基本概念

我们一起回顾一下上节课讲到的,过渡的几个钩子函数:

<body>
  <div id='app'>
    <button @click='show=!show'>btn</button>
    <transition :css=false @before-enter='fn1' @enter='fn2' @after-enter='fn3'>
      <h1 v-if='show'>嘿嘿嘿</h1>
    </transition>
  </div>

  <script src='./js/vue.js'></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        show: false
      },
      methods: {
        fn1(el) {
          el.style.color = 'red'
        },
        fn2(el, done) {
          const id = setInterval(() => {
            if (el.style.color === 'red') {
              el.style.color = 'green'
            } else {
              el.style.color = 'red'
            }
          }, 1000);
          setTimeout(() => {
            clearInterval(id)
            done()
          }, 3000);
        },
        fn3() {
          alert(666)
        }
      }
    })
  </script>
</body>

以上的3个过渡的钩子函数,就是在我们的动画这个周期内,在每个时间段,我们都可以去设置不同的代码去完成相对应的事,比如在动画开始之前我们需要什么操作,在动画执行过程中我们需要什么操作,动画执行完后我们需要什么操作,都可以写在函数里面去完成

vue的生命周期也是同样的道理,每个 Vue 实例在被创建时都要经过一系列的初始化过程

例如,需要设置数据监听、编译模板、将实例挂载到DOM 并在数据变化时更新DOM 等。同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会。

比如created钩子可以用来在一个实例被创建之后执行的代码:

<script>
  const app = new Vue({
    el: '#app',
    data: {
      msg: '哈哈哈'
    },
    created: function () {
      console.log(this.msg);
    }
  })
</script>

生命周期的基本概念

请添加图片描述
请添加图片描述

vue的方法和混入/自定义指令

vue的全局方法

Vue.extend( options )

使用基础 Vue 构造器,创建一个“子类”。参数是一个包含组件选项的对象。data 选项是特例,需要注意 - 在 Vue.extend() 中它必须是函数.

const Profile = Vue.extend({
  template: '<h1>{{name}}->{{num}}</h1>',
  data() {
    return {
      name: 'kobe',
      num: 8
    }
  }
})

vue的全局方法之nextTick

Vue.nextTick( [callback, context] )

在下次DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的DOM。

const app = new Vue({
  el: '#app',
  data: {
    msg: '123'
  }
})
console.log(app.msg);
app.msg = 'new msg' //更改数据
console.log(document.getElementById('app').innerText); //dom还没有更新
Vue.nextTick(function () {
  console.log(document.getElementById('app').innerText); //dom已经更新
})

vue的实例方法之nextTick

app.$nextTick( [callback] )

将回调延迟到下次DOM 更新循环之后执行。在修改数据之后立即使用它,然后等待DOM 更新。它跟全局方法Vue.nextTick 一样,不同的是回调的this 自动绑定到调用它的实例上。

const app = new Vue({
  el: '#app',
  data: {
    msg: '你好,世界'
  },
  methods: {
    fn() {
      this.msg = 'hello world'
      console.log(document.getElementById('demo').innerText); //dom还没有更新
      this.$nextTick(function () {
        console.log(document.getElementById('demo').innerText); //dom已经更新
      })
    }
  }
})

vue的实例方法之destroy

vm.$destroy()

完全销毁一个实例。清理它与其它实例的连接,解绑它的全部指令及事件监听器。触发beforeDestroy和destroyed的钩子。

vue的混入

混入 (mixin) 提供了一种非常灵活的方式,来分发 Vue 组件中的可复用功能。一个混入对象可以包含任意组件选项( 比如可以单独把数据或是方法什么的单独变成一个混合对象 )。当组件使用混入对象时,所有混入对象的选项将被“混合”进入该组件本身的选项。

<script>
  const app = new Vue({
    el: '#app',
    data: {

    },
    components: {
      cpn1: {
        template: '<div><h1 v-if="show">cpn1</h1><button @click="fn">cpn1</button></div>',
        data() {
          return { show: true }
        },
        methods: {
          fn() {
            this.show = !this.show
          }
        }
      },
      cpn2: {
        template: '<div><h1 v-if="show">cpn2</h1><button @click="fn">cpn2</button></div>',
        data() {
          return { show: true }
        },
        methods: {
          fn() {
            this.show = !this.show
          }
        }
      }
    }
  })
</script>

上面的案例罗级很简单,我们定义了两个组件cpn1和cpn2,用show的布尔值去控制h1标签内容的显示,我们发现cpn1和cpn2这两个组件中的data和methods中的内容时一样的,此时我们可以用mixins将这些相同的内容提取出来再分发到每个组件中.

<script>
  const mixData = {
    data() {
      return { show: true }
    },
    methods: {
      fn() {
        this.show = !this.show
      }
    }
  }
  const app = new Vue({
    el: '#app',
    data: {

    },
    components: {
      cpn1: {
        mixins: [mixData],
        template: '<div><h1 v-if="show">cpn1</h1><button @click="fn">cpn1</button></div>',
      },
      cpn2: {
        mixins: [mixData],
        template: '<div><h1 v-if="show">cpn2</h1><button @click="fn">cpn2</button></div>',
      }
    }
  })
</script>

vue混入的数据选项合并

当组件和混入对象含有同名选项时,这些选项将以恰当的方式进行“合并”。

比如,数据对象在内部会进行递归合并,并在发生冲突时以组件数据优先。

<script>
  const mixData = {
    data() {
      return {
        show: true,
        name: 'kobe'
      }
    },
    methods: {
      fn() {
        this.show = !this.show
      }
    }
  }
  const app = new Vue({
    el: '#app',
    data: {

    },
    components: {
      cpn1: {
        mixins: [mixData],
        template: '<div><h1 v-if="show">cpn1{{show}}</h1><button @click="fn">cpn1</button></div>',
        data() {
          return {
            show: 'test',
            num: 8
          }
        },
      },
      cpn2: {
        mixins: [mixData],
        template: '<div><h1 v-if="show">cpn2</h1><button @click="fn">cpn2</button></div>',
      }
    }
  })
</script>

请添加图片描述

vue混入的钩子函数选项合并

同名钩子函数将合并为一个数组( 数组的每一项都是一个函数, 当钩子被触发之后, 数组里面的每个函数都会执行依次的 ),因此都将被调用。另外,混入对象的钩子将在组件自身钩子之前调用。
请添加图片描述

<script>
  const mixData = {
    data() {
      return {
        show: true,
        name: 'kobe'
      }
    },
    methods: {
      fn() {
        this.show = !this.show
      }
    },
    created() {
      console.log('混入对象的钩子被调用');
    }
  }
  const app = new Vue({
    el: '#app',
    data: {

    },
    components: {
      cpn1: {
        mixins: [mixData],
        template: '<div><h1 v-if="show">cpn1{{show}}</h1><button @click="fn">cpn1</button></div>',
        data() {
          return {
            show: 'test',
            num: 8
          }
        },
        created() {
          console.log('组件钩子被调用');
        }
      }
    }
  })
</script>

相当于:

created: [function () { console.log('混入对象的钩子被调用') }, function () { console.log('组件钩子被调用') }]

vue混入的对象选项合并

值为对象的选项,例如methods、components和 directives,将被合并为同一个对象。两个对象键名冲突时,取组件对象的键值对。

<script>
  const mixData = {
    data() {
      return {
        msg: '嘿嘿嘿'
      }
    },
    methods: {
      fn() {
        console.log('from mixins');
      },
      fn1() {
        console.log('from mixins1');
      }
    }
  }
  const app = new Vue({
    el: '#app',
    data: {

    },
    components: {
      cpn: {
        mixins: [mixData],
        template: '<div><h1>{{msg}}</h1><button @click="fn">btn</button><button @click="fn1">btn1</button></div>',
        methods: {
          fn() {
            console.log('from cpn');
          }
        }
      }
    }
  })
</script>

vue的全局混入

混入也可以进行全局注册。使用时格外小心!一旦使用全局混入,它将影响每一个之后创建的Vue 实例。使用恰当时,这可以用来为自定义选项注入处理逻辑。

Vue.mixin( options )

<body>
  <div id='app'>
    <cpn></cpn>
  </div>

  <div id="vm">
    <cpn></cpn>
  </div>

  <script src='./js/vue.js'></script>
  <script>
    Vue.mixin({
      methods: {
        fn() {
          console.log('我是全局mixins');
        }
      }
    })
    const app = new Vue({
      el: '#app',
      data: {

      },
      components: {
        cpn: {
          template: '<div><button @click="fn">btn_app</button></div>'
        }
      }
    })

    const vm = new Vue({
      el: '#vm',
      data: {

      },
      components: {
        cpn: {
          template: '<div><button @click="fn">btn_vm</button></div>'
        }
      }
    })
  </script>
</body>

使用全局方法设置的混合, 会在之后的每一个Vue实例中进行混合,就如同是直接修改了Object.prototype一样

请谨慎使用全局混入,因为它会影响每个单独创建的Vue 实例 (包括第三方组件)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值