Vue JS 2 table 标题随内容水平滚动但不垂直滚动

Vue JS 2 table title Scroll horizontally with content but not vertically

首先是简单的 Html+css,没有 JS,这很容易做到:

table {
    border-collapse: collapse; 
}
tr {
    border: solid black 1px;
}
td{
  border: solid black 1px;
}

.outer-container {
    height: 190px;
    width: 620px;
}
.inner-container {
    width: 100%;
    height: 100%;
}
.table-header {
    width: 100%;
    overflow:hidden;
}
.table-body {
    height: 100%;
    width: inherit;
    overflow-y: scroll;
}

.col1, .col2, .col3, .col4, .col5 {
    width:320px;
    min-width: 320px;
}
<body>
<div class="outer-container"> <!-- absolute positioned container -->
<div class="inner-container">
    <div class="table-header" id="headerdiv">
        <table id="headertable" width="100%" cellpadding="0" cellspacing="0">
            <thead>
                <tr>
                    <th class="header-cell col1">One</th>
                    <th class="header-cell col2">Two</th>
                    <th class="header-cell col3">Three</th>
                    <th class="header-cell col4">Four</th>
                    <th class="header-cell col5">Five</th>
                </tr>
            </thead>
        </table>
    </div>
    <div class="table-body" onscroll="document.getElementById('headerdiv').scrollLeft = this.scrollLeft;">
        <table id="bodytable" width="100%" cellpadding="0" cellspacing="0">
            <tbody>
                <tr>
                    <td class="body-cell col1">body row1</td>
                    <td class="body-cell col2">body row2</td>
                    <td class="body-cell col3">body row2</td>
                    <td class="body-cell col4">body row2</td>
                    <td class="body-cell col5">body row2 en nog meer</td>
                </tr>
                <tr>
                    <td class="body-cell col1">body row1</td>
                    <td class="body-cell col2">body row2</td>
                    <td class="body-cell col3">body row2</td>
                    <td class="body-cell col4">body row2</td>
                    <td class="body-cell col5">body row2 en nog meer</td>
                </tr>
                <tr>
                    <td class="body-cell col1">body row1</td>
                    <td class="body-cell col2">body row2</td>
                    <td class="body-cell col3">body row2</td>
                    <td class="body-cell col4">body row2</td>
                    <td class="body-cell col5">body row2 en nog meer</td>
                </tr>
                <tr>
                    <td class="body-cell col1">body row1</td>
                    <td class="body-cell col2">body row2</td>
                    <td class="body-cell col3">body row2</td>
                    <td class="body-cell col4">body row2</td>
                    <td class="body-cell col5">body row2 en nog meer</td>
                </tr>
                <tr>
                    <td class="body-cell col1">body row1</td>
                    <td class="body-cell col2">body row2</td>
                    <td class="body-cell col3">body row2</td>
                    <td class="body-cell col4">body row2</td>
                    <td class="body-cell col5">body row2 en nog meer</td>
                </tr>
                <tr>
                    <td class="body-cell col1">body row1</td>
                    <td class="body-cell col2">body row2</td>
                    <td class="body-cell col3">body row2</td>
                    <td class="body-cell col4">body row2</td>
                    <td class="body-cell col5">body row2 en nog meer</td>
                </tr>
                <tr>
                    <td class="body-cell col1">body row1</td>
                    <td class="body-cell col2">body row2</td>
                    <td class="body-cell col3">body row2</td>
                    <td class="body-cell col4">body row2</td>
                    <td class="body-cell col5">body row2 en nog meer</td>
                </tr>
                <tr>
                    <td class="body-cell col1">body row1</td>
                    <td class="body-cell col2">body row2</td>
                    <td class="body-cell col3">body row2</td>
                    <td class="body-cell col4">body row2</td>
                    <td class="body-cell col5">body row2 en nog meer</td>
                </tr>
                <tr>
                    <td class="body-cell col1">body row1</td>
                    <td class="body-cell col2">body row2</td>
                    <td class="body-cell col3">body row2</td>
                    <td class="body-cell col4">body row2</td>
                    <td class="body-cell col5">body row2 en nog meer</td>
                </tr>
                <tr>
                    <td class="body-cell col1">body row1</td>
                    <td class="body-cell col2">body row2</td>
                    <td class="body-cell col3">body row2</td>
                    <td class="body-cell col4">body row2</td>
                    <td class="body-cell col5">body row2 en nog meer</td>
                </tr>
                <tr>
                    <td class="body-cell col1">body row1</td>
                    <td class="body-cell col2">body row2</td>
                    <td class="body-cell col3">body row2</td>
                    <td class="body-cell col4">body row2</td>
                    <td class="body-cell col5">body row2 en nog meer</td>
                </tr>
                <tr>
                    <td class="body-cell col1">body row1</td>
                    <td class="body-cell col2">body row2</td>
                    <td class="body-cell col3">body row2</td>
                    <td class="body-cell col4">body row2</td>
                    <td class="body-cell col5">body row2 en nog meer</td>
                </tr>
                <tr>
                    <td class="body-cell col1">body row1</td>
                    <td class="body-cell col2">body row2</td>
                    <td class="body-cell col3">body row2</td>
                    <td class="body-cell col4">body row2</td>
                    <td class="body-cell col5">body row2 en nog meer</td>
                </tr>
                <tr>
                    <td class="body-cell col1">body row1</td>
                    <td class="body-cell col2">body row2</td>
                    <td class="body-cell col3">body row2</td>
                    <td class="body-cell col4">body row2</td>
                    <td class="body-cell col5">body row2 en nog meer</td>
                </tr>
                <tr>
                    <td class="body-cell col1">body row1</td>
                    <td class="body-cell col2">body row2</td>
                    <td class="body-cell col3">body row2</td>
                    <td class="body-cell col4">body row2</td>
                    <td class="body-cell col5">body row2 en nog meer</td>
                </tr>
                <tr>
                    <td class="body-cell col1">body row1</td>
                    <td class="body-cell col2">body row2</td>
                    <td class="body-cell col3">body row2</td>
                    <td class="body-cell col4">body row2</td>
                    <td class="body-cell col5">body row2 en nog meer</td>
                </tr>
                <tr>
                    <td class="body-cell col1">body row1</td>
                    <td class="body-cell col2">body row2</td>
                    <td class="body-cell col3">body row2</td>
                    <td class="body-cell col4">body row2</td>
                    <td class="body-cell col5">body row2 en nog meer</td>
                </tr>
                <tr>
                    <td class="body-cell col1">body row1</td>
                    <td class="body-cell col2">body row2</td>
                    <td class="body-cell col3">body row2</td>
                    <td class="body-cell col4">body row2</td>
                    <td class="body-cell col5">body row2 en nog meer</td>
                </tr>
                <tr>
                    <td class="body-cell col1">body row1</td>
                    <td class="body-cell col2">body row2</td>
                    <td class="body-cell col3">body row2</td>
                    <td class="body-cell col4">body row2</td>
                    <td class="body-cell col5">body row2 en nog meer</td>
                </tr>
                <tr>
                    <td class="body-cell col1">body row1</td>
                    <td class="body-cell col2">body row2</td>
                    <td class="body-cell col3">body row2</td>
                    <td class="body-cell col4">body row2</td>
                    <td class="body-cell col5">body row2 en nog meer</td>
                </tr>
                <tr>
                    <td class="body-cell col1">body row1</td>
                    <td class="body-cell col2">body row2</td>
                    <td class="body-cell col3">body row2</td>
                    <td class="body-cell col4">body row2</td>
                    <td class="body-cell col5">body row2 en nog meer</td>
                </tr>
                <tr>
                    <td class="body-cell col1">body row1</td>
                    <td class="body-cell col2">body row2</td>
                    <td class="body-cell col3">body row2</td>
                    <td class="body-cell col4">body row2</td>
                    <td class="body-cell col5">body row2 en nog meer</td>
                </tr>
                <tr>
                    <td class="body-cell col1">body row1</td>
                    <td class="body-cell col2">body row2</td>
                    <td class="body-cell col3">body row2</td>
                    <td class="body-cell col4">body row2</td>
                    <td class="body-cell col5">body row2 en nog meer</td>
                </tr>
                <tr>
                    <td class="body-cell col1">body row1</td>
                    <td class="body-cell col2">body row2</td>
                    <td class="body-cell col3">body row2</td>
                    <td class="body-cell col4">body row2</td>
                    <td class="body-cell col5">body row2 en nog meer</td>
                </tr>
                <tr>
                    <td class="body-cell col1">body row1</td>
                    <td class="body-cell col2">body row2</td>
                    <td class="body-cell col3">body row2</td>
                    <td class="body-cell col4">body row2</td>
                    <td class="body-cell col5">body row2 en nog meer</td>
                </tr>
                <tr>
                    <td class="body-cell col1">body row1</td>
                    <td class="body-cell col2">body row2</td>
                    <td class="body-cell col3">body row2</td>
                    <td class="body-cell col4">body row2</td>
                    <td class="body-cell col5">body row2 en nog meer</td>
                </tr>
                <tr>
                    <td class="body-cell col1">body row1</td>
                    <td class="body-cell col2">body row2</td>
                    <td class="body-cell col3">body row2</td>
                    <td class="body-cell col4">body row2</td>
                    <td class="body-cell col5">body row2 en nog meer</td>
                </tr>
                <tr>
                    <td class="body-cell col1">body row1</td>
                    <td class="body-cell col2">body row2</td>
                    <td class="body-cell col3">body row2</td>
                    <td class="body-cell col4">body row2</td>
                    <td class="body-cell col5">body row2 en nog meer</td>
                </tr>
                <tr>
                    <td class="body-cell col1">body row1</td>
                    <td class="body-cell col2">body row2</td>
                    <td class="body-cell col3">body row2</td>
                    <td class="body-cell col4">body row2</td>
                    <td class="body-cell col5">body row2 en nog meer</td>
                </tr>
                <tr>
                    <td class="body-cell col1">body row1</td>
                    <td class="body-cell col2">body row2</td>
                    <td class="body-cell col3">body row2</td>
                    <td class="body-cell col4">body row2</td>
                    <td class="body-cell col5">body row2 en nog meer</td>
                </tr>
                <tr>
                    <td class="body-cell col1">body row1</td>
                    <td class="body-cell col2">body row2</td>
                    <td class="body-cell col3">body row2</td>
                    <td class="body-cell col4">body row2</td>
                    <td class="body-cell col5">body row2 en nog meer</td>
                </tr>
                <tr>
                    <td class="body-cell col1">body row1</td>
                    <td class="body-cell col2">body row2</td>
                    <td class="body-cell col3">body row2</td>
                    <td class="body-cell col4">body row2</td>
                    <td class="body-cell col5">body row2 en nog meer</td>
                </tr>
                <tr>
                    <td class="body-cell col1">body row1</td>
                    <td class="body-cell col2">body row2</td>
                    <td class="body-cell col3">body row2</td>
                    <td class="body-cell col4">body row2</td>
                    <td class="body-cell col5">body row2 en nog meer</td>
                </tr>
                <tr>
                    <td class="body-cell col1">body row1</td>
                    <td class="body-cell col2">body row2</td>
                    <td class="body-cell col3">body row2</td>
                    <td class="body-cell col4">body row2</td>
                    <td class="body-cell col5">body row2 en nog meer</td>
                </tr>
                <tr>
                    <td class="body-cell col1">body row1</td>
                    <td class="body-cell col2">body row2</td>
                    <td class="body-cell col3">body row2</td>
                    <td class="body-cell col4">body row2</td>
                    <td class="body-cell col5">body row2 en nog meer</td>
                </tr>
            </tbody>
        </table>
    </div>
</div>
</div>
</body>

source

问题是我的 Vue.js 应用程序中有不同的代码,我选择不使用 html table dom 标签并使用 bootstrap改为构建我的 table 。主要是因为它允许我使用 vue 的 for 循环并从我在服务器 api 响应中获得的项目创建我的 table。我尝试并失败了 tables dom 布局 html tables 意味着我想在这里做的事情在 dom html table秒。

但这没关系,我有一个可用的 Boostrap table :

问题是让 x 和 y 滚动像上面的代码片段一样工作。

编辑:

我第一次尝试使用一个组件(代码段不 运行 可用,只是为了便于阅读而使用此标签):

.container{
  width: 600px;
  height: 200px;
  .container-content{

    .table-header {
      width: 1220px;
      overflow:hidden;
    }
    .table-body {
      .red{
        height: 5px;
        width: 1220px;
        background-color: red;
      }
      float:left;
      height: 150px;
      width: inherit;
      overflow-y: scroll;
      padding-right: 16px;
    }
  }
}
<template>
   <div id="database" class="content">
     <br/>
     <h3 class="left">Database :</h3>
     <hr/>
     <div class="container">
       <b-container fluid v-if="posts && posts.length" class="container-content">
         <b-row class="table-header" v-bind:ref="tableheader">
           <b-col><h5>Titre</h5></b-col>
           <b-col><h5>Version</h5></b-col>
           <b-col><h5>ID</h5></b-col>
           <b-col><h5>Mise à jour</h5></b-col>
           <b-col><h5>Présence</h5></b-col>
           <b-col><h5>Link</h5></b-col>
         </b-row>
         <hr/>
         <div class="table-body" v-bind:ref="tablebody" v-on:scroll="handleScroll()">
           <div class="red"></div>
         <b-row v-for="post of posts" key=uuid()>
           <b-col>
             <div>{{post.title.split(' ').slice(0, 1).join(' ')}}</div>
           </b-col>
           <b-col>
             <div>{{post.title.split(' ').slice(2).join(' ')}}</div>
           </b-col>
           <b-col>
             <div>{{post.title.split(' ').slice(1, 2).join(' ')}}</div>
           </b-col>
           <b-col>
             <div>{{post.updated}}</div>
           </b-col>
           <b-col>
             <div>{{post.display}}</div>
           </b-col>
           <b-col>
             <div>{{post.code}}</div>
           </b-col>
         </b-row>
         </div>
       </b-container>
     </div>
   </div>
</template>

<script>
  import axios from 'axios'
  export default {
    name: 'database',
    data () {
      return {
        posts: [],
        errors: []
      }
    },
    methods: {
      handleScroll () {
        console.log('scrolling')
        this.$$['tableheader'].scrollLeft = this.$$['tablebody'].scrollLeft
      }
    },
    created () {
      var token = 'JWT'
      axios.get(`http://localhost:3000/api/allergyintolerance/`, {headers: { 'Authorization': token }})
        .then(response => {
          this.posts = response.data.entry
        })
        .catch(e => {
          this.errors.push(e)
        })
    }
  }
</script>

我确实收到了控制台日志,但是有一个错误:

所以我想知道template下第一个div是不是只能有refs或者el?因此 per-component?

所以我尝试了几个组件(相同,只是为了便于阅读而使用了片段):

(Database.vue):

<template>
   <div id="database" class="content">
     <br/>
     <h3 class="left">Database :</h3>
     <hr/>
     <div class="container">
       <b-container class="container-content">
         <TableHeader/>
         <hr/>
         <TableBody/>
       </b-container>
     </div>
   </div>
</template>

<script>
  export default {
    name: 'database',

    methods: {
      handleScroll () {
        console.log('scrolling')
        document.ref['table-header'].scrollLeft = document.ref['table-body'].scrollLeft
      }
    }
  }
</script>

(TableHeader.vue) :

<template>
  <b-row id="table-header" class="table-header" v-bind:ref=tableheader>
    <b-col><h5>Titre</h5></b-col>
    <b-col><h5>Version</h5></b-col>
    <b-col><h5>ID</h5></b-col>
    <b-col><h5>Mise à jour</h5></b-col>
    <b-col><h5>Présence</h5></b-col>
    <b-col><h5>Link</h5></b-col>
  </b-row>
</template>

<script>
    export default {
      name: 'table-header'
    }
</script>
   

(TableBody.vue) :

<template>
  <div id="table-body" v-if="posts && posts.length" class="table-body" v-bind:ref=tablebody v-on:scroll="callParent()">
    <div class="red"></div>
    <b-row v-for="post of posts" key=uuid()>
      <b-col>
        <div>{{post.title.split(' ').slice(0, 1).join(' ')}}</div>
      </b-col>
      <b-col>
        <div>{{post.title.split(' ').slice(2).join(' ')}}</div>
      </b-col>
      <b-col>
        <div>{{post.title.split(' ').slice(1, 2).join(' ')}}</div>
      </b-col>
      <b-col>
        <div>{{post.updated}}</div>
      </b-col>
      <b-col>
        <div>{{post.display}}</div>
      </b-col>
      <b-col>
        <div>{{post.code}}</div>
      </b-col>
    </b-row>
  </div>
</template>

<script>
  import axios from 'axios'

  export default {
    name: 'table-body',
    data () {
      return {
        posts: [],
        errors: []
      }
    },
    methods: {
      callParent () {
        this.$parent.$options.methods.handleScroll()
      }
    },
    created () {
      var token = 'JWT'
      axios.get(`http://localhost:3000/api/allergyintolerance/`, {headers: { 'Authorization': token }})
        .then(response => {
          this.posts = response.data.entry
        })
        .catch(e => {
          this.errors.push(e)
        })
    }
  }
</script>

在视觉上和 chrome 控制台中的错误与上面的屏幕截图完全相同。

我也尝试过仅使用 id 声明和 this.$$['table-header'].scrollLeft = this.$$['table-body'].scrollLeft 但错误仍然存​​在。

我看到另一个我最终要 运行 解决的问题:我没能制作出容器大小的标题剪辑。

更新:

我用 : document.getElementById('table-header').scrollLeft = document.getElementById('table-body').scrollLeft 摆脱了错误,但仍然没有任何反应。

我应该放弃在 vuejs 中尝试这样做吗?

好的,所以完全删除 bootstrap 就是这里的解决方案:

SASS / SCSS :

.container-content{
    width: 600px;
    height: 200px;
    .table-header {
      width: inherit;
      overflow:hidden;
      div{
        width: 250px;
      }
    }
    .table-body {
      .red{
        height: 5px;
        width: 1220px;
        background-color: red;
      }
      float:left;
      height: 150px;
      width: inherit;
      overflow-y: scroll;
      padding-right: 16px;
    }
  }

(Database.vue) :

<template>
   <div id="database" class="content">
     <br/>
     <h3 class="left">Database :</h3>
     <hr/>
     <div class="container">
       <div class="container-content">
         <TableHeader/>
         <hr/>
         <TableBody/>
       </div>
     </div>
   </div>
</template>

<script>
  export default {
    name: 'database',

    methods: {
      handleScroll () {
        document.getElementById('tableheader').scrollLeft = document.getElementById('tablebody').scrollLeft
      }
    }
  }
</script>

(TableHeader.vue) :

<template>
  <div id="tableheader" class="table-header webkit">
    <div><h5>Titre</h5></div>
    <div><h5>Version</h5></div>
    <div><h5>ID</h5></div>
    <div><h5>Mise à jour</h5></div>
    <div><h5>Présence</h5></div>
    <div><h5>Link</h5></div>
  </div>
</template>

(TableBody.vue) :

<template>
  <div id="tablebody" v-if="posts && posts.length" class="table-body" v-on:scroll="callParent()">
    <div class="red"></div>
    <div v-for="post of posts" key=uuid() class="webkit">
      <div>
        <div>{{post.title.split(' ').slice(0, 1).join(' ')}}</div>
      </div>
      <div>
        <div>{{post.title.split(' ').slice(2).join(' ')}}</div>
      </div>
      <div>
        <div>{{post.title.split(' ').slice(1, 2).join(' ')}}</div>
      </div>
      <div>
        <div>{{post.updated}}</div>
      </div>
    </div>
  </div>
</template>

<script>
  import axios from 'axios'

  export default {
    name: 'table-body',
    data () {
      return {
        posts: [],
        errors: []
      }
    },
    methods: {
      callParent () {
        this.$parent.$options.methods.handleScroll()
      }
    },
    created () {
      var token = 'JWT'
      axios.get(`http://localhost:3000/api/allergyintolerance/`, {headers: { 'Authorization': token }})
        .then(response => {
          this.posts = response.data.entry
        })
        .catch(e => {
          this.errors.push(e)
        })
    }
  }
</script>