【问题标题】:How can I toggle one state only and undo it when I toggle the next (VueJS)如何仅切换一个状态并在切换下一个状态时撤消它(VueJS)
【发布时间】:2019-12-28 22:45:29
【问题描述】:

首先,我为我提出问题的方式道歉。我找不到用一句话来形容它的方法。所以,请允许我解释一下。

我有一个 API,其中有数千个项目在 v-for 中循环。用户一次只能从集合中选择一个。单击它后,它将与其他一些数据一起显示在一个单独的位置(* ,所以这不是字符串插值的情况。它是一个对象。我只是简化了我的 jsfiddle 中的代码来实现它更少的混乱和无依赖运行

我在 API 中添加了一个布尔属性来切换它的真/假,以及一个执行切换的方法函数。并且在一些 v-if 和 v-show 指令的帮助下,当它们为假时,我将隐藏其他元素以防止渲染。

<div id="app">
  <div uk-grid class="card-body">
    <div class="uk-width-1-4@m">
      <div>1. Select an Item</div>
      <div class="pods" v-for="pod in pods" :key="pod.id" :id="pod.id">
        <div class="ws-in-col" v-for="workstations in pod.workstations" :key="workstations.id" :id="workstations.id" @click="selectWS(workstations, pod)">
          <div class="ws ws-number uk-text-default">{{workstations.number}}</div>
        </div>
      </div>
    </div>
    <div class="uk-width-1-4@m">
      <div>2. Selected Item</div>
      <div class="pods" v-for="pod in pods" :key="pod.id" :id="pod.id" v-show="pod.selected===true">
        <div class="ws-in-col" v-for="workstations in pod.workstations" :key="workstations.id" :id="workstations.id" v-show="workstations.selected===true">
          <div v-if="workstations.selected === true">
            <div class="group">
              <div class="ws ws-number uk-text-default">{{workstations.number}}</div>
              <div class="ws ws-number uk-text-default">{{workstations.text}}</div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

在脚本中

methods: {
  selectWS(workstations, pods) {
    pods.selected = !pods.selected;
    workstations.selected = !workstations.selected;
  }
}

但是,不仅很乱而且菜​​鸟。是马车。它起作用的唯一方法是,如果用户单击一项以显示它,然后再次单击以将其关闭,然后再单击另一项以将其打开。这远非用户友好。

我怎样才能以更干净和专业的方式解决这个问题,这样如果用户点击 1.1,它会显示 1.1,如果他想看到 1.2,他所要做的就是点击 1.2 而不必先关闭 1.1 ?

这是JSFIDDLE 复制我的问题

谢谢各位。成为这个地方唯一的 Vue 开发人员很难。

【问题讨论】:

    标签: vue.js vuejs2


    【解决方案1】:

    同意 IVO,而不是跟踪 in-item,使用一个(或两个)值来跟踪选择

    我发布单独答案的唯一原因是我建议使用计算值如果您需要将所选实例作为对象使用

    new Vue({
      el: "#app",
      data: {
      	workstation: null,
    pod: null,
    pods: [
    {
      id: "pod1",
      number: 1,
      selected: false,
      "workstations": [
        {
          id: "ws11",
          number: "1.1",
          text: "Some text",
          selected: false,
          close: false
        },
        {
          id: "ws12",
          number: "1.2",
          text: "Some text",
          selected: false,
          close: false
        },
        {
          id: "ws13",
          number: "1.3",
          text: "Some text",
          selected: false,
          close: false
        }
      ]
    },
    {
      id: "pod2",
      number: 2,
      selected: false,
      "workstations": [
        {
          id: "ws21",
          number: "2.1",
          text: "Some text",
          selected: false,
          close: false
        },
        {
          id: "ws22",
          number: "2.2",
          text: "Some text",
          selected: false,
          close: false
        },
        {
          id: "ws23",
          number: "2.3",
          text: "Some text",
          selected: false,
          close: false
        }
      ]
    }
      ]
      },
      computed: {
    selection(){
      if(this.workstations !== null && this.pod !== null){
        let s = this.pods.filter(p => p.id === this.pod).map(p => {
          let r = {...p}
          r.workstations = p.workstations.filter(w => w.id === this.workstation)
          return r
        })
        if (s.length === 1) return s[0]
      }
      return false
    }
      },
      methods: {
      	selectWS(workstations, pods) {
    	if (this.pod == pods.id && this.workstation == workstations.id){
        this.pod = null;
        this.workstation = null;
      } else{
        this.pod = pods.id;
        this.workstation = workstations.id;
      }
    }
      }
    })
    body {
      background: #20262E;
      padding: 20px;
      font-family: Helvetica;
    }
    
    #app {
      background: #fff;
      border-radius: 4px;
      padding: 20px;
      transition: all 0.2s;
    }
    
    li {
      margin: 8px 0;
    }
    
    h2 {
      font-weight: bold;
      margin-bottom: 15px;
    }
    
    del {
      color: rgba(0, 0, 0, 0.3);
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/uikit/3.1.7/js/uikit.min.js"></script>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/uikit/3.1.7/css/uikit.min.css" rel="stylesheet"/>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
    <div id="app">
      <div uk-grid class="card-body">
    <div class="uk-width-1-4@m">
      <div>1. Select an Item</div>
      <div class="pods" v-for="pod in pods" :key="pod.id" :id="pod.id">
        <div class="ws-in-col" v-for="workstations in pod.workstations" :key="workstations.id" :id="workstations.id" @click="selectWS(workstations, pod)">
          <div class="ws ws-number uk-text-default">{{workstations.number}}</div>
        </div>
      </div>
    </div>
    <div class="uk-width-1-4@m">
      <div>2. Selected Item</div>
      <div v-if="selection" class="pods">
        <div class="ws-in-col">
          <div v-if="selection.workstations.length > 0">
            <div class="group">
              <div class="ws ws-number uk-text-default">{{selection.workstations[0].number}}</div>
              <div class="ws ws-number uk-text-default">{{selection.workstations[0].text}}</div>
            </div>
          </div>
        </div>
      </div>
    </div>
      </div>
    </div>

    【讨论】:

    • 太棒了!这就像一个魅力!我确实喜欢您将所选实例作为对象的想法,因为它将被进一步操作。我从工作站内部的示例代码中省略的部分内容是一堆开关和控件,它们有一些自己的代码。它不适用于 IVO 的解决方案,但我忽略了它并不是他的错。非常感谢您的帮助
    • 另外,如果您的 pod 的结构没有改变,我建议您不要跟踪 podworkstation 中的 id,而是跟踪索引。然后点击传递索引(对于 pod,你可以得到这样的索引 v-for="(pod, p_i) in pods" )这将使 selection 计算更直接
    【解决方案2】:

    您必须简单地设置最后选择的 pod/workstation,然后显示其属性(请在整个页面中运行 sn-p,否则您将无法看到正确的列):

    new Vue({
      el: "#app",
      data: {
        selectedPod: null,
        selectedWorkstation: null,
        pods: [
        {
          id: "pod1",
          number: 1,
          selected: false,
          "workstations": [
            {
              id: "ws11",
              number: "1.1",
              text: "Some text 1",
              selected: false,
              close: false
            },
            {
              id: "ws12",
              number: "1.2",
              text: "Some text 2",
              selected: false,
              close: false
            },
            {
              id: "ws13",
              number: "1.3",
              text: "Some text 3",
              selected: false,
              close: false
            }
          ]
        },
        {
          id: "pod2",
          number: 2,
          selected: false,
          "workstations": [
            {
              id: "ws21",
              number: "2.1",
              text: "Some text 4",
              selected: false,
              close: false
            },
            {
              id: "ws22",
              number: "2.2",
              text: "Some text 5",
              selected: false,
              close: false
            },
            {
              id: "ws23",
              number: "2.3",
              text: "Some text 6",
              selected: false,
              close: false
            }
          ]
        }
      ]
      },
      methods: {
      	selectWS(workstation, pod) {
          this.selectedPod = pod;
          this.selectedWorkstation = workstation;
        }
      }
    })
    body {
      background: #20262E;
      padding: 20px;
      font-family: Helvetica;
    }
    
    #app {
      background: #fff;
      border-radius: 4px;
      padding: 20px;
      transition: all 0.2s;
    }
    
    li {
      margin: 8px 0;
    }
    
    h2 {
      font-weight: bold;
      margin-bottom: 15px;
    }
    
    del {
      color: rgba(0, 0, 0, 0.3);
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/uikit/3.1.7/js/uikit.min.js"></script>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/uikit/3.1.7/css/uikit.min.css" rel="stylesheet"/>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
    <div id="app">
      <div uk-grid class="card-body">
        <div class="uk-width-1-4@m">
          <div>1. Select an Item</div>
          <div class="pods" v-for="pod in pods" :key="pod.id">
            <div class="ws-in-col" v-for="workstation in pod.workstations" :key="workstation.id" @click="selectWS(workstation, pod)">
              <div class="ws ws-number uk-text-default">
              {{workstation.number}}
              {{workstation.text}}
              </div>
            </div>
          </div>
        </div>
        <div class="uk-width-1-4@m">
          <div>2. Selected Item</div>
          <div class="pods" v-if="selectedWorkstation">
            <div class="ws-in-col">
              <div>
                <div class="group">
                  <div class="ws ws-number uk-text-default">{{selectedWorkstation.number}}</div>
                  <div class="ws ws-number uk-text-default">{{selectedWorkstation.text}}</div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-10-14
      • 1970-01-01
      • 2020-01-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多