如何在 Vue 中显示/隐藏对象的一部分 [英] How to show/hide parts of an object after in Vue

查看:70
本文介绍了如何在 Vue 中显示/隐藏对象的一部分的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为产品创建功能页面.当您点击功能名称时,它应该会展开下面的框并提供说明.

我取了一小段数据,其结构基本如下:

{部分": {第1页":{"FeatureName": "功能描述","FeatureName": "功能描述"},第2页": {"FeatureName": "功能描述","FeatureName": "功能描述"}}}

我想出了一些方法来做到这一点,但我个人认为它们中的任何一个都不是很好的方法.

  1. 遍历 json/object 并为每个功能添加一个 show 属性.然后我可以切换 bool 来显示/隐藏

  2. 从我的后端服务器开始,实际提供 show 属性,以便它可以与 vue 一起使用

这两种解决方案都不会使这些组件可重复使用(即,我将来可以将其用作手风琴,但我必须使用 show properties 污染源数据或进行一些繁重的迭代以添加属性,我并不总是这样做知道深度/级别.)

所以我问,有没有更好的方法,还是我列出的唯一方法?

解决方案

实现展开/折叠以显示更多细节是一个非常常见的问题.您可以使用以下几种方法:

  1. 为集合中的每个对象添加一个布尔属性.这实际上是您的两种方法归结起来的原因.我不希望服务器介入,这完全是一个 UI 问题.
  2. 将显示/隐藏值存储在单独的数组/对象中.只是一个大数组或布尔对象.这很可怕,但它确实避免了改变原始数据.在您的情况下,原始数据位于一个对象中,因此您还可以为布尔值使用一个对象,由与原始对象相同的键进行键控.
  3. 另一种避免改变原始数据的方法是包装每个对象.例如<代码>{第 1 页:{ 显示:假,页面:{ FeatureName:... } }.这种结构的缺点是必须编写模板来处理额外的嵌套.
  4. 创建一个组件来保存每个项目的相关状态.这通常是最好的解决方案,但问题是显示/隐藏状态是组件内部的,因此不容易从外部更改它.这使得实现全部显示"之类的事情变得很痛苦.只要您不需要从外部访问该状态,它就是一个巧妙的解决方案.示例在最后.

所有这些都假设每个扩展框都应该独立运行.如果您希望将它们链接起来以便一次只能打开一个,那么一切都会变得更加简单,因为您只需将当前展开的项目的 id 存储为 data 属性即可.

现在,正如承诺的那样,使用组件保存每个项目的相关状态的示例:

const expander = {道具:['物品'],数据 () {返回 {展开:假}},模板:`<div><h4>{{ item.title }}</h4><button @click="expanded = !expanded">切换</button><p v-if="expanded">{{ item.description }}</p>

`}新的 Vue({el: '#app',成分: {扩张器},数据 () {返回 {部分": {第1页":{"title": "标题 1",描述":等等等等等等"},第2页": {"title": "标题 2",描述":更多更多更多"}}}}})

<script src="https://unpkg.com/vue@2.6.10/dist/vue.js"><<;/脚本><div id="应用程序"><扩展器v-for="(item, propertyName) in Section":key="属性名":项目=项目"></扩展器>

I am creating a features page for a product. When you click the feature name, it should expand a box below and provide a description.

I took a small snippet of my data which is basically structured like this:

{
  "Section": {
    "Page1": {
      "FeatureName": "Feature desc",
      "FeatureName": "Feature desc"
    },
    "Page2": {
      "FeatureName": "Feature desc",
      "FeatureName": "Feature desc"
    }
  }
}

I have figured out a few ways to do this, but personally don't think any of them are great approaches.

  1. Looping through the json/object and adding a show property to each feature. Then I can just toggle bool to show/hide

  2. From my backend server, actually provide the show property to begin with so its ready to use with vue

Neither solution will make these components re-usable (ie, I can use this as an accordion in the future, but I have to pollute my source data with show properties OR do some heavy iterating to add properties, which I dont always know the depth/levels of.)

So I ask, is there a better approach or is what I have listed the only ways?

解决方案

Implementing expand/collapse to show more details is a pretty common problem. Here are a few ways you can do it:

  1. Add a boolean property to each object in the collection. This is effectively what both of your approaches boil down to. I wouldn't expect the server to get involved, this is entirely a UI concern.
  2. Store the show/hide values in a separate array/object. Just a big array or object of booleans. This is horrible but it does avoid mutating the original data. In your case the original data is in an object so you'd also use an object for the booleans, keyed by the same keys as the original object.
  3. Another way to avoid mutating the original data is to wrap each object. e.g. { Page1: { show: false, page: { FeatureName: ... } }. The downside with this structure is that the template must be written to handle the extra nesting.
  4. Create a component to hold the relevant state for each item. This is usually the best solution but the problem is that the show/hide state is internal to the component so it isn't easy to change it from the outside. This makes implementing something like 'Show all' a pain. So long as you don't need access to that state from outside it is a neat solution. Example at the end.

All of this assumes that each of the expand boxes should act independently. If you want them to be linked so that only one can be open at once it all gets much simpler as you can just store the id of the currently expanded item as a data property.

Now, as promised, an example of using a component to hold the relevant state for each item:

const expander = {
  props: ['item'],
  
  data () {
    return {
      expanded: false
    }
  },
  
  template: `
    <div>
      <h4>{{ item.title }}</h4>
      <button @click="expanded = !expanded">Toggle</button>
      <p v-if="expanded">{{ item.description }}</p>
    </div>
  `
}

new Vue({
  el: '#app',
  
  components: {
    expander
  },
  
  data () {
    return {
      "Section": {
        "Page1": {
          "title": "Title 1",
          "description": "Blah blah blah blah"
        },
        "Page2": {
          "title": "Title 2",
          "description": "More more more more"
        }
      }
    }
  }
})

<script src="https://unpkg.com/vue@2.6.10/dist/vue.js"></script>

<div id="app">
  <expander
    v-for="(item, propertyName) in Section"
    :key="propertyName"
    :item="item"
  ></expander>
</div>

这篇关于如何在 Vue 中显示/隐藏对象的一部分的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
前端开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆