-
效果图(点击右侧的按钮,展示弹框,点击外部区域,当前的弹框进行隐藏)
image.png -
首先要将按钮和弹框写在一个组件中,用一个标签将两个进行包裹,否则后面点击的话,会有问题
-
话不多说,直接上代码
<div class="dialog-po" ref="dialog">
<img src="../assets/image/icon.png" alt="" class="icon" @click="() => (show = !show)" />
<div class="dialog" v-if="show">
<ul>
<li v-for="(item, index) in actions" :key="index" class="flexr flexcc po-li" @click="onSelect(index)" ref="dialogChild">
<img src="../assets/image/ac.png" alt="" class="ac" v-show="item.check" />
<p :class="item.check ? 'ac-li' : ''">{{ item.text }}</p>
</li>
</ul>
</div>
</div>
- 上述代码中,第一张图片是菜单,图片中的右上角的小按钮,主要是ref在当前页面的根标签上
<script>
import { watch } from 'vue';
export default {
name: 'DialogPage',
components: {},
props: {},
emits: ['dialogTitlte'],
setup(props, { emit }) {
const data = reactive({
show: false,
actions: [
{ text: '首页', check: true, path: '/' },
{ text: '我们的产品', check: false, path: '/product' },
{ text: '订制化解决方案', check: false, path: '/option' },
{ text: '果儿商城', check: false, path: '/shop' },
{ text: '新闻资讯', check: false, path: '/message' },
{ text: '关于我们', check: false, path: '/about' },
],
});
const route = useRoute();
const router = useRouter();
// 不是点击弹框中的事件,直接跳转展示的问题进行优化
watch(
() => route.path,
(newVal) => {
data.actions.forEach((item) => {
if (item.path === newVal) {
item.check = true;
} else {
item.check = false;
}
});
}
);
// 弹框中的点击事件,进行回调父组件通知更新
const onSelect = (k) => {
data.actions.forEach((item) => (item.check = false));
data.actions[k].check = true;
emit('dialogTitlte', data.actions[k].text);
data.show = false;
if (k == 3) {
window.open('https://miniapp.coretecnology.com/h5/guoer/index.html#/', '_blank');
} else {
router.push(data.actions[k].path);
}
};
const dialog = ref(null);
onMounted(() => {
document.addEventListener('click', (e) => hideDialog(e));
});
// 监听弹框标签外的点击事件,弹框外的点击事件可隐藏当前的弹框
const hideDialog = (e) => {
console.log('e', e, dialog.value?.contains(e.target), data.show);
if (data.show && !dialog.value?.contains(e.target)) {
data.show = false;
}
};
onUnmounted(() => {
document.removeEventListener('click', (e) => hideDialog(e));
});
return {
...toRefs(data),
dialog,
onSelect,
};
},
};
</script>
- vue 的api是用的插件自动引入可查看我的另一篇文章,代码的逻辑主要在最下面,onMounted这里,判断当前点击的元素在不在,不在就进行隐藏
- 有不懂的小伙伴可以私信我,希望可以帮助到你!
网友评论