vue中父子组件之间的问题

父子组件生命周期顺序

渲染过程:
父beforeCreate -> 父created -> 父beforeMount -> 子beforeCreate -> 子created -> 子beforeMount -> 子mounted -> 父mounted

  • 当父组件执行完beforeMount挂载开始后,会依次执行子组件中的钩子,直到全部子组件mounted挂载到实例上,父组件才会进入mounted钩子
  • 子级触发事件,会先触发父级beforeUpdate钩子,再去触发子级beforeUpdate钩子,下面又是先执行子级updated钩子,后执行父级updated钩子

更新过程

子组件: beforeUpdate(父) - beforeUpdate(子)-updated(子)- updated(父)
父组件:beforeUpdate(父)- updated(父))

销毁过程

beforeDestroy(父)- beforeDestroy(子)- destroyed(子)- destroyed(父)

父子组件之间的传值

  • props:父组件直接绑定在子组件的标签上,子组件通过props接收传递过来的参数。

    父组件:

     <template>
    	<i-activities-item :content="content"/>
    </template>
    
    

    子组件

    <template>
    	<div>{{ content }}</div>
    </template>
    <script>
    	export default {
    	  name: '',
    	  props: {
    	    content: {
    	    	// 定义接收的类型 还可以定义多种类型 [String, Undefined, Number]
    	    	// 如果required为true,尽量type允许undefined类型,因为传递过来的参数是异步的。或者设置默认值。
    			type: String,
    			// 定义是否必须传
    			required: true,
    			// 定义默认值
    			default: '暂无'
    		},
    	  },
    
    	};
    </script>
    
  • $emit:触发当前实例上的事件。附加参数都会传给监听器回调。

       <div id="app">
            <counter @inc="addnumber"></counter>
        </div>
        <script>
            Vue.component('counter', {
                template: '<div @click="add">点击一下</div>',
                methods: {
                    add: function() {
                        this.$emit('inc', '大老虎')
                    }
                },
            })
        </script>
    
  • sync修饰符:在有些情况下,我们可能需要对一个 prop 进行“双向绑定”。不幸的是,真正的双向绑定会带来维护上的问题,因为子组件可以修改父组件,且在父组件和子组件都没有明显的改动来源。

     <text-document
      v-bind:title="doc.title"
      v-on:update:title="doc.title = $event"
    ></text-document>
    
    <text-document v-bind:title.sync="doc.title"></text-document>
    
    this.$emit('update:title', newTitle)
    
  • attrs和listeners

    attrs:包含了父作用域中不作为 prop 被识别 (且获取) 的特性绑定 (class 和 style 除外)。当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 (class 和 style 除外),并且可以通过 v-bind=“attrs” 传入内部组件——在创建高级别的组件时非常有用。

    listeners:包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on="$listeners" 传入内部组件——在创建更高层次的组件时非常有用。

     <div id="app">
        <child :foo="foo" :bar="bar" @one.native="triggerOne" @two="triggerTwo">
            <child>
    </div>
    <script>
        let Child = Vue.extend({
            template: '<h2>{{ foo }}</h2>',
            props: ['foo'],
            created() {
                console.log(this.$attrs, this.$listeners)
                    // -> {bar: "parent bar"}
                    // -> {two: fn}
    
                // 这里我们访问父组件中的 `triggerTwo` 方法
                this.$listeners.two()
                    // -> 'two'
            }
        })
    
        new Vue({
            el: '#app',
            data: {
                foo: 'parent foo',
                bar: 'parent bar'
            },
            components: {
                Child
            },
            methods: {
                triggerOne() {
                    alert('one')
                },
                triggerTwo() {
                    alert('two')
                }
            }
        })
    </script>
    
  • provide 和 inject 主要为高阶插件/组件库提供用例。并不推荐直接用于应用程序代码中。
    这对选项需要一起使用,以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在起上下游关系成立的时间里始终生效。如果你熟悉 React,这与 React 的上下文特性很相似。

      <div id="app">
            <child>
               </child>
        </div>
        <script>
            // 全局变量
            let EventBus = new Vue()
    
            // 子组件
            let Child = Vue.extend({
                template: '<h2>child</h2>',
                created() {
                    console.log(EventBus.message)
                        // -> 'hello'
                    EventBus.$emit('received', 'from child')
                }
            })
            new Vue({
                el: '#app',
                components: {
                    Child
                },
                created() {
                    // 变量保存
                    EventBus.message = 'hello'
                        // 事件监听
                    EventBus.$on('received', function(val) {
                        console.log('received: ' + val)
                            // -> 'received: from child'
                    })
                }
            })
        </script>
    
  • EventBus:思路就是声明一个全局Vue实例变量EventBus,把所有的通信数据,事件监听都存储到这个变量上,这样就到达在组件间实现数据共享,有点类似Vuex。但是这种方式只适合极小的项目,复杂的项目还是推荐Vuex。

  • Vuex :官方推荐,VueX是一个专门为Vue.js应用程序开发的状态管理模式

  • $root:当前组件树的根Vue实例,如果当前实例没有父实例,此实例将会是自己。通过访问根组件也能进行数据之间的交互,但极小情况下回直接修改父组件中的数据.

  • $parent:父实例,如果当前实例有的话,通过访问父实例也能进行数据之间的交互,但极小情况下回直接修改父组件中的数据

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值