zoukankan      html  css  js  c++  java
  • Vue生命周期 钩子函数和组件传值

    Vue生命周期 钩子函数

    每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等。

    同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会。(来源:官方文档)

    官方生命周期图示:

    生命周期的钩子函数见下表

    钩子函数 触发的行为 在此阶段可以做的事情
    beforeCreadted

    vue实例的挂载元素$el和数据对象data

     都为undefined,还未初始化。

    加loading事件
    created

    vue实例的数据对象data有了,$el还没有

    结束loading、请求数据为mounted渲染做准备
    beforeMount

    vue实例的$el和data都初始化了,但还是虚拟的dom节点,

    具体的data.filter还未替换。

    ...
    mounted vue实例挂载完成,data.filter成功渲染 配合路由钩子使用
    beforeUpdate data更新时触发 ...
    updated data更新时触发

    数据更新时,做一些处理(此处也可以用

    watch进行观测)

    beforeDestroy 组件销毁时触发 ...
    destroyed

    组件销毁时触发,vue实例解除了事件监听以及和dom的绑定

    (无响应了),但DOM节点依旧存在

    组件销毁时进行提示

    说明一下: 

    beforeCreate:el 和 data 并未初始化 (此方法不常用) 

    created:完成了 data 数据的初始化,el的初始化未完成。用来发送ajax

    beforeMount:(执行此方法时已经完成了 el 和 data 初始化 (已经赋予了对应的值)) 

    渲染DOM之前先确认下是否有要编译的根元素(有无el属性),有才继续确认是否具有模板属性template,如果有模版属性,则会用template的值替

    换掉HTML中的结构,template模版中只能有一个根元素(而且不能是文本); 

    mounted:(执行此方法时代表已经挂载结束了) 

    把编译好的数据挂载到DOM元素上,最后渲染成真实的DOM元素;真实DOM已经渲染完成,可以操作DOM了

    beforeUpdate:当页面依赖的数据更改之后触发(此时DOM结构还没有重新加载) 

    updated:DOM结构重新加载之后触发

    调用vm.$destroy()之后触发下面两个事件: 

    beforeDestroy:实例销毁之前调用。在这一步,实例仍然完全可用。(可在此处清除定时器,清除事件绑定) 

    destroyed:Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。

    destroyed钩子函数有一点一定要特别注意:在执行destroy方法后,对data的改变不会再触发周期函数,此时的vue实例已经解除了事件监听

    以及和dom的绑定,但是dom结构依然存在。所以对于实时显示的通知型组件,在他destroyed之前,我们必须手动removeChild()删除该节点;

    否则,DOM节点还是存在,影响浏览器性能。

    注意:

    所有的生命周期钩子自动绑定this上下文到实例中,因此你可以访问数据,对属性和方法进行运算。这意味着你不能使用箭头函数来定义一个

    生命周期方法(例如created: () => this.fetchTodos())。这是因为箭头函数绑定了父上下文,因此this与你期待的 Vue 实例不同,

    this.fetchTodos的行为未定义。

    测试代码:

    export default {
      data () {
        return {
          todos: [],
          allCounts: 0,
          filter: 'all',
          id: 0,
          states: ['all', 'active', 'completed']
        }
      },
      beforeCreate () {
        console.log('==============' + 'beforeCreated' + '===================')
        console.log(this.$el)
        console.log(this.$data)
        console.log(this.filter)
      },
      created () {
        console.log('==============' + 'created' + '===================')
        console.log(this.$el)
        console.log(this.$data)
        console.log(this.filter)
      },
      beforeMount () {
        console.log('==============' + 'beforeMount' + '===================')
        console.log(this.$el)
        console.log(this.$data)
        console.log(this.filter)
      },
      mounted () {
        console.log('==============' + 'mounted' + '===================')
        console.log(this.$el)
        console.log(this.$data)
        console.log(this.filter)
      },
      beforeUpdate () {
        console.log('==============' + 'beforeUpdate' + '===================')
        console.log(this.$el)
        console.log(this.$data)
        console.log(this.filter)
      },
      updated () {
        console.log('==============' + 'updated' + '===================')
        console.log(this.$el)
        console.log(this.$data)
        console.log(this.filter)
      },
      beforeDestroy () {
        console.log('==============' + 'beforeDestroy' + '===================')
        console.log(this.$el)
        console.log(this.$data)
        console.log(this.filter)
      },
      destroyed () {
        console.log('==============' + 'destroyed' + '===================')
        console.log(this.$el)
        console.log(this.$data)
        console.log(this.filter)
      }
     }

    测试结果:

    组件传值

    Vue常用的三种传值方式有:

      父传子

      子传父

      非父子传值

    引用官网的一句话:父子组件的关系可以总结为 prop 向下传递,事件向上传递。父组件通过 prop 给子组件下发数据,子组件通过事件给父

    组件发送消息。

    1.父组件向子组件进行传值

    父组件

    <template>
      <div>
        父组件:
        <input type="text" v-model="name">
        <br>
        <br>
        <!-- 引入子组件 -->
        <child :inputName="name"></child>
      </div>
    </template>
    <script>
      import child from './child'
      export default {
        components: {
          child
        },
        data () {
          return {
            name: ''
          }
        }
      }
    </script>

    子组件

    <template>
      <div>
        子组件:
        <span>{{inputName}}</span>
      </div>
    </template>
    <script>
      export default {
        // 接受父组件的值
        props: {
          inputName: String,
          required: true
        }
      }
    </script>

    子组件通过props接收父组件传回的值

    2.子组件向父组件传值

    父组件

    <template>
      <div>
        父组件:
        <span>{{name}}</span>
        <br>
        <br>
        <!-- 引入子组件 定义一个on的方法监听子组件的状态-->
        <child v-on:childByValue="childByValue"></child>
      </div>
    </template>
    <script>
      import child from './child'
      export default {
        components: {
          child
        },
        data () {
          return {
            name: ''
          }
        },
        methods: {
          childByValue: function (childValue) {
            // childValue就是子组件传过来的值
            this.name = childValue
          }
        }
      }
    </script>

    子组件

    <template>
      <div>
        子组件:
        <span>{{childValue}}</span>
        <!-- 定义一个子组件传值的方法 -->
        <input type="button" value="点击触发" @click="childClick">
      </div>
    </template>
    <script>
      export default {
        data () {
          return {
            childValue: '我是子组件的数据'
          }
        },
        methods: {
          childClick () {
            // childByValue是在父组件on监听的方法
            // 第二个参数this.childValue是需要传的值
            this.$emit('childByValue', this.childValue)
          }
        }
      }
    </script>

    子组件通过事件派发向父组件传值

    3.兄弟组件通信

    通过事件总线的方式实现就是一个空的vue示例只用来绑定方法。

    举个例子:

    1 在main.js中全局注册一个

    data:{
      eventHub: new Vue()
    }

    2 在组件a里定义需要传的参数

    self.$root.eventHub.$emit('add',{tabnum:tab.index,yuid:tab.$vnode.key,);

    3 在组件b里取得需要接受的参数

    self.$root.eventHub.$on('add',function(data) {
      self.tabnum = data.tabnum;
      self.yunid = data.yuid;
      }
    })
  • 相关阅读:
    MyBatis3: There is no getter for property named 'code' in 'class java.lang.String'
    jQuery获取Select选择的Text和 Value(转)
    mybatis3 :insert返回插入的主键(selectKey)
    【转】Mybatis/Ibatis,数据库操作的返回值
    Android问题-打开DelphiXE8与DelphiXE10编译空工程提示“[Exec Error] The command exited with code 1.”
    Android问题-打开DelphiXE8与DelphiXE10新建一个空工程提示"out of memory"
    BAT-使用BAT生成快捷方式
    给 TTreeView 添加复选框
    跨进程发送消息数据
    鼠标拖动虚影效果
  • 原文地址:https://www.cnblogs.com/wxf-h/p/10651842.html
Copyright © 2011-2022 走看看