vue基础扩展——插槽

1.1 插槽

  • 组件的最大特性就是复用性,而用好插槽能大大提高组件的可复用能力

  • 在Vue中插槽是很重要的存在,通过插槽,我们可以把 父组件中指定的DOM 作用到 子组件的任意位置,后面我们做项目用到的组件库比如element-ui,vant-ui都频繁用到的插槽,Vue的插槽主要有匿名插槽,具名插槽,作用域插槽三种,下面我们分别来认识一下他们。

插槽插槽实质是对子组件的扩展,通过<slot>插槽-----向组件内部“指定位置” 放置内容。

插槽设置的地方:一定是在子组件中。子组件可以在任意位置添加slot。

父组件提供插槽内容。

1.1.1 匿名插槽

故名思义就是没有名字的插槽,只需要在子组件中使用<slot></slot>引入即可

我们来看一下案例,如何引入匿名插槽的:

<div id="app">
        <!-- 组件复用的时候,父组件向子组件的插槽中放置内容 -->
        <alert-box>小马过河</alert-box>
        <alert-box>这里有一个bug</alert-box>
    </div>
    <template id="alert-box">
        <div>
            <h1>我是子组件alert-box</h1>
            <strong>ERROR:</strong>
            <h1 style="color:red">
            <slot>
           
                默认内容
           
            </slot>
            </h1>
        </div>
    </template>
<script src="./js/vue.js"></script>
    <script>
        Vue.component('alert-box',{
            template:`#alert-box`,
            data(){
                return{

                }
            }
        })
        var vm=new Vue({
            //模板选择器
            el:'#app',
            //数据中心
            data(){

                return{
                   
                }

            },
            methods:{
               

            }
        })
    </script>

预览:

 

1.1.2 具名插槽

  • 具有名字的插槽就是具名插槽

  • 使用 <slot> 中的 "name" 属性绑定元素,name就是插槽的名字

  .title{
            font-size: 30px;
            color: blue;
        }
        .price{
            font-size: 26px;
            color: green;
        }
        .descriptions{
            font-size: 22px;
            color: purple;
        }
<div id="app">
        <parent></parent>
    </div>
    <template id="child">
        <div>
            <h1>我是子组件</h1>
            <div class="title">
                <slot name="t"></slot>
            </div>
            <div class="price">
                <slot name="p"></slot>
            </div>
            <div class="descriptions">
                <slot name="des"></slot>
            </div>
        </div>
    </template>
    <template id="parent">
        <div>
            <h1>我是父组件</h1>
            <child>
                <h1 slot="t">{{title}}</h1>
                <h2 slot="p">{{price}}</h2>
                <p slot="des">{{descriptions}}</p>
            </child>
        </div>
    </template>
<script src="./js/vue.js"></script>
    <script>
        //子组件
        var child={
            template:`#child`,
            data(){
                return{
                   
                }
            }
        }
        //父组件
        var parent={
            template:`#parent`,
            data(){
                return{
                    title:'活着 (余华著长篇小说)',
                    price:'56.9',
                    descriptions:'讲述了在大时代背景下,随着内战、三反五反,大跃进,文化大革命等社会变革,徐福贵的人生和家庭不断经受着苦难,到了最后所有亲人都先后离他而去,仅剩下年老的他和一头老牛相依为命。'
                }
            },
            components: {
                child
            }
        }
        //根组件
        var vm=new Vue({
            //模板选择器
            el:'#app',
            //数据中心
            data(){

                return{
                   
                }

            },
            methods:{
               

            },
            components:{
                parent
            }
        })
    </script>

预览:

 

1.1.3 作用域插槽

作用域插槽(带数据的插槽):绑定数据的插槽slot插槽scope作用域

作用域插槽要求,在slot上面绑定数据。

  • 可以让父组件对子组件的内容进行加工处理。

  • 既可以复用子组件的slot,又可以使slot内容不一致。

    • 父组件中使用slot-scope绑定一个属性

    • 子组件中给<slot>标签绑定一个自定义属性,可以传递子组件的内容

    • 父组件通过slot-scope接受子组件传递过来的值即可

.current{
        font-size: 30px;
        color: red;
    }
    .active{
        font-size: 45px;
        color: green;
    }
    .yty{
        font-size: 39px;
        color: pink;
    }
 <div id="app">
        <fruit-list :list="list">
             <!--2.父组件中使用`slot-scope`绑定一个属性
               scopes在这里只是临时变量 
            -->
            <template slot-scope="scopes">
                <strong v-if="scopes.info.id==3" class="current">
                    {{scopes.info.name}}
                </strong>
                <span>{{scopes.info.name}}</span>
            </template>
        </fruit-list>

        <fruit-list :list="list">
            <!--2.父组件中使用`slot-scope`绑定一个属性
              scopes在这里只是临时变量 
           -->
           <template slot-scope="scopes">
               <strong v-if="scopes.info.id==2" class="active">
                   {{scopes.info.name}}
               </strong>
               <span>{{scopes.info.name}}</span>
           </template>
       </fruit-list>
    </div>
    <template id="fruit-list">
        <div>
            <ul>
                <li v-for="item in list" :key="item.id">
                    <!-- 作用域插槽使用的第一步:在子组件的slot上定义一个属性:info -->
                    <!-- 如果有数据传递过来,数据会被渲染到这个插槽上 -->
                    <!-- :绑定数据的插槽,这个就叫做作用域插槽 -->
                    <slot :info="item">默认内容</slot>
                </li>
            </ul>
        </div>
    </template>
<script src="./js/vue.js"></script>
    <script>
        //子组件
        Vue.component('fruit-list',{
            props:['list'],
            template:`#fruit-list`,
            data(){
                return{

                }
            }
        })

        //父组件
        var vm=new Vue({
            //模板选择器
            el:'#app',
            //数据中心
            data(){

                return{
                    list:[
                    {
                        id: 1,
                        name: 'apple'
                    },
                    {
                        id: 2,
                        name: 'orange'
                    },
                    {
                        id: 3,
                        name: 'banana'
                    }
                ]
                }

            },
            methods:{
               

            }
        })
    </script>

预览:

 

分析:

可以让 父组件 对 子组件的内容 进行加工处理

  • 父组件中使用slot-scope绑定一个属性

  • 子组件中给<slot>标签绑定一个自定义属性,可以传递子组件的内容

  • 父组件通过slot-scope接受子组件传递过来的值即可

 

1.2 插槽综合案例讲解-分页组件

分页组件

.sync修饰符,可以对 单个 prop进行双向绑定

.sync修饰符可以像v-model一样实现类似双向绑定的场景用法 。

我们在父组件中,使用 :page.sync="uPage"  实现的作用是:双向数据绑定,即:子传父,子组件将数据传递给父组件。父组件同时,在这里可以将数据传递给子组件。

父组件设置如下:

<w-pagination :total="list.length" :page.sync="uPage" :prepage="prePage"></w-pagination>

子组件设置如下:

我们用下面这种形式传参

$emit('update:xx', 参数)

例如:

this.$emit('update:page',p);

因为如果不用这种方法子组件内的props参数将无法成功修改,而是没有反应,所以Vue官方建议我们在子组件触发传递父组件事件中也同样用update:xx这种写法。

 .current{
        font-size: 30px;
        color: red;
    }
    .active{
        font-size: 45px;
        color: green;
    }
    .yty{
        font-size: 39px;
        color: pink;
    }
 <div id="app">
        <fruit-list :list="list">
             <!--2.父组件中使用`slot-scope`绑定一个属性
               scopes在这里只是临时变量 
            -->
            <template slot-scope="scopes">
                <strong v-if="scopes.info.id==3" class="current">
                    {{scopes.info.name}}
                </strong>
                <span>{{scopes.info.name}}</span>
            </template>
        </fruit-list>

        <fruit-list :list="list">
            <!--2.父组件中使用`slot-scope`绑定一个属性
              scopes在这里只是临时变量 
           -->
           <template slot-scope="scopes">
               <strong v-if="scopes.info.id==2" class="active">
                   {{scopes.info.name}}
               </strong>
               <span>{{scopes.info.name}}</span>
           </template>
       </fruit-list>
    </div>
    <template id="fruit-list">
        <div>
            <ul>
                <li v-for="item in list" :key="item.id">
                    <!-- 作用域插槽使用的第一步:在子组件的slot上定义一个属性:info -->
                    <!-- 如果有数据传递过来,数据会被渲染到这个插槽上 -->
                    <!-- :绑定数据的插槽,这个就叫做作用域插槽 -->
                    <slot :info="item">默认内容</slot>
                </li>
            </ul>
        </div>
    </template>
 <script src="./js/vue.js"></script>
    <script>
        //子组件
        Vue.component('fruit-list',{
            props:['list'],
            template:`#fruit-list`,
            data(){
                return{

                }
            }
        })

        //父组件
        var vm=new Vue({
            //模板选择器
            el:'#app',
            //数据中心
            data(){

                return{
                    list:[
                    {
                        id: 1,
                        name: 'apple'
                    },
                    {
                        id: 2,
                        name: 'orange'
                    },
                    {
                        id: 3,
                        name: 'banana'
                    }
                ]
                }

            },
            methods:{
               

            }
        })
    </script>

预览:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
组件是 Vue.js 中最重要的概念之一。组件可以让我们将 UI 拆分为独立、可复用的部件,使得代码更加清晰、易于维护。在 Vue.js 中,组件可以分为全局组件和局部组件,其中全局组件可在任何地方使用,而局部组件只能在其父组件中使用。 定义组件时,需要使用 Vue.component() 方法,该方法需要传入两个参数:组件名称和组件配置对象。组件名称应该采用 kebab-case(短横线分隔命名)格式,以便在 HTML 中使用。 示例代码如下: ```javascript // 定义一个名为 button-counter 的新组件 Vue.component('button-counter', { data: function () { return { count: 0 } }, template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>' }) ``` 在上述代码中,我们定义了一个名为 button-counter 的组件,该组件包含一个计数器,每次点击按钮计数器加一。 在 HTML 中使用组件时,需要使用组件名称作为自定义标签来调用组件。示例代码如下: ```html <div id="app"> <button-counter></button-counter> </div> ``` 在上述代码中,我们调用了 button-counter 组件,并将其渲染到了 id 为 app 的 div 元素中。 除了组件的 data 和 template 属性外,还可以使用 props 属性来传递组件之间的数据。使用 props 时,需要在组件的配置对象中定义 props 属性,并在 HTML 中使用 v-bind 指令来传递数据。 示例代码如下: ```javascript // 定义一个名为 todo-item 的新组件 Vue.component('todo-item', { props: ['todo'], template: '<li>{{ todo.text }}</li>' }) // 创建一个 Vue 实例 var app = new Vue({ el: '#app', data: { groceryList: [ { id: 0, text: '蔬菜' }, { id: 1, text: '水果' }, { id: 2, text: '奶酪' } ] } }) ``` 在上述代码中,我们定义了一个名为 todo-item 的组件,并使用 props 属性定义了一个名为 todo 的 prop。在 HTML 中,我们使用 v-bind 指令将 groceryList 数组中的每个对象传递给了 todo-item 组件。示例代码如下: ```html <div id="app"> <ul> <todo-item v-for="item in groceryList" v-bind:todo="item" v-bind:key="item.id"></todo-item> </ul> </div> ``` 在上述代码中,我们使用 v-for 指令遍历 groceryList 数组,并使用 v-bind 指令将数组中的每个对象传递给了 todo-item 组件。注意,我们还需要使用 v-bind:key 指令来为每个列表项指定一个唯一的 key 值。 插槽Vue.js 中另一个重要的概念。插槽可以让父组件在子组件中插入任意的 HTML 内容,使得组件更加灵活、可复用。 在子组件中,使用 <slot> 标签来定义插槽。在父组件中,使用子组件的自定义标签来调用组件,并在标签内部插入 HTML 内容。示例代码如下: ```javascript // 定义一个名为 alert-box 的新组件 Vue.component('alert-box', { template: ` <div class="alert-box"> <strong>Error!</strong> <slot></slot> </div> ` }) // 创建一个 Vue 实例 var app = new Vue({ el: '#app' }) ``` 在上述代码中,我们定义了一个名为 alert-box 的组件,并在组件中定义了一个插槽。在 HTML 中,我们调用了 alert-box 组件,并在标签内部插入了一些 HTML 内容。示例代码如下: ```html <div id="app"> <alert-box> <p>Something bad happened.</p> </alert-box> </div> ``` 在上述代码中,我们调用了 alert-box 组件,并在标签内部插入了一些 HTML 内容。该 HTML 内容会被插入到 alert-box 组件的插槽中。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值