桌子100%宽度

时间:2018-09-17 13:48:07

标签: javascript vuejs2

我当前正在使用VueJS创建一个复杂的接口,我想创建一个表,其宽度不超过100,并且在添加每列后必须始终等于100。 (最小和最大= 100)

例如:

columns = [
  {value: 10, active: true, head: "Col1"}, 
  {value: 25, active: true, head: "Col2"},
  {value: 50, active: false, head: "Col3"},
  {value: 25, active: true, head: "Col4"},
  {value: 10, active: true, head: "Col5"},
  {value: 30, active: true, head: "Col6"}
]

// Total = 100

现在想象一个表(只有活动元素可见并加起来:最大100个):

| Col1    | Col2         | Col4         | Col 5   | Col 6       |
|---------|--------------|--------------|---------|-------------|
 width:10%   width:25%      width:25%    width:10%   width:20%

我想让用户选择移动列的宽度。因此,如果我将第2列移到右侧,则会通过减小下一个可见列的大小来增加后者的大小。

到目前为止,我已经尝试了很多东西,但是没有任何作用。 看起来像我要创建的项目的唯一项目是在不起眼的捆绑网站上。:
 on the humble bundle site.

如果有人对评论有任何想法,我可以做到,最好的问候。

编辑:这是一个JS小提琴:https://jsfiddle.net/eywraw8t/374304/

1 个答案:

答案 0 :(得分:0)

您的代码中的问题是由(col, index) in getOnlyActive中的variable = index引起的。

当某些列处于非活动状态时,索引可能不会指向this.columns的正确列元素

例如

  1. col3 是不活动的,如果更改 col4 ,其索引在getOnlyActive内为3,但实际上在this.columns内,索引是4。

  2. col3 是不活动的,如果更改 col2 的值,则您的代码将减小 col3 的值,但是 col4 应该会减少。

一种解决方案

  1. 计算生命周期hook = {id中的created()属性。

  2. col.id传递给method = updateValue ,而不是v-for的索引。

  3. 使用Array.find获取 orgColumn

  4. 使用Array.find来获取 nextColumn ,如果最后一列,则从头开始使用第一活动列 。实际上,我们可以合并this.columnsthis.columns,然后从index=selectedId+1

  5. 中找到下一个活动列

下面是演示

new Vue({
  el: "#app",
  data: {
    columns: [
  		{value: 10, active: true, head: "Col1"}, 
  		{value: 25, active: true, head: "Col2"},
  		{value: 50, active: false, head: "Col3"},
  		{value: 25, active: true, head: "Col4"},
  		{value: 10, active: true, head: "Col5"},
  		{value: 30, active: true, head: "Col6"}
     ],
    oldValue: []
  },
  created () {
    this.columns.map((item, index) => {
      this.$set(item, 'id', index) // get id first before v-for
      return item
    })
  },
  mounted () {
  	this.oldValue = JSON.parse(JSON.stringify(this.columns))
  },
  methods: {
  	updateValue (col,selectedId) { // Something wrong here  
      // use id get the target col
    	let orgColumn = this.oldValue.find(item => item.id===selectedId)
      // use id to get next col, if id exceed the columns count, then get first active col from beginning
      let nextColumn = [...this.columns, ...this.columns].slice(selectedId+1).find(item => item.active)
      let diff = col.value - orgColumn['value']
      nextColumn['value'] -= diff
      this.oldValue = JSON.parse(JSON.stringify(this.columns))
    }
  },
  computed: {
  	getOnlyActive () {
    	return this.columns.filter(e => e.active)
    },
    getTotal () {
    	return this.getOnlyActive.map(e => +e.value).reduce((a,b) => a + b)
    }
  }
})
table, th, td {
   border: 1px solid black;
   width: 600px;
}
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app">
  <div v-for="(col, index) in getOnlyActive">
    {{col.id}}-{{col.head}}
     <input type="range" min="10" max="50" @change='updateValue(col,col.id)' v-model="col.value"> {{ col.value }}
  </div>
  
  <h3>{{ getTotal}}</h3>
  <table style="width=100%">
    <tr>
      <th v-for="(col, index) in getOnlyActive" :style="{width: col.value +'%'}"> {{ col.head }} </th>
    </tr>
    <tr v-for="col in 5">
      <td v-for="(col, index) in getOnlyActive">
      <p>RANDOM VALUE {{ col.id}}</p>
      </td>
    </tr>
  </table>  
</div>