【问题标题】:Vue image modal open on click单击时打开 Vue 图像模式
【发布时间】:2021-05-28 00:17:34
【问题描述】:

我正在开发一个简单的 Vue 应用程序,其中包含我希望在单击时以引导模式打开的图像。

我一直在阅读各种教程和解决方案,但我仍然无法弄清楚如何完成模式。我有图片显示,但我不知道如何在点击图片时让图片以模式显示。

这是我目前所拥有的:

Vue 组件:

<template>
  <div class="row" v-if="othersImages">
      <div id="others-images" class="grid">
          <div class="grid-item" v-for="image in othersImages" :key="image.id">
              <h5>{{ image.name }}</h5>
              <picture v-bind="'image' + image.id">
                <img v-bind:src="image.image.path" v-bind:alt="image.description" 
                @click="showModal"/>
              </picture>
          </div>
      </div>
      <div id="image-modal" class="modal" tabindex="-1" role="dialog">
        <div class="modal-dialog" role="document">
          <div class="modal-content">
            <div class="modal-body">
            </div>
          </div>
        </div>
      </div>
  </div>
</template>

<script>
export default {
  name: 'othersImages',
  created() {
    this.fetchImages();
  },
  data() {
    return {
      apiRequest: new this.$request(),
      othersImages: [],
      errors: '',
    };
  },
  methods: {
    showModal() {
      // Not sure what to put here?
    }
  },
};
</script>

CSS:

#others-images{
    margin-bottom: 30px;
}
.modal-dialog{
    max-width: 75vw !important;
    .modal-content{
        background-color: transparent;
        border: none;
        border-radius: 0;
        display: flex;
        justify-content: center;
        align-items: center;
        .modal-body{
            padding: 0;
            background-color: #fff;
            img{
                width: 100%;
                height: auto;
            }
            h5{
                color: $gold;
                font-weight: 700;
                margin-top: 15px;
                margin-left: 15px;
            }
            p{
                margin-top: 5px;
                margin-left: 15px;
            }
            .close{
                position: abs(absolute);
                border-bottom: none;
                border-top-left-radius: 0;
                border-top-right-radius: 0;
                right: 15px;
                bottom: 15px;
                color: $text_colour;
                text-shadow: none;
            }
        }
    }
}

【问题讨论】:

    标签: vue.js bootstrap-modal bootstrap-vue


    【解决方案1】:

    对于要在单击时加载的特定图像,您需要将其作为函数的参数传递,然后将其放入您插入到 img src 中的变量中。 像这样:

    将选定的 img 作为参数传递

    <div class="grid-item" v-for="image in othersImages" :key="image.id">
              <h5>{{ image.name }}</h5>
              <picture v-bind="'image' + image.id">
                <img v-bind:src="image.image.path" v-bind:alt="image.description" 
                @click="showModal(image.image.path)"/>
              </picture>
          </div>
    

    然后你将 img 路径加载到一个变量中:

    data() {
    return {
      // ...
      modalShow: false,
      selectedImgPath: ''
    };
    }
    methods: {
        showModal(imgPath) {
          this.selectedImgPath = imgPath
          this.modalShow = true
        }
      },
    

    通过显示模态和选定的 img 来终止:

    <div id="image-modal" v-if="modalShow" class="modal" tabindex="-1" role="dialog">
            <div class="modal-dialog" role="document">
              <div class="modal-content">
                <div class="modal-body">
                  <img :src='selectedImgPath'/>
                </div>
              </div>
            </div>
          </div>
    

    应该是这样的。

    【讨论】:

    • 感谢您的回复,我可以在调试中看到它正在通过图像路径传递给“showModal”方法,但之后似乎出现了问题。我在
      问题是在 标签上使用没有属性的 v-bind if is an id use
    【解决方案2】:

    我将通过一个简单的代码 sn-p 向您展示解决方案,以便更好地理解。

    在代码sn-p中,我们使用show_modal方法改变modal的内容,然后打开modal。

    new Vue({
      el: '#app',
      data() {
        return {
          modal_image_path: "",
          images: [{
              id: 1,
              path: "https://i.picsum.photos/id/42/100/100.jpg?hmac=H5fOEzyhxakVIBdXzI4E5EQ9Fox99YKCeCO7dwSzLFY"
            },
            {
              id: 2,
              path: "https://picsum.photos/100/100"
            }
          ]
        }
      },
      methods: {
        open_modal(image_path) {
          this.modal_image_path = image_path
          this.$bvModal.show('showImageModal')
        }
      }
    })
    #app {
      padding: 20px;
      height: 450px;
    }
    
    .wrapper {
      display: flex;
    }
    
    .wrapper>div {
      margin: 10px;
      cursor: pointer;
    }
    <link type="text/css" rel="stylesheet" href="https://unpkg.com/bootstrap@4.5.3/dist/css/bootstrap.min.css" />
    <link type="text/css" rel="stylesheet" href="https://unpkg.com/bootstrap-vue@2.21.2/dist/bootstrap-vue.css" />
    
    <script src="https://unpkg.com/vue@2.6.12/dist/vue.min.js"></script>
    <script src="https://unpkg.com/bootstrap-vue@2.21.2/dist/bootstrap-vue.min.js"></script>
    
    <div id="app">
      <b-modal id="showImageModal" title="BootstrapVue">
        <b-img-lazy :src="modal_image_path" />
      </b-modal>
      <div class="wrapper">
        <div v-for="image in images" :key="image.id" @click="open_modal(image.path)">
          <b-img-lazy :src="image.path" />
        </div>
      </div>
    </div>

    【讨论】:

      【解决方案3】:

      有很多方法可以控制应用中的模式。

      您可以尝试以下一些额外的初学者步骤:

      1 - 定义将保持模态状态的参数(简单地 true/false 表示显示/隐藏),以及保存模态内容的东西(在更成熟的模态系统中,您不会保留像这……为什么要存储两次?):

      data() {
          return {
            // ...
            modalShow: false,
            modalContent: null
          };
      }
      

      2 - 在模态元素上添加v-if。 modal会根据状态参数显示/隐藏。

      <div id="image-modal" v-if="modalShow" ...
      

      3 - 将内容传递到您的 showModal() 方法中

      ... @click="showModal(image.image.path)"/>
      

      .

      showModal(content) {
        this.modalShow = true
        this.modalContent = content
      }
      

      4 - 使模态内容在模态中呈现

      <div class="modal-body">
         {{ modalContent }}
      </div>
      

      您在@click 事件中究竟传递了什么内容,以及您如何在模态中解释它是另一个问题。您想在模态框内显示的究竟是什么?只有一个,没有控件?这可能就像将 src url 换成图像元素一样粗糙。


      最终要利用 Vue 的真正力量,您可能想要制作自己的“Modal.vue”组件,您可以在整个应用程序中全局使用它(在根目录中导入一次)。它可以有控制它是否是全屏模式、是否启用用户关闭、背景页面是否可滚动、它具有什么样的过渡等的道具。

      您可能希望使用事件总线来打开/关闭它,并将内容发送到其中。您也可能会在模态的模板中使用slots(例如,模态槽,如'header'、'content'、'footer')。这就是我在所有 Vue 应用程序中为模态所做的。

      上述想法与您在 React 应用程序(或其他技术)中实现的想法完全相同。基本上你是在解耦和抽象事物。

      无论如何,您不需要任何引导程序,但是,如果您喜欢使用它,请随意。我建议学习 Vue,不要让引导程序弄得一团糟。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-12-17
        • 2022-01-25
        • 1970-01-01
        • 2018-12-30
        • 2022-06-17
        • 2018-11-02
        • 1970-01-01
        相关资源
        最近更新 更多