Vue深入-8【组件注册、父子组件通信】

(1).注册组件的两种方式

1.全局注册组件

<script>
    Vue.component('my-cmp',{
        template:'<div>我的全局注册组件</div>'
    })
</script>

2.局部注册组件

let myLocalCmp={
    template:'<div>我的局部注册组件</div>'
}
new Vue({
    el:'#app',
    components:{
        myLocalCmp
    }
})

3.组件解析

组件就是个对象

通过vue-loder解析的对象

<template>
    <div>Test</div>
</template>
<script>
import App from './App';
console.log(App)
</script>

(2).jsx配合render注册组件中的html

1.render

也可以在render中直接输出html,下面这么写会报错

Vue.component('my-cmp',{
    render(h){
        renturn(
            <h1>hello</h1>
        )
    }
})

这里必须要写到组件中经过babel编译(下方就用cli了),且要禁用规则或者调用一下h才不会报错

<script>
    export default{
        render(h){
            console.log(h);
            return(
                <h1>App</h1>
            )
        }
    }
</script

(3).render的h函数注册组件中的html

h函数中有三个参数,第一个为标签名,第二个为类名/id等,第三个为嵌套

1.第三个参数

基础用法

h的第三个参数就是为嵌套关系(儿子)

如果有多个会将多个拼接在一起

<script>
    export default{
        render(h){
            return h('h1',{},['Test1','Test2'])
        }
    }
</script>


 

嵌套标签

<script>
    export default{
        render(h){
            return h('h1',{},[
                h('span',{},'这是一个span')
            ])
        }
    }
</script>

循环创建

<scipt>
    export default{
        data(){
            return{
                items:['span1','span2']
            }
        },
        render(h){
            return h('h1',{},this.items.map((item)=>{
                return h('span',{},item)
            }))
        }
    }
</script>

2.第二个参数

可以写类名/id/样式等等

记得驼峰或者横杠

<script>
    export default{
        render(h){
            return h('h1',{
                //类名
                class:{
                    test:true,
                    'another-class':true
                },
                //样式
                style:{
                    color:'red',
                    fontSize:'100px'
                },
                //id
                attrs:{
                    id:'test'
                },
                //事件响应
                on:{
                    click:this.xx
                }
            })
        }
    }
</script>

(4).父子组件通信

1.引入标签传值通信

<template>
    <div>
        <h1>父亲</h1>
        <Child :message="message"/>
    </div>
</template>
<script>
    import Child from './Child';
    export default{
        components:{
            Child
        },
        data(){
            return{
                message:'Hello Parent'
            }
        }
    }
</script>

<template>
    <div>
        <h1>孩子</h1>
        <p>{{message}}</p>
    </div>
</template>
<script>
    export default{
        props:['message']
    }
</script> 

2.$emit通信

<template>
    <div>
        <h1>父亲</h1>
        <Child :message="message" @changeMessage="message=$event"/>
    </div>
</template>
<script>
    import Child from './Child';
    export default{
        components:{
            Child
        },
        data(){
            return{
                message:'Hello Parent'
            }
        }
    }
</script>

<template>
    <div>
        <h1>孩子</h1>
        <p>{{message}}</p>
        <button @click="handleClick">按钮</button>
    </div>
</template>
<script>
    export default{
        props:['message'],
        methods:{
            handleClick(){
                this.$emit('changeMessage','Bye')
            }
        }
    }
</script>

3.直接将函数传递下去

这里vue会将this传递下去

<template>
    <div>
        <h1>父亲</h1>
        <Child :message="message" :changeMessageFn="changeMessage"/>
    </div>
</template>
<script>
    import Child from './Child';
    export default{
        components:{
            Child
        },
        data(){
            return{
                message:'Hello Parent'
            }
        },
        methods:{
            changeMessage(value){
                this.message = value
            }
        }
    }
</script>

<template>
    <div>
        <h1>孩子</h1>
        <p>{{message}}</p>
        <button @click="changeMessageFn('回调函数')">按钮</button>
    </div>
</template>
<script>
    export default{
        props:['message','changeMessageFn'],
        methods:{
            handleClick(){
                this.$emit('changeMessage','Bye')
            }
        }
    }
</script>   

需要注意

data和props在初始化的时候会做合并,如果重名会报错

<script>
    export default{
        data(){
            return {
                message:'data里的message'
            }
        },
        props:['message','changeMessageFn'],
        methods:{
            handleClick(){
                this.$emit('changeMessage','Bye')
            }
        }
    }
</script>

4.$children访问儿子data

<template>
    <div>
        <h1>父亲</h1>
        <p>{{message}}</p>
        <button @click="changeChildNumber">按钮</button>
        <Child/>
    </div>
</template>
<script>
    import Child from './Child';
    export default{
        components:{
            Child
        },
        data(){
            return{
                message:'Hello Parent'
            }
        },
        methods:{
            changeChildNumber(){
                this.$children[0].number = 50
            }
        }
    }
</script>

<template>
    <div>
        <h1>孩子</h1>
        <p>{{number}}</p>
    </div>
</template>
<script>
    export default{
        data(){
            return{
                nmber:30
            }
        }
      
    }
</script> 

$children的顺序是不一定的,所以节制调用

5.通过$parent来访问父实例

<template>
    <div>
        <h1>孩子</h1>
        <p>{{parentMessage}}</p>
    </div>
</template>
<script>
    export defalut{
        data(){
            return {
                number:10
            }
        },
        computed:{
            parentMessage(){
                return this.$parent.message
            }
        }
    }
</script>

同时也可以获取到父组件的名称

this.$parent.$options.name

$parent $children是没什么用的,通常用于组件库去查询到父组件的名称

6.provide,inject

所有inject都可以获取到provide声明的值,无论是什么层级的组件

<template>
    <div>
        <h1>父亲</h1>
        <Child/>
    </div>
</template>
<script>
    import Child from './Child';
    export default{
        provide:{
            message:'Hello Parent'
        },
        components:{
            Child
        }
    }
</script>

<template>
    <div>
        <h1>孩子</h1>
        {{message}}
        <GrandChild/>
    </div>
</template>
<script>
    import GrandChild from './GrandChild'
    export default{
        inject:['message'],
        components:{
            GrandChild
        }
    }
</script>

<template>
    <div>
        <h1>孙子</h1>
        {{message}}
    </div>
</template>
<script>

    export default{
        inject:['message']
    }
</script>

7.$attrs $listeners

1.$attrs 和v-bind

$attrs可以不接收父亲的data,保存在attrs中传递给孙子

<template>
    <div>
        <h1>父亲</h1>
        <p>姓名:{{name}}</p>
        <p>年龄:{{age}}</p>
        <Child :name="name" :age="age"/>
    </div>
</template>
<script>
    import Child from './Child';
    export default{
        components:{
            Child
        },
        data(){
            return {
                name:'zza',
                age:20
            }
        }
    }
</script>

<template>
    <div>
        <h1>孩子</h1>
        <GrandChild v-bind="$attrs"/> //这里的v-bind就是简化了参数的传递
    </div>
</template>
<script>
    import GrandChild from './GrandChild';
    export default{
        components:{
            GrandChild
        }
    }
</script>

<template>
    <div>
        <h1>孙子</h1>
        {{name}}
        {{age}}
    </div>
</template>
<script>

    export default{
        props:['name','age']
    }
</script>

 $listeners监听父亲监听器触发的函数

触发父级绑定的事件处理函

<template>
    <div>
        <h1>父亲</h1>
        <p>姓名:{{name}}</p>
        <p>年龄:{{age}}</p>
        <Child :name="name" :age="age" @test="changeName"/>
    </div>
</template>
<script>
    import Child from './Child';
    export default{
        components:{
            Child
        },
        data(){
            return {
                name:'zza',
                age:20
            }
        },
        methods:{
            changeName(){
                this.name='小夏'
            }
        }
    }
</script>

<template>
    <div>
        <h1>孩子</h1>
        <button @click="$listeners.test">按钮</button>
      
    </div>
</template>

8.$refs.childComp

引用组件事件

<template>
    <div>
        <h1>父亲</h1>
         <button @click="changeAge">按钮</button>
        <Child ref="childComp"/>
    </div>
</template>
<script>
    import Child from './Child';
    export default{
        components:{
            Child
        },
        methods:{
            changeAge(){
                console.log('before',this.$refs.childComp.age)//20
                this.$refs.childComp.changeAge();
                 console.log('before',this.$refs.childComp.age)//50
            }
        }
    }
</script>

<template>
    <div>
        <h1>孩子</h1>
        <button>按钮</button>
      
    </div>
</template>
<script>
    export default{
        data(){
            return {
                age:20
            }
        },
        methods:{
            changeAge(){
                this.age=50
            }
        }
    }
</script>

$ref也可以获取dom

<template>
    <div>
        
        <div ref="mydiv"></div>
    </div>
</template>
<script>
mounted(){
    console.log(this.$refs.myDiv)
    this.$refs.myDiv.innerHtml="Hello"
}
</script

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值