Vue 组件 + 组件之间传值 + 组件插槽

Posted 鲸渔要加油

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vue 组件 + 组件之间传值 + 组件插槽相关的知识,希望对你有一定的参考价值。

文章目录

组件

组件就是把各自独立的积木拼成一个整体然后进行数据交互


一、组件注册


1. 全局注册

组件注意事项

  • 全局组件 注册后,任何 vue实例 都可以用
  • 组件参数的data值必须是函数同时这个函数要求返回一个对象
  • 组件模板必须是单个根元素
  • 组件模板的内容可以是模板字符串
 Vue.component('组件名称', 
     data: function () return,	// data 在这里是函数
     template: '模板'
 )

就是相当于封装了一个模板,然后任何 vue实例 都可以用它自定义的名字来调用它


2. 局部注册

  • 只能在当前注册它的vue实例中使用
 let aaa = 
     data() 
         return 
             ppp: 'ppp'
         
     ,
     template: `<div>ppp</div>`
 
 // Vue 组件
 const vm = new Vue(
     el: '#box',
     components: 
         'xxx': aaa  // 使用 <xxx></xxx>
     
 )


二、组件之间传值


1. 父组件向子组件传值

父组件在子组件的模板标签里面,使用属性传值给子组件的 props 接收,子组件直接template 定义模板里面使用

  • 父组件发送的形式是以属性的形式绑定值到子组件身上,有静态和加 : 的动态两种形式
  • 然后子组件用属性 props 接收
  • 在 props 中使用驼峰形式,模板中需要使用短横线的形式字符串形式的模板中没有这个限制

props 属性值类型

  • 字符串 String
  • 数值 Number
    静态绑定是传字符串,: 动态绑定是数值
  • 布尔 Boolean
    静态绑定是传字符串,: 动态绑定是布尔
  • 数组 Array
  • 对象 Object
<body>
    <div id="box">
        <ce-shi :pstr='pstr' :pnum='10' :pboo='true' :parr='parr' :pobj='pobj'></ce-shi>
    </div>

    <script src="../vue.js"></script>
    <script>
        Vue.component('CeShi', 
            props: ['pstr', 'pnum', 'pboo', 'parr', 'pobj'],
            template: `
            <div>
                <div>pstr</div>
                <div>pnum + 10</div>
                <div>pboo</div>
                <ul>
                    <li :key='index' v-for='(item,index) in parr'>item</li>
                </ul>
                <div>
                    <span>pobj.name</span>
                    <span>pobj.age</span>
                    <span>pobj.like</span>
                </div>
            </div>
            `
        )

        const vm = new Vue(
            el: '#box',
            data: 
                pstr: 'yjy',
                parr: [1, 2, 3],
                pobj: 
                    name: '远近渔',
                    age: 18,
                    like: 'me'
                
            
        )
    </script>
</body>

2. 子组件向父组件传值

虽然可以从子组件传数据到父组件,但别用
props 传数据的原则:单项数据流,只能父传子,不要子传父

  • 子组件调用 $emit() 方法触发事件
  • $emit() 第一个参数为自定义的事件名称,第二个参数为需要传递的数据
  • 父组件用 v-on 监听子组件的事件
<body>
    <div id="box">
        <ce-shi @big='dadada'></ce-shi>
        <div :style='fontSize: font + "px"'>parr</div>
    </div>

    <template id="moban">
        <div>
            <button @click='$emit("big")'>扩大</button>
        </div>
    </template>
    <script src="../vue.js"></script>
    <script>
        Vue.component('CeShi', 
            template: `#moban`,
        )

        const vm = new Vue(
            el: '#box',
            data: 
                parr: '远近渔',
                font: 10
            ,
            methods: 
                dadada() 
                    this.font += 5
                
            
        )
    </script>
</body>

$event是固定写法

<body>
    <div id="box">
        <ce-shi @big='bbb($event)'></ce-shi>
        <div :style='fontSize: font + "px"'>msg</div>
    </div>

    <template id="moban">
        <div>
            <button @click='$emit("big", 100)'>变大</button>
        </div>
    </template>
    <script src="../vue.js"></script>
    <script>
        Vue.component('CeShi', 
            template: `#moban`,
        )

        const vm = new Vue(
            el: '#box',
            data: 
                msg: '远近渔',
                font: 10
            ,
            methods: 
                bbb(v) 
                    this.font += v
                
            
        )
    </script>
</body>

3. 兄弟组件间传值

  • 兄弟之间传递数据需要通过 事件中心
    let hub = new Vue() 来作为 事件中心

  • 传递数据通过一个事件 触发 hub.$emit(名, 传递的数据)

  • 接收数据 ,在 mounted() 钩子中触发 hub.$on(名, (接收的值)=>做的事) 方法

  • 销毁事件 ,在父组件中通过 hub.$off(名) 方法名销毁之后无法进行传递数据

<body>
    <div id="box">
        <one></one>
        <two></two>
        <button @click='c'>禁止</button>
    </div>

    <script src="../vue.js"></script>
    <script>
        let hub = new Vue()

        Vue.component('one', 
            data() 
                return 
                    num: 0
                
            ,
            template: `
            <div>
                <div>one --- num</div>
                <button @click='a'>+++2</button>
            </div>
             `,
            methods: 
                a() 
                    hub.$emit('two-b', 2)
                
            ,
            mounted() 
                hub.$on('one-a', (v) => 
                    this.num += v
                )
            
        )

        Vue.component('two', 
            data() 
                return 
                    num: 0
                
            ,
            template: `
            <div>
                <div>two --- num</div>
                <button @click='b'>+++1</button>
            </div>
             `,
            methods: 
                b() 
                    hub.$emit('one-a', 1)
                
            ,
            mounted() 
                hub.$on('two-b', (v) => 
                    this.num += v
                )
            
        )

        const vm = new Vue(
            el: '#box',
            methods: 
                c() 
                    hub.$off('two-b')
                    hub.$off('one-a')
                
            
        )
    </script>
</body>


三、组件插槽

组件插槽的作用: 父组件向子组件传递内容(模板的内容)

因为父组件在子组件的模板里面写东西无法显示,所以使用插槽把父组件标签里面的内容传到子组件


1. 匿名插槽

插槽位置
子组件的模板里面预留 <slot></slot> 位置接收父的自定义内容

插槽内容
slot 里面可以写默认的内容,父的标签里面可以自定义内容

<body>
    <div id="box">
        <aaa>有刺客</aaa>
        <aaa></aaa>
    </div>

    <script src="../vue.js"></script>
    <script>
        Vue.component('aaa', 
            template:`
            <div>
                <strong>ERROR:</strong>
                <slot>123</slot>
            </div>
            `
        )
        
        const vm = new Vue(
            el: '#box',
        )
    </script>
</body>

2. 具名插槽

  • 使用 <slot> 中的 "name" 属性绑定元素
  • 模板里面写 <slot name='abc'></slot>
  • 标签里面写 <p slot="abc">xxxxxxx</p>
  • slot 属性 只能加给子组件里面的内容标签
  • 如果元素没有绑定 slot 属性 ,则放到默认的插槽 <slot></slot>
  • 一个个加属性太麻烦,可以放到总的 <template slot="abc"><p>xxx</p></template> 里面
<body>
    <div id="box">
        <aaa>
            <p slot="abc">xxx</p>
            <p slot="ggg">yyy</p>
            <p slot="www">zzz</p>
            <p>qwerqwerqwer</p>
            <p>asdfasdfasdfasdf</p>
        </aaa>
        
        <aaa>
            <template slot="abc">
                <p>xxx</p>
                <p>qwerqwerqwer</p>
                <p>asdfasdfasdfasdf</p>
            </template>   
            <template slot="ggg">
                <p>123</p>
                <p>321</p>
                <p>213</p>
            </template>   
        </aaa>
        
    </div>

    <script src="../vue.js"></script>
    <script>
        Vue.component('aaa', 
            template:`
            <div>
                <slot></slot>
                <slot name='ggg'></slot>
                <strong>123</strong>
                <slot name='abc'></slot>
                <slot name='www'></slot>
            </div>
            `
        )
        
        const vm = new Vue(
            el: '#box',
        )
    </script>
</body>

3. 作用域插槽

  • 好处,既可以父用子组件的slot,又可以使slot内容不一致
  • 因为子组件的东西一般都是封装好的,所以我们需要用父组件来对子组件进行加工
  • 先给子组件的模板的 <slot></slot> 自定义一个属性 <slot :shuxing="item"></slot>
  • 然后在父组件的模板标签里面使用 <template slot-scope='slotProps'></template> 获取子组件的数据
    slotProps 自定义的名字,是个对象,包含子组件里面的所有 slot 的属性
<body>
    <div id="box">
        <aaa :qwer='list'>
            <template slot-scope='slotProps'>
                <strong v-if='slotProps.shuxing.id==2'>slotProps.shuxing.name</strong>
                <span v-else>slotProps.shuxing.name</span>
            </template>
        </aaa>
    </div> 

    <script src="../vue.js"></script>
    <script>
        Vue.component('aaa', 
            props: ['qwer'],
            template: `
            <div>
                <div>
                    <li :key="item.id" v-for="item in qwer">
                        <slot :shuxing="item"></slot>
                    </li>
                </div>
            </div>
            `
        )

        const vm = new Vue(
            el: '#box',
            data: 
                list: [
                    id: 1,
                    name: '远近渔'
                , 
                    id: 2,
                    name: '渔渔渔'
                , 
                    id: 3,
                    name: '渔渔子'
                ]
            
        )
    </script>
</body>

以上是关于Vue 组件 + 组件之间传值 + 组件插槽的主要内容,如果未能解决你的问题,请参考以下文章

VUE_03 组件化思想全局|局部注册组件之间传值(父传子子传父兄弟传兄弟)匿名|具名|作用域插槽

Vue组件传值及插槽

Vue组件传值及插槽

Vue组件传值及插槽

vue中组件通信的方式

vue中组件通信的方式