当前位置:   article > 正文

vue项目开发记录1:为v-html内的img元素添加点击放大效果_点击 v-html 里面的元素

点击 v-html 里面的元素

项目需求:在页面上显示帖子,帖子内的数据来源于后端,形式是"<p>内容</p>"这样的字符串。其中,要为所有的img元素添加一个点击之后看全图的功能,研究了一下,实现方案如下。

1. 基础内容,实现了帖子的显示
  1. <template>
  2. <div>
  3. <div v-for="post in posts" :id="post.id">
  4. <p>{{ post.author }}</p>
  5. <p>{{ post.create_time }}</p>
  6. <div class="content" v-html="post.content"></div>
  7. </div>
  8. </div>
  9. </template>
  10. <script setup>
  11. import { ref, onMounted } from 'vue';
  12. import { getPost } from '@/api/index";
  13. const posts = ref([])
  14. onMounted(() => {
  15. getData();
  16. })
  17. const getData = () => {
  18. getPost().then((res) => {
  19. posts.value = res.data;
  20. }).catch(err => {});
  21. }
  22. </script>
  23. <style scoped>
  24. .content >>> img {
  25. max-width: 500px;
  26. }
  27. </style>
2. 在finally中获取dom节点

由于要为img元素添加点击事件,起初我的想法是,用replaceAll函数手动给img添加@click或onclick事件,将字符串变成<img οnclick="test" src="/pictures/01.png" />这样的形式,后来发现不行,添加@click浏览器无法识别,添加onclick,浏览器也无法获取写在vue文件中的test函数,必须要对dom节点进行操作。

网上的写法都是在onMounted中通过ref获取对应节点,但是因为项目逻辑是在onMounted中调用api接口访问后端,所以必须要等到数据回来之后再去访问节点,才能获取对应的内容。

这时候就可以用到finally。在异步操作中,then, catch, finally是一组,finally内的内容在then和catch执行后执行,非常符合当前的场景。

  1. const getData = () => {
  2. getPost().then((res) => {
  3. posts.value = res.data;
  4. }).catch(err => {
  5. console.log(err);
  6. }).finally(() => {
  7. const elements = document.querySelectorAll('.content img'); // 获取所有img节点
  8. elements.forEach(item => item.addEventListener('click', handleClick);
  9. });
  10. }
3. 添加弹窗

本来想使用ant-design中的Modal实现图片放大后的弹窗,但是默认的样式和需求差得太远,所以自己写了个。其中还有个小插曲,因为这个组件外部还有内容,所以将.modal_mask的样式写为position:absolute;的时候,并没有达到全屏的效果,只是占满了外部组件的全部,所以要写成position:fixed;

  1. <template>
  2. <div>
  3. ...
  4. <div v-show="showModal" class="modal_mask">
  5. <div class="close_btn" @click="showModal=false">
  6. <img src="@/assets/pictures/close.png" />
  7. </div>
  8. <img :src="imgsrc" />
  9. </div>
  10. </template>
  11. <script setup>
  12. ...
  13. const showModal = ref(false); //控制弹窗显示隐藏
  14. const imgsrc = ref('');
  15. ...
  16. const handleClick = (event) => {
  17. showModal.value = true;
  18. imgsrc.value = event.target.src; //必须要通过传来的event获取图片src
  19. }
  20. </script>
  21. <style scoped>
  22. .modal_mask {
  23. position: fixed;
  24. left: 0;
  25. right: 0;
  26. top: 0;
  27. bottom: 0;
  28. background-color: rgba(0, 0, 0, 0.45);
  29. z-index: 9999;
  30. display: flex;
  31. align-items: center;
  32. justify-content: center;
  33. }
  34. .modal_mask .close_btn {
  35. position: absolute;
  36. right: 10px;
  37. top: 10px;
  38. cursor: pointer;
  39. }
  40. .modal_mask img {
  41. max-width: 100%;
  42. max-height: 100%;
  43. }
  44. </style>
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小舞很执着/article/detail/1014977
推荐阅读