美文网首页封装组件
通过vue封装弹窗组件/vue封装组件的方式选择依据

通过vue封装弹窗组件/vue封装组件的方式选择依据

作者: Raral | 来源:发表于2021-03-18 09:43 被阅读0次

通过vue封装弹窗组件

大部分vue对效果的封装,有3个方式:

  1. 普通公共组件封装: 涉及东西,父子组件之间的传值和通过 v-modal 指令监听父子间的数据
  2. 通过渲染函数封装组件:render函数运用
  3. 通过混合封装组件:mixins,extends使用

共性:
vue的插槽使用:

1. 普通插槽:父组件向子组件 传dom结构的

2. 具名插槽: 父组件向子组件 根据插槽不同名称,传dom结构的

3. 作用域插槽: 在书写插槽内容时可以获取到插槽作用域的值
        概括就是v-slot :后边是插槽名称,=后边是组件内部绑定作用域值的映射。

4. 结构插槽: 就是 使用 es6 解构赋值语法  获取域中的属性

1. popup通用组件封装

<template>
    <div class="popup"  >
        <transition name="maskfade">
            <div class="mask"  @click="$emit('on-visible-change', !show)" v-if="show"></div>
        </transition>
        <transition :name="position + 'Slide'">
            <div class="view" :class="position" v-if="show">
                <!-- 比如这是头部插槽,可以控制 关闭操作的 样式和逻辑 -->
                <slot name="header"/>
                 <!-- 比如这是内容插槽,可以放入自己的 交互组件 比如  下拉框,联动的。。等等-->
                <slot name="content"/>
                <!--具名插槽 -->
                <slot name= "bottom" :list="list" />
            </div>
        </transition>
    </div>
</template>
<script>
export default {
    props: {
        show: Boolean,
        position: String
    },
     model: {
        prop: 'show',
        event: 'on-visible-change',
    },
    data() {
        return {
            list: [1,2,3,4]//为了模拟 作用域插槽提供数据
        }
    },
    computed: {
        classObject: function() {
            // return  this.
        }
    }
}
</script>
<style>
    .mask {
        position: absolute;
        top: 0;
        left: 0;
        bottom: 0;
        right: 0;
        z-index: 1;
        background-color: #000;
    }

    .view {
        background-color: #fff;
        position: absolute;
        z-index: 1000;

    }
    .bottom {
        width: 100%;

        height: 12.5rem;
        left: 0;
        bottom: 0;
    }
    .top {
        width: 100%;
        height: 12.5rem;
        left: 0;
        top: 0;
    }
    .left {
        width: 50%;
        height: 100vh;
        left: 0;
        bottom: 0;
    }
      .right {
        width: 50%;
        height: 100vh;
        right: 0;
        bottom: 0;
    }
    /* vue中的过渡动画定义 */
    /* 遮罩层过渡 */
     .maskfade-enter,.maskfade-leave-to {
        opacity: 0;
    }
    .maskfade-enter-active,.maskfade-leave-active {
        transition: all .3s linear;
    } 
     .maskfade-enter-to, .maskfade-leave {
        opacity: 1;
    }
    /* 内容层过渡 */
    /* bottom */
    .bottomSlide-enter,.bottomSlide-leave-to {
          transform: translateY(100%);
    }
    .bottomSlide-enter-active,     .bottomSlide-leave-active {
        transition: all .3s linear;
     }
     .bottomSlide-enter-to,   .bottomSlide-leave{
         transform: translateY(0%);
    }

     /* top */
    .topSlide-enter,.topSlide-leave-to {
          transform: translateY(-100%);
    }
    .topSlide-enter-active,     .topSlide-leave-active {
        transition: all .3s linear;
     }
     .topSlide-enter-to,   .topSlide-leave{
         transform: translateY(0%);
    }

    /* left */
     .leftSlide-enter,.leftSlide-leave-to {
          transform: translateX(-100%);
    }
    .leftSlide-enter-active,     .leftSlide-leave-active {
        transition: all .3s linear;
     }
     .leftSlide-enter-to,   .leftSlide-leave{
         transform: translateX(0%);
    }

    /* right */
        .rightSlide-enter,.rightSlide-leave-to {
          transform: translateX(100%);
    }
    .rightSlide-enter-active,     .rightSlide-leave-active {
        transition: all .3s linear;
     }
     .rightSlide-enter-to,   .rightSlide-leave{
         transform: translateX(0%);
    }
   

</style>

父组件调用

<template>
    <div class="mixins">
        <button @click="showClick">test</button>

       <Popup v-model="show" position="top">
           <template v-slot:header>
                <div>
                    我是头部的slot
                </div>  
           </template>
           <template v-slot:content>
                <div>
                    我是内容的slot
                </div>  
           </template>
            <template v-slot:bottom="myList">
                <div v-for="(item, index) in myList.list" :key="index">
                    我是 具名插槽 {{index}}
                </div>  
           </template>
       </Popup>
    </div>
</template>

<script>
    import Popup from "@/components/popup/Popup.vue"
    export default {
        components: {
            Popup
        },
        data() {
            return {
                show: false
            }
        },
        methods: {
            showClick() {
                this.show = !this.show;
            }
        },
    }
</script>

效果:


1616033366(1).png

总结:

  1. 不论写什么组件,首先你必须可以通过原生js 亲自的去操作dom, 就想之前文章弹窗封装(一)/咋样动态节点实现过渡动画;这篇文章主要介绍实现原理。

  2. 然后通过 常见的 js和jquery 封装手段,去封装弹窗组件;弹窗封装(二)/深入体验闭包,this指向

只要有这样通过这2步才能深刻 体验 js的 强大的魅力;深入理解:上下文(this指向),作用域, 通过方法之间调用会转让控制权的目的是什么,闭包使用优点, 模块化区分,面向对象和面向过程

  1. vue封装时候,让我们比原生封装简化很多里面的细节,就是最核心的数据驱动视图 代替 操作dom,还有属性和方法之间的调用也简化很多,因为所有的方法都挂在当前实例对象上,通过es6语法不要考虑 上下文问题,简化我们的封装思想

2. 通过过 混入 封装弹窗对象(里面有坑,解决这种模式封装可以控制 dom节点的 插入动画实现)

解决原理: 动态的dom节点添加过渡动画呢一定要注意js单线程执行同步任务,但是我们的过渡动画是有时间段的,也就是两种状态的。在js单线程执行,尤其在同步任务中,所有的执行逻辑都是同步进行,也就是说 创建遮罩层和添加show类名是同时的,所以导致m没有效果我们要把添加过渡最后类名,添加到异步队列中执行。setTimeout()实现宏观任务队列

promise异步队列

敬请期待

3. 通过过 渲染 封装弹窗对象(里面有坑,咋样灵活高效控制一个节点的样式变化)

敬请期待

万水千山总是情,点波关注行不行(●'◡'●)!!!

相关文章

网友评论

    本文标题:通过vue封装弹窗组件/vue封装组件的方式选择依据

    本文链接:https://www.haomeiwen.com/subject/nhlucltx.html