记录要点个人

23 阅读2分钟

vue 点击某个div和本身弹窗不消失,点击其他空白处弹窗消失


@click.stop="" hidePopup

 <template>
    <div class="map-action-top flex">
        <div class="search">
            <el-input placeholder="请输入水源地、断面、河流..." v-model="serach" class="action-search"></el-input>
            <div class="search-buttom font-type">搜索</div>
        </div>
        <div class="map-action-top-right flex flex-align-c">
            <div class="map-action-top-right-li flex flex-dir-c flex-align-c flex-jus-c" v-for="(item, index) in tab"
                :key="index">
                <div class="flex flex-align-c" @click="handlerClick(item, index)">
                    <img class="icon-aciton" :src="item.url" :alt="item.name">
                    <div class="icon-name font-type mr-l"
                        :style="{ color: currentType.type === item.type ? '#0070c0' : '#fff' }">
                        {{ item.name }}</div>
                    <img :ref="item.type" v-if="index <= 3" class="icon-xia mr-l" src="../../../../assets/images/xia.png"
                        alt="">
                </div>
                <PopUp @click.stop="" class="test" v-if="currentType.type === item.type && item.flag && item.popUpTitle"
                    :style="{
                        top: '30px',
                        left: '50%'
                    }">
                    <div slot="title">
                        {{ item.popUpTitle }}
                    </div>
                </PopUp>
            </div>
        </div>
    </div>
</template>

<script>
import PopUp from './pop-up.vue'
export default {
    data() {
        return {
            serach: '',
            currentType: {},
            tab: [
                {
                    name: '流域',
                    type: 'catchment',
                    url: require("../../../../assets/images/catchment.png"),
                    flag: false,
                    popUpTitle: '都江堰水系数据',
                },
                {
                    name: '区域',
                    type: 'area',
                    url: require("../../../../assets/images/area.png"),
                    flag: false,
                    popUpTitle: '都江堰行政区划',
                },
                {
                    name: '组织管理',
                    type: 'organization',
                    url: require("../../../../assets/images/organization.png"),
                    flag: false,
                    popUpTitle: '组织管理',
                },
                {
                    name: '图层转换',
                    type: 'LayerConversion',
                    url: require("../../../../assets/images/LayerConversion.png"),
                    flag: false,
                    popUpTitle: '图层',
                },
                {
                    name: '清屏',
                    type: 'cls',
                    url: require("../../../../assets/images/cls.png"),
                    flag: false,
                },
                {
                    name: '全屏',
                    type: 'full-screen',
                    url: require("../../../../assets/images/full-screen.png"),
                    flag: false,
                },
                {
                    name: '地图',
                    type: 'map',
                    url: require("../../../../assets/images/map.png"),
                    flag: false,
                },
            ]
        }
    },
    components: {
        PopUp
    },
    mounted() {
        document.addEventListener("click", this.hidePopup);
    },
    beforeDestroy() {
        document.removeEventListener("click", this.hidePopup);
    },
    methods: {
        handlerClick(item, index) {
            if (index <= 3) if (!this.$refs[item.type][0].style.transform) this.$refs[item.type][0].style.transform = 'rotate(0deg)'
            this.currentType = item
            this.tab.forEach((v, index) => {
                if (this.$refs[v.type] && index <= 3) {
                    if (v.type == item.type) {
                        v.flag = !v.flag
                        this.$refs[v.type][0].style.transform == 'rotate(0deg)' ? this.$refs[v.type][0].style.transform = 'rotate(-180deg)' : this.$refs[v.type][0].style.transform = 'rotate(0deg)'
                    } else {
                        this.$refs[v.type][0].style.transform = 'rotate(0deg)'
                        v.flag = false
                    }
                }
            })
        },
        hidePopup(event) {
            // 判断点击的元素是否在弹窗中
            if (!this.$el.contains(event.target)) {
                this.currentType.flag = false
            }
        }

    },
}

</script>
<style scoped lang='scss'>
.map-action-top {
    position: absolute;
    left: 50%;
    top: 8px;
    height: 30px;
    transform: translate(-50%, 0);

    ::v-deep .action-search .el-input__inner {
        height: 30px;
        background: rgba($color: #031B38, $alpha: .9);
        // 设置字号
        font-size: 14px;
        font-family: PingFangSC-Regular, PingFang SC;
        font-weight: 400;
        // 设置输入字体的颜色
        color: #00ccff;
        border: 1px solid #004B96 !important;
        border-radius: 4px !important;
        width: 293px;
    }

    .search {
        position: relative;

        .search-buttom {
            position: absolute;
            top: 0;
            right: 1px;
            width: 52px;
            height: 30px;
            background: #004B96;
            border-radius: 4px;
            border-bottom-left-radius: 0;
            border-top-left-radius: 0;
            font-size: 14px;
            line-height: 30px;
            text-align: center;
            cursor: pointer;
        }
    }

    .map-action-top-right {
        margin-left: 10px;
        width: auto;
        height: 30px;
        background-image: url('../../../../assets/images/map-action-top-right.png');
        background-size: 100% 100%;
        background-repeat: no-repeat;

        .map-action-top-right-li {
            cursor: pointer;
            position: relative;
            height: 20px;
            padding: 0px 10px;
            border-right: 1px solid #ddd;

            &:last-child {
                border: none;
            }

            .icon-aciton {
                width: 13px;
                height: 13px;
                margin-top: -2px;
            }

            .icon-xia {
                width: 18px;
                height: 15px;
                transform: rotate(0deg);
                cursor: pointer;
                transition: all 0.5s;

                &:hover {
                    // transform: rotate(0deg);
                }
            }

            .icon-name {
                font-size: 13px;
            }

            // .action-top {
            //     position: absolute;
            //     top: 30px;
            //     left: 50%;
            //     transform: translate(-50%, 0);
            //     width: 100px;
            //     height: 100px;
            //     border: 1px solid red;
            // }
        }
    }

    .font-type {
        font-family: Source Han Sans CN;
        font-weight: 400;
        color: #FFFFFF;
    }

    .mr-l {
        margin-left: 5px;
    }
}
</style>

子组件封装成为v-model

Lin:
<template>
  <div>
    <el-input
      v-bind:value="vaal"
      v-on:input="handle"
    />
  </div>
</template>

<script>
export default {
  model: {
    prop: "vaal",
    event: "myInput",
  },
  props: {
    vaal: {
      type: String,
      default: "",
    },
  },
  methods:{
    handle(event){
        console.log(event)
        this.$emit('myInput', event)
    }
  }
};
</script>

<style lang="scss" scoped></style>

Lin:
// 子组件
export default {
  props: ['apiData'],
  watch: {
    apiData: {
      immediate: true, // 立即触发一次,确保初始值被观察
      handler(newVal) {
        this.$nextTick(() => {
          // 在DOM更新后执行代码
          // 更新表格等操作
        });
      },
    },
  },
}

其他

www.speeder.one/auth/login poe.com/ lj.lbbai.com/?node66