Vue组件传值及插槽

Posted 遥岑.

tags:

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

目录

组件传值

父组件向子组件传值

组件内部通过props接收传递过来的值,父组件通过属性将值传递给子组件。

  • 静态绑定
<body>
    <div id="app">
        <test title="来自父组件的值"></test>
    </div>
</body>
<script>
    Vue.component('test', 
        props: ['title'],
        data: function() 
            return 
                msg: '子组件的数据'
            
        ,
        template: '<div>title + "-" + msg</div>'
    )
    var vm = new Vue(
        el:'#app',
        data: 
            pmsg: '内容'
        
    )
</script>
  • 动态绑定
<test :title="title"></test>

props属性名规则:

  • 在props中使用驼峰形式,模板中需要使用短横线的形式
Vue.component('test', 
    //驼峰
    props: ['titleName'],
    data: function() 
        return 
             msg: '子组件的数据'
        
    ,
    template: '<div>titleName + "-" + msg</div>'
)
//短横线形式
<div id="app">
    <test title-name="来自父组件的值"></test>
</div>
  • 字符串形式的模板中没有这个规则
Vue.component('test', 
        props: ['titleName'],
        data: function() 
            return 
                msg: '子组件的数据'
            
        ,
        //在字符串中可以使用驼峰形式myName
        template: '<div>titleName + "-" + msg<test1 myName="yc"></test1></div>'
    )
    Vue.component('test1', 
        props: ['myName'],
        template: '<div>myName</div>'
    )

props属性值类型:

<body>
    <div id="app">
        <test :pstr="pstr" :pnum="12" :pboo="pboo" :parr="parr" :pobj="pobj"></test>
    </div>
</body>
<script>
    Vue.component('test', 
        props: ['pstr','pnum','pboo','parr','pobj'],
        template: `
        <div>
            <div>pstr</div>
            <div>pnum</div>
            <div>pboo</div>
            <ul>
                <li :key="index" v-for='(item,index) in parr'>item</li>
            </ul>
            <div>pobj.name</div>
        </div>
        `
    )
    var vm = new Vue(
        el:'#app',
        data: 
            pstr: '内容',
            pboo:true,
            parr:[1,2,34],
            pobj: 
                name: 'yc',
                age: 24
            
        
    )
</script>

子组件向父组件传值

props传递数据原则,单向数据流

  • 子组件通过自定义事件向父组件传递信息
//触发方法$emit enlarge-text自定义事件
<button v-on:click='$emit("enlarge-text")'>扩大字体</button>
  • 父组件监听子组件的事件
<menu-item v-on:enlarge-text='fontSize += 0.1'></menu-item>
<body>
    <div id="app">
        <div :style="fontSize: fontSize + 'px'">msg</div>
        <test @enlarge-text="onLarge"></test>
    </div>
</body>
<script>
    Vue.component('test', 
        template: `
          <div>
            <button @click='$emit("enlarge-text")'>扩大字号</button>
          </div>
        `
    )
    var vm = new Vue(
        el:'#app',
        data: 
            msg: '遥岑',
            fontSize: 10
        ,
        methods: 
            onLarge:function() 
                this.fontSize += 5
            
        

    )
</script>

传参:

  • 子组件通过自定义事件向父组件传递信息
//第二个参数传参
<button v-on:click='$emit("enlarge-text",0.1)'>扩大字体</button>
  • 父组件监听子组件的事件
//$event接收值
//如果绑定的函数 可以将$event作为参数传递给函数
<menu-item v-on:enlarge-text='fontSize += $event'></menu-item>
<body>
    <div id="app">
        <div :style="fontSize: fontSize + 'px'">msg</div>
        <test @enlarge-text="onLarge($event)"></test>
    </div>
</body>
<script>
    Vue.component('test', 
        template: `
          <div>
            <button @click='$emit("enlarge-text",5)'>扩大字号</button>
          </div>
        `
    )
    var vm = new Vue(
        el:'#app',
        data: 
            msg: '遥岑',
            fontSize: 10
        ,
        methods: 
            onLarge:function(val) 
                this.fontSize += val
            
        

    )
</script>

兄弟组件间传值

  • 单独事件中心管理组件间的通信
//扮演事件中心角色
var eventHub = new Vue()
  • 监听事件与销毁事件
//第一个参数:自定义事件名称 第二个参数:自定义函数
eventHub.$on('add-todo', addTodo)
eventHub.$off('add-todo')
  • 触发事件
eventHub.$emit('add-todo', id)
<body>
    <div id="app">
        <div>父组件</div>
        <button @click="destory">销毁</button>
        <test></test>
        <test1></test1>
    </div>
</body>
<script>
    //事件中心
    var hub = new Vue()
    
    Vue.component('test',
        data: function() 
            return 
                num:0
            
        ,
        template: `
          <div>
            <div>Tom:num</div>  
            <button @click="handle">点击</button>
          </div>
        `,
        methods: 
            handle: function() 
                hub.$emit('jerry-event',2)
            
        ,
        mounted: function() 
            //监听事件
            hub.$on('tom-event',(val)=> 
                this.num += val
            )
        
    )
    Vue.component('test1',
        data: function() 
            return 
                num:0
            
        ,
        template: `
          <div>
            <div>Jerry:num</div>  
            <button @click='handle'>点击</button>
          </div>
        `,
        methods: 
            handle: function() 
                hub.$emit('tom-event',1)
            
        ,
        mounted: function() 
            //监听事件
            hub.$on('jerry-event',(val)=> 
                this.num += val
            )
        
    )
    var vm = new Vue(
        el:'#app',
        methods: 
            destory:function() 
                hub.$off('tom-event')
                hub.$off('jerry-event')
            
        
    )
</script>

组件插槽

父组件向子组件传递内容

<body>
    <div id="app">
        <alert-box>有bug</alert-box>
        <alert-box>有问题</alert-box>
        <alert-box></alert-box>
    </div>
</body>
<script>
    Vue.component('alert-box', 
        template: `
          <div>
            <strong>Error:</strong>
            <slot>默认内容</slot>
          </div>
        `
    )
    var vm = new Vue(
        el:'#app',
        data: 

        
    )
</script>

具名插槽

根据名称进行匹配,没有匹配到的放在默认插槽中。

<body>
    <div id="app">
        <alert-box>
            <p slot="header">标题</p>
            <p>内容</p>
            <p slot="footer">底部</p>
        </alert-box>
    </div>
</body>
<script>
    Vue.component('alert-box', 
        template: `
          <div>
            <header>
                <slot name="header"></slot>
            </header>
            <main>
                <slot></slot>
            </main>
            <footer>
                <slot name="footer"></slot>
            </footer>
          </div>
        `
    )
    var vm = new Vue(
        el:'#app',
        data: 

        
    )
</script>

作用域插槽

父组件对子组件进行加工处理,在父组件中获得子组件的数据对它进行加工。

<body>
    <div id="app">
        <fruit-box :list="list">
            <!-- slotProps接收子组件自定义属性传过来的值 -->
            <template slot-scope="slotProps">
                <strong v-if="slotProps.info.id === 1" class="current">slotProps.info.name</strong>
                <span v-else>slotProps.info.name</span>
            </template>
        </fruit-box>
    </div>
</body>
<script>
    Vue.component('fruit-box', 
        props: ['list'],
        //info子组件自定义属性
        template: `
          <div>
            <li :key="item.id" v-for="item in list">
                <slot :info='item'>item.name</slot>    
            </li>
          </div>
        `
    )
    var vm = new Vue(
        el:'#app',
        data: 
            list: [
                id:1,
                name: 'apple'
            ,
                id: 2,
                name: 'orange'
            ,
                id: 3,
                name: 'banana'
            ]
        
    )
</script>

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

Vue组件传值及插槽

Vue组件传值及页面缓存问题

VUe.js 父组件向子组件中传值及方法

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

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

vue 插槽slot向父组件传值