如何根据 v-for 值在模态窗口(单击按钮时)上获取所选数据?

Posted

技术标签:

【中文标题】如何根据 v-for 值在模态窗口(单击按钮时)上获取所选数据?【英文标题】:How can I get the selected data on my modal window(on button click) based on the v-for value? 【发布时间】:2020-01-19 09:59:59 【问题描述】:

我是 Vue 的新手,我正在使用 Bootstrap 模式来显示产品信息。我有网格容器,每个容器都有一个产品图片、描述和两个按钮。其中一个按钮(More details >>)在单击时会弹出一个模态窗口,该窗口应显示与其所在网格完全相同的产品描述和图片。

<div id="myapp">
  <h1>  allRecords()  </h1>
  <div class="wrapper" >
    <div class="grid-container" v-for="product in products" v-bind:key="product.ID">
      <div class="Area-1">
        <img class="product_image" src="https:....single_product.jpg"> 
      </div>
      <div class="Area-2">
        <div class = "amount">
           product.amount 
        </div>
         product.Description 
      </div>
      <div class="Area-3">
        <b-button size="sm" v-b-modal="'myModal'" product_item = "'product'">
          More Details >>
        </b-button>
        <b-modal id="myModal" >
          <h1>  product.Name  </h1>
          <h3>  product.Description  </h3>
        </b-modal>
      </div>
      <div class="Area-4">
        <br><button>Buy</button>
      </div>
    </div>
  </div>
</div>
var app = new Vue(
  'el': '#myapp',
  data: 
    products: "",
    productID: 0
  ,
  methods: 
    allRecords: function()
      axios.get('ajaxfile.php')
        .then(function (response) 
          app.products = response.data;
        )
        .catch(function (error) 
          console.log(error);
        );
    ,
  
)

区域 1、2 和 4 工作得非常好,它们根据 v-for 值显示产品数据,并分别按每个网格容器的预期显示。当我单击More details &gt;&gt; 按钮时,区域 3 是一个问题,我只看到一个褪色的黑屏。我不确定我在这里做错了什么,非常感谢一些帮助。

【问题讨论】:

【参考方案1】:

添加一个属性 selectedProduct,然后在 More Details 按钮单击事件上,将当前产品分配给 selectedProduct 成员,如下所示:

html

  <div class="Area-3">
    <b-button size="sm" v-b-modal="'myModal'" 
             @click="selectProduct(product)">More Details >> </b-button>    
    <b-modal id="myModal">
             <h1>  this.selectedProduct.Name  </h1>
             <h3>  this.selectedProduct.Description  </h3>
    </b-modal>
  </div>

javascript

var app = new Vue(
 'el': '#myapp',
 data: 
    products: "",
    productID: 0,
    selectedProduct: Name: '', Description: '', Amount:0
 ,
 methods: 
   allRecords: function()
   ...
   ,
   selectProduct: function(product)
   
       this.selectedProduct = product;
   
   ...
 

【讨论】:

这是一个不错的选择,但是您需要将b-modal 放在v-for 之外。 我做了@Hiws 提到的操作,但在控制台中出现错误:TypeError: Cannot read property 'Name' of undefined 非常感谢!你的解决方案奏效了。问题是我有很多script srcs和imports,一步一步清除,现在效果很好。【参考方案2】:

我无法复制该问题。我创建了 JSFiddle 来测试:

https://jsfiddle.net/4289wh0e/1/

但是,当我单击“更多详细信息”按钮时,我意识到会显示多个模态元素。

我建议您在包装器中仅添加一个模态并将所选产品存储在数据变量中。

https://jsfiddle.net/4289wh0e/2/

<div id="myapp">
    <h1>  allRecords()  </h1>

    <div class="wrapper">

        <div class="grid-container" v-for="product in products" v-bind:key="product.ID">

            <div class="Area-1"><img class="product_image" src="https:....single_product.jpg"> </div>

            <div class="Area-2">
                <div class="amount"> product.amount  </div>
                 product.Description </div>

            <div class="Area-3">
                <b-button size="sm" v-b-modal="'productModal'" @click="chooseProduct(product)" product_item="'product'">More Details >> </b-button>

            </div>

            <div class="Area-4">
                <br>
                <button>Buy</button>
            </div>
        </div>

        <b-modal id="productModal" v-if="chosenProduct">
            <h1>  chosenProduct.Name  </h1>
            <h3>  chosenProduct.Description  </h3>
        </b-modal>
    </div>
</div>
Vue.use(BootstrapVue)

var app = new Vue(
    'el': '#myapp',
    data: 
        products: [],
        chosenProduct: null
    ,
    methods: 
            chooseProduct: function (product) 
            this.chosenProduct = product
        ,
        allRecords: function()
                    this.products = [
            
                ID: 1,
                Description: 'dek',
              Name: 'Name',
              amount: 100
            ,
            
                ID: 2,
                Description: 'dek 2',
              Name: 'Name 2',
              amount: 300
            
          ]
        ,
    
)

【讨论】:

嗨!感谢您的回答,我收到一个错误:ReferenceError: chosenProduct is not defined。此外,由于我从数据库中获取数据,我假设该方法应如下所示:chooseProduct: function (product) app.chosenProduct = product , ?如果我错了,请纠正我 是的,你是对的。对于 Ajax 请求,this 范围更改。 是否在数据字段中声明? 是的,var app = new Vue( 'el': '#myapp', data: products: [], chosenProduct: null ,【参考方案3】:

您看到黑屏的原因是您没有为v-for 中的b-modal 提供唯一ID。 因此,当您单击按钮时,它实际上同时打开了所有模式,并堆叠了背景使其看起来很暗。

相反,您可以在您的模态 ID 中使用您的产品 ID(我猜它是独一无二的)以使其独一无二

<div id="myapp">
  <h1>  allRecords()  </h1>
  <div class="wrapper" >
    <div class="grid-container" v-for="product in products" v-bind:key="product.ID">
      <div class="Area-1">
        <img class="product_image" src="https:....single_product.jpg"> 
      </div>
      <div class="Area-2"><div class = "amount"> product.amount  </div>
         product.Description 
      </div>
      <div class="Area-3">
        <b-button size="sm" v-b-modal="`myModal-$product.ID`" product_item = "'product'">
          More Details >> 
        </b-button>
        <b-modal :id="`myModal-$product.ID`" >
          <h1>  product.Name  </h1>
          <h3>  product.Description  </h3>
        </b-modal>
      </div>
      <div class="Area-4">
        <br><button>Buy</button>
      </div>
    </div>
  </div>
</div>

示例笔: https://codepen.io/Hiws/pen/qBWJjOZ?editors=1010

【讨论】:

嗨!感谢您的回答!屏幕看起来不那么暗了,我可以看到后面的组件,但没有包含预期内容的模态窗口。 :( @AlyssaAlex 如果背景显示在前面,则可能与此问题有关。 ***.com/questions/10636667/… 您也可以在打开窗口后尝试探索 DOM,看看模态是否真的存在。我添加了上述示例的代码笔,它正在工作

以上是关于如何根据 v-for 值在模态窗口(单击按钮时)上获取所选数据?的主要内容,如果未能解决你的问题,请参考以下文章

根据最初检查的复选框值在后退按钮单击时重新加载 Angular 6 反应式表单

模态弹出窗口上的“发送”按钮第一次不起作用c#

如何在模态窗口中显示 pdf? [关闭]

如何在模态中显示来自 v-for 的单击元素的 vue 数据

在 Laravel 中单击模态后如何获取标签的 data-href 值

单击按钮 php mysql 后,在模式弹出窗口上显示基于所选 id 的数据