【问题标题】:How to create function that creates new grid-item onClick? Vuex using vue-grid-layout如何创建创建新网格项 onClick 的函数? Vuex 使用 vue-grid-layout
【发布时间】:2019-11-30 15:30:37
【问题描述】:

我正在使用 vue-grid-layout 创建一个可拖动的 tile 系统,它将跟踪我们研究实验室中系统执行的步骤顺序。简而言之,我可以通过硬编码创建尽可能多的网格项元素,但我需要能够创建一个函数来创建/删除其他网格项。我很困惑如何解决这个问题,因为我很擅长 JavaScript,要在 HTML 中创建一个网格项,我可以执行以下操作:

//这些只是网格项目的“设置”//

    <h2 style="color: #f6a821;">Steps</h2>
      <hr class="hr" />
      <grid-layout
        :layout.sync="stepsGrid"
        :col-num="8"
        :row-height="75"
        :is-draggable="true"
        :is-resizable="false"
        :is-mirrored="false"
        :vertical-compact="true"
        :margin="[50, 50]"
        :use-css-transforms="true">

//here we actually create the grid-item, starting at [0]
       <grid-item
          :x=stepsGrid[0].x
          :y=stepsGrid[0].y
          :w=stepsGrid[0].w
          :h=stepsGrid[0].h
          :i=stepsGrid[0].i
          :isDraggable=stepsGrid[0].isDraggable>

          <div class="Panel__name">1</div>
          <div class="editButton">
            <router-link to="/Parameters-template" class="editButton">Edit</router-link></router-link>
          </div><br>
          <div class="Panel__status">Status:</div>

        </grid-item>

我基本上需要知道如何单击以添加任意数量的这些,但我不确定如何编程。如果我目前有这个网格项,我需要按下一个按钮,该按钮将在以下位置创建另一个网格项:

<grid-item
      :x=stepsGrid[1].x
      :y=stepsGrid[1].y
      :w=stepsGrid[1].w
      :h=stepsGrid[1].h
      :i=stepsGrid[1].i
      :isDraggable=stepsGrid[1].isDraggable>

 ... content
</grid-item>

-并且会从 0 递增到 1、2、3 等。我的网格布局状态如下:

import Vue from 'vue';
import Vuex from 'vuex';

import createPersistedState from 'vuex-persistedstate'

Vue.use(Vuex);

export const store = new Vuex.Store({
    //strict: process.env.NODE_ENV !== 'production',
    state: {
        stepsGrid : [
            {"x":0,"y":0,"w":2,"h":1,"i":"0"},
            {"x":2,"y":0,"w":2,"h":1,"i":"1"},
            {"x":4,"y":0,"w":2,"h":1,"i":"2"},
            {"x":6,"y":0,"w":2,"h":1,"i":"3"},
            {"x":0,"y":2,"w":2,"h":1,"i":"4"},
            {"x":2,"y":2,"w":2,"h":1,"i":"5"}
        ],
.......
        mutations: {
        state.stepsGrid = [
            {"x":0,"y":0,"w":2,"h":1,"i":"0"},
            {"x":2,"y":0,"w":2,"h":1,"i":"1"},
            {"x":4,"y":0,"w":2,"h":1,"i":"2"},
            {"x":6,"y":0,"w":2,"h":1,"i":"3"},
            {"x":0,"y":2,"w":2,"h":1,"i":"4"},
            {"x":2,"y":2,"w":2,"h":1,"i":"5"}
                       ],

【问题讨论】:

    标签: javascript html vue.js grid vuex


    【解决方案1】:

    您需要使用v-for 来循环您的数据并创建每个项目。

    在下面的例子中我没有使用grid-layoutgrid-item,但原理完全一样。

    const store = new Vuex.Store({
        state: {
            stepsGrid: [
                {x: 0, y: 0, w: 2, h: 1, i: 0}
            ]
        },
        
        mutations: {
            addStep (state, step) {
                state.stepsGrid.push(step);
            }
        },
        
        actions: {
            addStep ({state, commit}) {
                const step = {x: 2, y: 0, w: 2, h: 1, i: state.stepsGrid.length};
    
                commit('addStep', step);
            }
        }
    });
    
    new Vue({
        el: '#app',
        store,
    
        computed: {
            stepsGrid () {
                return this.$store.state.stepsGrid;
            }
        },
    
        methods: {
            onClick () {
                this.$store.dispatch('addStep');
            }
        }
    });
    <script src="https://unpkg.com/vue@2.6.10/dist/vue.js"></script>
    <script src="https://unpkg.com/vuex@3.1.1/dist/vuex.js"></script>
    <div id="app">
      <ul>
        <li v-for="step in stepsGrid">{{ step }}</li>
      </ul>
      <button @click="onClick">Add step</button>
    </div>

    所以你的情况是:

    <grid-item
        v-for="step in stepsGrid"
        :x="step.x"
        :y="step.y"
        :w="step.w"
        :h="step.h"
        :i="step.i"
        :isDraggable="step.isDraggable">
    

    您可以将其简化为:

    <grid-item
        v-for="step in stepsGrid"
        v-bind="step">
    

    渲染列表的相关文档:

    https://vuejs.org/v2/guide/list.html
    https://vuejs.org/v2/api/#v-for

    【讨论】:

    • 谢谢,这很有帮助。但是,我现在遇到了我填充的网格项的持久状态问题。我现在可以创建新项目,每次都会增加数量,但是当我在这些图块/网格项目上单击“编辑”时,我会返回到所有创建的图块堆叠在一起。我将不得不研究我应该如何管理网格项位置的状态,当我从不同的组件单击/返回时出现此错误:
    • 错误:[Vue 警告]:nextTick 中的错误:“错误:VueGridLayout:布局[1].i 必须是字符串!”在 ---> at src/renderer/components/Automation.vue at src/renderer/App.vue
    • "模块警告(来自 ./node_modules/vue-loader/lib/loaders/templateLoader.js):(发出值而不是错误实例): 用 v-for 渲染的组件列表应该有明确的键。"
    • @julianstogs 在我的示例中,我将每个步骤的 i 值设为一个数字。该错误似乎表明 VueGridLayout 需要一个字符串。在我的示例中,我没有尝试为xywh 分配合理的值。如需添加密钥,请参阅 vuejs.org/v2/api/#keyvuejs.org/v2/style-guide/#Keyed-v-for-essential。在你的情况下,我建议:key="step.i"
    • 我尝试了你的建议,但是我仍然收到错误“VueGridLayout:布局[1]。我必须是一个字符串!”我进入了 store.js 文件,在定义“addStep”的操作中,我在“state.stepsGrid.length”周围加上了引号,现在我可以填充新的图块,当我更改页面并返回时,图块仍然存在在适当的位置。但是,它将“state.stepsGrid.length”解释为一个字符串,并且实际上是在每个图块上打印它,哈哈。有什么想法吗?
    猜你喜欢
    • 2013-10-10
    • 2019-02-03
    • 2019-11-29
    • 2021-05-31
    • 1970-01-01
    • 2021-04-01
    • 1970-01-01
    • 2018-03-16
    • 2018-01-13
    相关资源
    最近更新 更多