vue slot的使用(transform动画)

slot的说明就看vue的官方文档  但是有点模糊

理解:

是对组件的扩展,通过slot插槽向组件内部指定位置传递内容,通过slot可以父子传参;
 

解决什么问题:
正常情况下,<Child><span style=”color:red;”>hello world</span></Child>在组件标签Child中的span标签会被组件模板template内容替换掉,当想让组件标签Child中内容传递给组件时需要使用slot插槽;

 

通俗的讲:

是“占坑”,在组件模板中占好了位置,当使用该组件标签时候,组件标签里面的内容就会自动填坑(替换组件模板中<slot>位置),当插槽也就是坑<slot name=”mySlot”>有命名时,组件标签中使用属性slot=”mySlot”的元素就会替换该对应位置内容;


例如下面使用的例子

第一次使用slot  练习的一个小例子有问题大家指正

 

最先编码的时候没有做到上下收缩,只能是列表式的,如下图

 

 

代码:

        <p class="title" style="text-align:left;font-weight:bold">特有属性</p>
        <div class="param-gap">
            <label class="left" for="">圆角&nbsp;:</label>
            <div class="right">
                <input class="data-value" :keep-selected="true" placeholder="请输入(上,右,下,左)" @input="updateData"/>
            </div>
        </div>

但是后面实际需要的效果是可以进行上下伸缩的,如下图

所以这样就得每一个 p元素上写成一个组件,组件里面写点击弹出下面的div,这种方式肯定可以实现,但是这里我就使用了插槽,讲需要下拉的内容通过一个参数传过去,放到对应的slot坑中

首先:

用一个组件讲下方的元素进行包裹起来  collapse-item  组件里面的内容就可以当做一个插槽

<collapse-item title="点击我进行收缩的" :isShow="true">
    <div class="param-gap">
        <label class="left" for="" title="线型">线型:</label>
        <div class="right">
            <select class="data-value"  name="" id="">
                <option value="1">线型一</option>
                <option value="2">线型二</option>
                <option value="3">线型三</option>
                <option value="4">线型四</option>
                <option value="5">线型五</option>
            </select>
        </div>
    </div>
</collapse-item>

CollapseItem.vue进行正常引入

import CollapseItem from './CollapseItem'

CollapseItem.vue里面的代码

<template>
    <div style="width:100%" class="testbox" :class="{'collapsed': !isActive }">
        <p class="click" @click="handleHeaderClick">
            <span>{{title}}</span>
            <i class="arrow icon iconfont icon_down"></i>
        </p>
        <div v-show="isActive">
            <slot></slot>
        </div>
    </div>
</template>

slot里面的最终解析出来的html就是上面collapse-item标签里面包裹的元素

 效果图(点击可以上下收缩,图标切换)

 

 

 

最后还使用了一个动画效果,讲小图标进行旋转

注意:

下面的css  如果直接切换class  为 collapsed 的时候,会导致点击的时候图标会有动画的效果,但是再点击一下会瞬间回到初始位置,不会出现动画

    .collapsed .arrow {
        transition: transform 0.18s ease 0s;
        transform: rotate(-180deg) scale(1, 0.9);
    }

 

解决办法,就是让初始的位置就进行旋转180度,把图片icon原本是down换成up,这样初始的时候看起来就和原来一样,然后再在点击的时候切换 collapsed   具体看代码

CollapseItem.vue

<template>
    <div style="width:100%" class="testbox" :class="{'collapsed': !isActive }">
        <p class="click" @click="handleHeaderClick">
            <span>{{title}}</span>
            <i class="arrow icon iconfont icon_up"></i>
        </p>
        <div v-show="isActive">
            <slot></slot>
        </div>
    </div>
</template>
<script>

export default {
    name: 'CollapseItem',
    props:{
        title:String,//指定title为string类型的
        isShow: {
            type: Boolean,
            default() {
                return true
            }
        }
    },
    data(){
      return {
        isActive : true
      }
    },
    methods: {
        handleHeaderClick(){
            this.isActive = !this.isActive
        }
    }
}
</script>
<style lang="scss" scoped >


    .click {
        display: flex;
        justify-content: space-between;
    }
    .arrow{
        transition: transform 0.18s ease 0s;
        transform: rotate(-180deg) scale(1, 0.9);
    }
    .collapsed .arrow {
        
        transform: rotate(0deg) scale(1, 0.9);
    }





</style>

hutest

<template>
    <div class="one">
        <div class="box">
            <p class="box-head">这是标题</p>
            <div class="box-content">
            <collapse-item title="点击我进行收缩的" :isShow="true">
                <div class="param-gap">
                    <label class="left" for="" title="线型">线型:</label>
                    <div class="right">
                        <select class="data-value"  name="" id="">
                            <option value="1">线型一</option>
                            <option value="2">线型二</option>
                            <option value="3">线型三</option>
                            <option value="4">线型四</option>
                            <option value="5">线型五</option>
                        </select>
                    </div>
                </div>
            </collapse-item>
            </div>
        </div>
    </div>
</template>
<script>
import CollapseItem from './CollapseItem'
export default {
    name:'hutest',
    components: { CollapseItem },
    data() {
        return {

        }
    },
    methods: {

    }
}
</script>
<style lang="scss" scoped >
    .param-pannel input,.param-pannel select{
        border:1px solid #ddd;
        width:100%
    }
    .param-pannel input[type=color]{
        padding:0
    }
    .one{
        position: fixed;
        width:100%;
        height:100%;
        display: flex;
        justify-content: center;
        align-items: center;
    }
    .box{
        width:400px;
        height: 400px;
        border: 1px solid #ddd;
        display: flex;
        flex-direction: column;
        .box-head{
            flex: 0 0 auto;
            background-color: pink;
        }
        .box-content{
            flex:1 1 0px;
            background-color: #eee;
            display: flex;
        }
    }
</style>
View Code

注意图标使用的是element ui 所以需要引入,,如果不想引入,也可以直接写字体,或者键盘的尖括号,或者小于号旋转一下,然后将选装的样式进行调一下也可以达到类似的效果

尖括号举例

    .collapsed .arrow {
        transform: translateX(-25%) translateY(25%) rotate(0deg) scale(1, 0.9);
    }

 

效果同上图

 

 

上面所使用的插槽是默认插槽,如果没有给插槽命名,那么默认就是拿组件中的第一个子元素进行填充

 

 

需求二:如果如下图,在特有属性中需要添加一个文本内容,这个时候为了方便就需要再添加了一个插槽

 

 

代码:

Hutest.vue

<template>
    <div class="one">
        <div class="box">
            <p class="box-head">这是标题</p>
            <div class="box-content">
            <collapse-item title="样式" :isShow="true">
                <div class="param-gap">
                    <label class="left" for="" title="线型">线型:</label>
                    <div class="right">
                        <select class="data-value"  name="" id="">
                            <option value="1">线型一</option>
                            <option value="2">线型二</option>
                            <option value="3">线型三</option>
                            <option value="4">线型四</option>
                            <option value="5">线型五</option>
                        </select>
                    </div>
                </div>
            </collapse-item>
            <collapse-item title="特有属性" :isShow="true">

                <div class="param-gap" slot="before">
                    <label for="" class="left">文本内容&nbsp;:</label>
                    <div class="right">
                        <input class="data-value" placeholder="我是特有属性自己独有的 "/>
                    </div>
                </div>

                <div class="param-gap">
                    <label class="left" for=""  title="线型">线型:</label>
                    <div class="right">
                        <select class="data-value"  name="" id="">
                            <option value="1">线型一</option>
                            <option value="2">线型二</option>
                            <option value="3">线型三</option>
                            <option value="4">线型四</option>
                            <option value="5">线型五</option>
                        </select>
                    </div>
                </div>
            </collapse-item>
            </div>
        </div>
    </div>
</template>
<script>
import CollapseItem from './CollapseItem'
export default {
    name:'hutest',
    components: { CollapseItem },
    data() {
        return {

        }
    },
    methods: {

    }
}
</script>
<style lang="scss" scoped >
    .param-pannel input,.param-pannel select{
        border:1px solid #ddd;
        width:100%
    }
    .param-pannel input[type=color]{
        padding:0
    }
    .one{
        position: fixed;
        width:100%;
        height:100%;
        display: flex;
        justify-content: center;
        align-items: center;
    }
    .box{
        width:400px;
        height: 400px;
        border: 1px solid #ddd;
        display: flex;
        flex-direction: column;
        .box-head{
            flex: 0 0 auto;
            background-color: pink;
        }
        .box-content{
            flex:1 1 0px;
            background-color: #eee;
            display: flex;
            flex-direction: column
        }
    }
</style>
View Code

CollapseItem.vue

<template>
    <div style="width:100%" class="testbox" :class="{'collapsed': !isActive }">
        <p class="click" @click="handleHeaderClick">
            <span >{{title}}</span>
            <i class="arrow icon iconfont icon_up"></i>
        </p>
        <div v-show="isActive">
            <slot name="before"></slot>
            <slot></slot>
        </div>
    </div>
</template>
<script>

export default {
    name: 'CollapseItem',
    props:{
        title:String,//指定title为string类型的
        isShow: {
            type: Boolean,
            default() {
                return true
            }
        }
    },
    data(){
      return {
        isActive : true
      }
    },
    methods: {
        handleHeaderClick(){
            this.isActive = !this.isActive
        }
    }
}
</script>
<style lang="scss" scoped >


    .click {
        display: flex;
        justify-content: space-between;
    }
    .arrow{
        transition: transform 0.18s ease 0s;
        transform: rotate(-180deg) scale(1, 0.9);
    }
    .collapsed .arrow {
        
        transform: rotate(0deg) scale(1, 0.9);
    }





</style>
View Code

 

posted @ 2019-11-07 20:37  人在路途  阅读(699)  评论(0编辑  收藏  举报