美文网首页封装组件
通过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