ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2021-06-05 20:03:29  阅读:215  来源: 互联网

标签:Vue hub 插槽 传值 template 组件 模板


文章目录

组件

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


一、组件注册


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,hub,插槽,传值,template,组件,模板
来源: https://blog.csdn.net/qq_53283188/article/details/117418551

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有