实战小技巧: 基于Vue的混入-实现面板打开与关闭

734 阅读2分钟

1.gif

作者:老九—技术大黍

社交:知乎

公众号:老九学堂(新人有惊喜)

特别声明:原创不易,未经授权不得转载或抄袭,如需转载可联系笔者授权

前言

Vue.js在国内流行得不要不要的,我们今天也来凑凑热闹,给大家介绍一个实战小技巧。我们现给出实战核心代码,希望能够帮助到大家。

实战代码

自定义面板组件

/**
 * 功能:定义一个基本面板组件(具有关闭按钮)
 */

let BasePanel1 = {
    props: ['visible'],
    data() {
        return {
            isFirstShow: true, //是否为首次渲染
            isClose: false,     //背景选择面板是否关闭(用于播放关闭动画)
        }
    },
    watch: {
        //监听visible变化(将首次渲染设定为false)
        visible: function (newVal,oldVal) {
            //首次打开
            if(this.isFirstShow) {
                this.firstShow();
                this.isFirstShow = false;
            }
            //面板显示与隐藏
            if(newVal) {
                this.panelShow();
            }else {
                this.panelClose();
            }
        }
    },
    methods: {
        //面板首次打开时要做的逻辑
        firstShow: function () {

        },
        //面板打开时要做的逻辑
        panelShow: function () {

        },
        //面板关闭时要做的逻辑
        panelClose: function () {

        },
        //关闭按钮点击事件
        onCloseBtnClick: function() {
            //设置动画状态为正在播放(关闭动画)
            this.isClose = true;
            //动画播放完毕后,重置数据
            setTimeout(() => {
                this.isClose = false;
                this.$emit('update:visible',false);
            },400);
        },
    }
}

自定义一个包裹组件

/**
 * 功能:包裹页面组件
 */

let PackagePanel = {
    template: `
        <div class="shade package-panel" v-if="!isFirstShow" v-show="visible">
            <div :class="['panel-content animate__animated animate__faster',this.isClose ? 'animate__zoomOut' : 'animate__zoomIn']">
                <!-- 关闭按钮 -->
                <img
                    class="btn close-btn"
                    src="./imgs/ui/BtnClose2.png"
                    alt="关闭按钮"
                    @click="onCloseBtnClick"
                />
                <!-- 绘制包裹格子 -->
                <div class="box-panel package-box-panel">
                    <div
                        class="package-box"
                        v-for="i in 15"
                        :style="{left: 136 * ((i - 1) % 5) + 'px',top: 30 + 129 * Math.floor((i - 1) / 5) + 'px'}"
                    ></div>
                </div>
            </div>
        </div>
    `,
    mixins: [BasePanel1],
    methods: {
        //面板首次打开时要做的逻辑
        firstShow: function () {
            //给关闭按钮绑定音效
            this.$nextTick(() => {
                addEventBtnEffect(document.querySelector('.package-panel .close-btn'));
            });
        }
    }
}

主页导入组件

...
<script type="text/javascript" src="./components/BasePanel1.js"></script>
<script type="text/javascript" src="./components/PackagePanel.js"></script>
...

通用样式设置

...
.shade {
  width: 100%;
  height: 100%;
  background-color: rgba(0,0,0,.5);
  position: absolute;
  top: 0;
}
...

包裹样式设置

//包裹界面
.package-panel {
  pointer-events:auto;
  @include flex-center;
  .panel-content {
    background-image: url("../imgs/ui/package-panel.png");
    width: 899px;
    height: 564px;
    position: relative;
    .close-btn {
      position: absolute;
      right: 10px;
      top: 20px;
      z-index: 2;
    }
    .box-panel {
      position: absolute;
      width: 656px;
      height: 445px;
      left: 120px;
      top: 82px;
      overflow: hidden;
      box-sizing: border-box;
      &.package-box-panel {
        z-index: 1;
        .package-box {
          position: absolute;
          background-image: url("../imgs/ui/package-box.png");
          width: 106px;
          height: 109px;
        }
      }
    }
  }
}

主页引入样式

...
@import "../components/PackagePanel";

总结

详细代码和设计思路,如果大家感兴趣,请关注B站老九学堂的直播间

最后

记得给大黍❤️关注+点赞+收藏+评论+转发❤️

作者:老九学堂—技术大黍

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。