【问题标题】:How to toggle items from grid and list view in Vuejs?如何在 Vuejs 中从网格和列表视图切换项目?
【发布时间】:2021-05-07 23:10:30
【问题描述】:

    isGridView: true,
    isListView: true,

    methods: {
            
            switchView: function() {
                
          this.isGridView = !this.isGridView;
          
            },

            switchData: function () {

                this.isListView = !this.isListView;
            }
  <div class="product-grid1">item1</div>
     <div class="product-grid2">item2</div> 
     <div class="product-grid3">item3</div>
     
      <div class="product-list1">item1</div>
     <div class="product-list2">item2</div> 
     <div class="product-list3">item3</div>
     
      <div id="app-gridview">

            <div>
                <button class="button" v-on:click="switchView()"></button>
                <button class="button" v-on:click="switchData()"></button>
            </div>

            <div v-bind:class="[ isGridView ? 'grid-wrapper' : 'list-wrapper' ]">

                <div class="grid-row" v-if="isGridView">
                    <div class="grid-header" v-for="name in gridData.columns">{{ name }}</div>
                </div>

                <!-- GridView structure -->
                <div v-if="isGridView" class="grid-row" v-for="row in gridData.data">
                    <div class="list-row-item" v-for="name in gridData.columns">
                        <div>{{ row[name] }}</div>
                    </div>
                </div>

                <!-- ListView structure -->
                <div v-if="!isGridView" class="list-row" v-for="row in gridData.data">
                    <img v-bind:src="row.ImagePath" class="list-image" />
                    <div class="list-property">
                        <div class="list-row-item" v-for="name in gridData.columns">
                            <div class="list-property-name">{{ name }}</div>
                            <div>{{ row[name] }}</div>
                        </div>
                    </div>
                </div>

            </div>

我尝试实现列表和网格视图,我需要在每个视图之间切换。为此,我将 isGrid 和 isList 设置为 true,并且从 vue 方面我尝试放置三元运算符,并在彼此之间切换。

你能帮我从列表和网格视图切换吗?

【问题讨论】:

  • 请创建一个minimal reproducible example。您可以从左侧下拉列表中选择 Vue.js 并添加您的 Vue.js 应用程序和组件。目前 sn-p 抛出错误

标签: javascript vue.js


【解决方案1】:

当你创建一个可以改变视图的组件时,我建议你使用容器展示组件模式。非常容易跟踪,添加新的数据“视图”是轻而易举的事。

// this is the grid view
// this is a presentational component:
// only displays what is passed through props
Vue.component("GridView", {
  props: ["users"],
  computed: {
    headers() {
      if (!this.users.length) return []
      return Object.keys(this.users[0])
    },
  },
  template: `
    <table>
      <thead>
        <tr>
          <th
            v-for="header in headers"
            :key="header"
          >
            {{ header }}
          </th>
        </tr>
      </thead>
      <tbody>
        <tr
          v-for="user in users"
          :key="user.id"
        >
          <td
            v-for="(val, key) in user"
            :key="user.id + '-' + key"
          >
            {{ val }}
          </td>
        </tr>
      </tbody>
    </table>
  `
})

// this is the list view
// this is a presentational component:
// only displays what is passed through props
Vue.component("ListView", {
  props: ["users"],
  template: `
    <ol>
      <li
        v-for="user in users"
        :key="user.id"
      >
        <div
          v-for="(val, key) in user"
          :key="user.id + '-' + key"
        >
          {{ key }}: {{ val }}
        </div>
      </li>
    </ol>
  `
})

// this component handles the data:
// fetching, mapping, transforming, etc.
// this is a renderless component
Vue.component("DataContainer", {
  data() {
    return {
      users: []
    }
  },
  mounted() {
    this.fetchUsers()
  },
  methods: {
    async fetchUsers() {
      try {
        const response = await fetch('https://jsonplaceholder.typicode.com/users')
        const json = await response.json()
        this.users = json.map(({
          id,
          name,
          username,
          email
        }) => ({
          id,
          name,
          username,
          email
        }))
      } catch (err) {
        console.error(err)
      }
    }
  },
  render(h) {
    // renders nothing, just provides the data
    // by passing it through "users"
    return this.$scopedSlots.default({
      users: this.users,
    })
  },
})

// the Vue instance
new Vue({
  el: "#app",
  data() {
    return {
      layout: "list-view",
    }
  },
  methods: {
    switchView() {
      this.layout = this.layout === "list-view" ? "grid-view" : "list-view"
    }
  },
  template: `
    <div>
      <button
        @click="switchView"
      >
        SWITCH VIEW
      </button>
      <data-container>
        <template
          #default="{ users }"
        >
          <component
            :is="layout"
            v-bind="{ users }"
          />
        </template>
      </data-container>
    </div>
  `,
})
table {
  border-collapse: collapse;
}

table,
tr,
th,
td {
  border: 1px solid black;
}

td,
th {
  padding: 4px 8px;
}

th {
  background-color: rgba(0, 0, 0, 0.3);
}
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script>
<div id="app"></div>

我知道这距离纠正 v-if 条件处理有点远 - 但此设置将帮助您创建灵活、可扩展且可维护的解决方案。

【讨论】:

    【解决方案2】:

    这是最干净的解决方案

    <template>
      <button @click="toggleList">switch render view</button>
    
      <component
        :is="currentComponent"
        :columns="gridData.columns"
        :items="gridData.data"
      />
    </template>
    
    <script>
    import gridComponent from "./your-grid-component.vue";
    import listComponent from "./your-list-component.vue";
    
    export default {
      components: {
        gridComponent,
        listComponent,
      },
      data() {
        return {
          listType: "grid", //grid/list
          gridData: {
            columns: [],
            data: [],
          },
        };
      },
      methods: {
        toggleList() {
          this.listType = this.listType === "grid" ? "list" : "grid";
        },
      },
      computed: {
        currentComponent() {
          return this.listType === "grid" ? "gridComponent" : "listComponent";
        },
      },
    };
    </script>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-04-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-27
      • 2013-06-11
      • 1970-01-01
      相关资源
      最近更新 更多