Vue11-其他语法补充

152 阅读2分钟

非父子间的组件通信

分为两种方式

1.Provide/Inject

专门给子孙用的,兄弟不行

图片.png 爷孙之间用props就会很麻烦,通过provide和Inject就可以避免这么麻烦。

App.vue

<template>

</template>

<script>
    ipmort Home from './Home.vue'
    import { computed } from 'vue'
    
    export default{
        components:{
            Home
        },
        
//1.provide:开始为别人提供数据        
        provide:{
        最好默认写成函数形式,也就是return{}
        //1.使用return,否则this指向有问题
            return{
                name:"why",
                age:18//2.想拿到一个对象数据,在provide必须使用return
                length:this.names.length
        //这里length不是响应式的,names数组长度改变是,length其实是不变的
        //后期会告诉为什么这样做,就能变成响应式
                length:computed(()=> this.names.length)
            }    
        },
        data(){
            return{
                names:["abc","cba"]
            }
        }
    }    
</script>

length讲解:computed一般会传递一个getter函数,所以直接写箭头函数就行;这里的this就是想找provide中的this

Home.vue

<template>

</template>

<script>
    ipmort HomeContent from './HomeContent.vue'
</script>

HomeContent.vue

<template>
    <div>
    这里length其实是ref对象,具体的值要通过value
        {{name}}--{{age}}---{{length.value}}
    </div>
</template>

<script>
    export default{
//2.使用provide提供的数据,就需要inject注入        
        inject:['name','age']
    }
    
</script>

以上是组件之间数据的传输,可是我想要组件间,非连接的组件之间的,事件的传递,那么就使用全局事件总线!

2.Mitt全局事件总线库

图片.png

npm install mitt

其次可以进行封装

eventbus.js

//mitt实质是一个函数
import mitt from 'mitt'

const emitter = mitt();

export default emitter;

App.vue

<template>

</template>

<script>
    import Home from './Home.vue'
    import About from './About.vue'
    export default{
        components:{
            Home,
            About,
        }
    }
</script>

Home

<template>

</template>

<script>
    import 
    export default{
        
    }
</script>

About

<template>
    <div>
        <button @click="btnClick"/>
    </div>
</template>

<script>
    import emmiter from './eventbus'

    export default{
        components:{
            
        },
        methods:{
            btnClick(){
                emmiter.emit("why",{name:"why",age:"18"})
                console.log('我是About')
            }
        }
    }
</script>

HomeContent.vue

<template>

</template>

<script>
    import emitter from './eventbus'
    export default{
    一开始创建的时候我就监听函数
        created(){
            emitter.on("why",(info)=>{
                console.log('我是HomeContent')
            })
        }
    }
</script>

在About中通过emitter发送了一个事件,HomeContent中监听

当我点击About中的click时,我的HomeContent也会触发事件

demo06.gif

取消emitter中所有的监听

emitter.all.clear()

图片.png

实际上,我们更推荐Vuex来进行组件间的通信

认识插槽Slot

图片.png

如何使用插槽slot?

图片.png

App.vue

<template>
    <div>
    这个时候,MySlot的位置就变成了一个按钮,也可以插入组件
        <my-slot-cpn>
            <button>我是按钮</button>
        </my-slot-cpn>
    </div>
</template>

<script>
    import MySlotCpn from './MySlotCpn.vue'
    export default{
        components:{
            MySlotCpn,
        }
    }
</script>

MySlotCpn.vue

<template>
    <h2>组件开始</h2>

//由外界决定我要显示什么,先占一个坑,预留插槽    
    <slot></slot>

    <h2>组件结束</h2>
</template>

<script>
    import 
    export default{
    }
</script>

插槽的默认内容

当我没有传给插槽内容时,插槽可以定义默认元素

    <my-slot-cpn></my-slot-cpn>
    
    <slot>
        <i>我是默认元素,当我my-slot-cpn插入数据时,我的i元素就会消失</i>
    </slot>

当我在插槽里定义了很多数据,一个坑位就能把所有的数据全部展示

<slot></slot>

图片.png

但是如果我定义了很多数据,也占了很多坑位,那么每个坑位都会显示数据,所以需要我们手工指定具体给哪个坑位。也就是具名插槽

具名插槽的使用

必须在template标签里书写

v-slot:插槽里写的name的值
图片.png

图片.png

这样每个插槽都有自己需要的数据了

图片.png

图片.png

有些时候,我插槽里的name不是写死的,而且通过配置决定插槽的名字

App.vue

<nav-bar :name="name">
//v-slot:name表示取 名叫name的插槽,并不会取值,所以要用[]表示取值
    <template v-slot:[name]>
        <i>我是传数据的,NavBar里是占坑的</i>
    </template>
</nav-bar>

data(){
    return{
        name:"why"
    }
}

NavBar.vue

    <slot :name="name"></slot>
    props:{
    接收父组件传来的name值是why
        name:String
    }

具名插槽v-slot的简写:#

图片.png

作用域插槽的使用

图片.png

图片.png

认识作用域插槽

图片.png v-slot="slotProps",slotProps就是坑位里写的属性

子组件

图片.png

父组件

图片.png

如果插槽有name,name就要指定名字

<slot name="why">

图片.png

独占默认插槽的缩写

当只有一个插槽占坑时,并且不是具名插槽,就可以删除template

完整前:

图片.png

简写后:

图片.png