diff --git a/src/components/table/cell.vue b/src/components/table/cell.vue
new file mode 100644
index 0000000..1fa8a1f
--- /dev/null
+++ b/src/components/table/cell.vue
@@ -0,0 +1,68 @@
+<template>
+    <div :class="[prefixCls + '-cell']">
+        <template v-if="renderType === 'index'">{{index + 1}}</template>
+        <template v-if="renderType === 'normal'">{{{ row[column.key] }}}</template>
+    </div>
+</template>
+<script>
+    export default {
+        props: {
+            prefixCls: String,
+            row: Object,
+            column: Object,
+            index: Number
+        },
+        data () {
+            return {
+                renderType: '',
+                uid: -1
+            }
+        },
+        methods: {
+            compile () {
+                if (this.column.render) {
+                    const template = this.column.render(this.row, this.column, this.index);
+                    const cell = document.createElement('div');
+                    cell.innerHTML = template;
+                    const _oldParentChildLen = this.$parent.$parent.$children.length;
+                    this.$parent.$parent.$compile(cell);
+                    const _newParentChildLen = this.$parent.$parent.$children.length;
+
+                    if (_oldParentChildLen !== _newParentChildLen) {    // if render normal html node, do not tag
+                        this.uid = this.$parent.$parent.$children[this.$parent.$parent.$children.length - 1]._uid;    // tag it, and delete when data or columns update
+                    }
+                    this.$el.innerHTML = '';
+                    this.$el.appendChild(cell);
+                }
+            },
+            destroy () {
+                for (let i = 0; i < this.$parent.$parent.$children.length; i++) {
+                    if (this.$parent.$parent.$children[i]._uid === this.uid) {
+                        this.$parent.$parent.$children[i].$destroy();
+                    }
+                }
+            }
+        },
+        compiled () {
+            if (this.column.type === 'index') {
+                this.renderType = 'index';
+            } else if (this.column.render) {
+                this.renderType = 'render';
+            } else {
+                this.renderType = 'normal';
+            }
+        },
+        ready () {
+            this.compile();
+        },
+        beforeDestroy () {
+            this.destroy();
+        },
+        watch: {
+            index () {
+                this.destroy();
+                this.compile();
+            }
+        }
+    }
+</script>
\ No newline at end of file
diff --git a/src/components/table/table.vue b/src/components/table/table.vue
index c416f77..efc7b05 100644
--- a/src/components/table/table.vue
+++ b/src/components/table/table.vue
@@ -26,12 +26,19 @@
                         @mouseleave.stop="handleMouseOut(index)"
                         @click.stop="highlightCurrentRow(index)">
                         <td v-for="column in cloneColumns" :class="alignCls(column)">
-                            <div :class="[prefixCls + '-cell']">
-                                <template v-if="column.type === 'selection'">
-                                    <Checkbox :checked="cloneData[index] && cloneData[index]._isChecked" @on-change="toggleSelect(index)"></Checkbox>
-                                </template>
-                                <template v-else>{{{ renderRow(row, column, index) }}}</template>
+                            <div :class="[prefixCls + '-cell']" v-if="column.type === 'selection'">
+                                <Checkbox :checked="cloneData[index] && cloneData[index]._isChecked" @on-change="toggleSelect(index)"></Checkbox>
                             </div>
+                            <Cell v-else :prefix-cls="prefixCls" :row="row" :column="column" :index="index"></Cell>
+                            <!--<div :class="[prefixCls + '-cell']" v-else>-->
+                                <!--{{{ renderRow(row, column, index) }}}-->
+                            <!--</div>-->
+                            <!--<div :class="[prefixCls + '-cell']">-->
+                                <!--<template v-if="column.type === 'selection'">-->
+                                    <!--<Checkbox :checked="cloneData[index] && cloneData[index]._isChecked" @on-change="toggleSelect(index)"></Checkbox>-->
+                                <!--</template>-->
+                                <!--<template v-else>{{{ renderRow(row, column, index) }}}</template>-->
+                            <!--</div>-->
                         </td>
                     </tr>
                 </tbody>
@@ -49,13 +56,14 @@
 <script>
     import TableHead from './table-head.vue';
     import Checkbox from '../checkbox/checkbox.vue';
+    import Cell from './cell.vue';
     import Mixin from './mixin';
     import { oneOf, getStyle, deepCopy } from '../../utils/assist';
     const prefixCls = 'ivu-table';
 
     export default {
         mixins: [ Mixin ],
-        components: { TableHead, Checkbox },
+        components: { TableHead, Checkbox, Cell },
         props: {
             data: {
                 type: Array,
@@ -108,6 +116,9 @@
                 compiledUids: [],
                 cloneData: deepCopy(this.data),
                 cloneColumns: deepCopy(this.columns),
+                leftFixedColumns: [],
+                rightFixedColumns: [],
+                centerColumns: [],
                 showSlotHeader: true,
                 showSlotFooter: true,
                 bodyHeight: 0
@@ -147,53 +158,25 @@
             rowClsName (index) {
                 return this.rowClassName(this.data[index], index);
             },
-            renderRow (row, column, index) {
-                return column.type === 'index' ? index + 1 : column.render ? '' : row[column.key];
-            },
-            compileRender (update = false) {
+            handleResize () {
                 this.$nextTick(() => {
-                    if (update) {
-                        for (let i = 0; i < this.$parent.$children.length; i++) {
-                            const index = this.compiledUids.indexOf(this.$parent.$children[i]._uid);
-                            if (index > -1) {
-                                this.$parent.$children[i].$destroy();
-                                this.compiledUids.splice(index, 1);
-                                i--;
-                            }
-                        }
+                    const allWidth = !this.columns.some(cell => !cell.width);
+                    if (allWidth) {
+                        this.tableWidth = this.columns.map(cell => cell.width).reduce((a, b) => a + b);
+                    } else {
+                        this.tableWidth = parseInt(getStyle(this.$el, 'width')) - 1;
                     }
-
-                    const $el = this.$els.render;
-                    for (let i = 0; i < this.cloneColumns.length; i++) {
-                        const column = this.cloneColumns[i];
-                        if (column.render) {
-                            for (let j = 0; j < this.data.length; j++) {
-                                // todo 做一个缓存,只在需要改render时再重新编译,data改变时不用再编译
-                                const row = this.data[j];
-                                const template = column.render(row, column, j);
-                                const cell = document.createElement('div');
-                                cell.innerHTML = template;
-                                const _oldParentChildLen = this.$parent.$children.length;
-                                this.$parent.$compile(cell);
-                                const _newParentChildLen = this.$parent.$children.length;
-
-                                if (_oldParentChildLen !== _newParentChildLen) {    // if render normal html node, do not tag
-                                    this.compiledUids.push(this.$parent.$children[this.$parent.$children.length - 1]._uid);    // tag it, and delete when data or columns update
-                                }
-                                $el.children[j].children[i].children[0].innerHTML = '';
-                                $el.children[j].children[i].children[0].appendChild(cell);
+                    this.$nextTick(() => {
+                        this.columnsWidth = [];
+                        let autoWidthIndex = -1
+                        if (allWidth) autoWidthIndex = this.cloneColumns.findIndex(cell => !cell.width);
+                        this.$els.tbody.querySelectorAll('tbody tr')[0].querySelectorAll('td').forEach((cell, index) => {
+                            if (index === autoWidthIndex) {
+                                this.columnsWidth.push(parseInt(getStyle(cell, 'width')) - 1);
+                            } else {
+                                this.columnsWidth.push(parseInt(getStyle(cell, 'width')));
                             }
-                        }
-                    }
-                    this.handleResize();
-                });
-            },
-            handleResize () {
-                this.tableWidth = parseInt(getStyle(this.$el, 'width'));
-                this.$nextTick(() => {
-                    this.columnsWidth = [];
-                    this.$els.tbody.querySelectorAll('tbody tr')[0].querySelectorAll('td').forEach((cell) => {
-                        this.columnsWidth.push(parseInt(getStyle(cell, 'width')));
+                        });
                     });
                 });
             },
@@ -282,6 +265,9 @@
                         center.push(col);
                     }
                 });
+                this.leftFixedColumns = left;
+                this.rightFixedColumns = right;
+                this.centerColumns = center;
                 this.cloneColumns = left.concat(center).concat(right);
             }
         },
@@ -291,7 +277,7 @@
             this.showSlotFooter = this.$els.footer.innerHTML.replace(/\n/g, '').replace(/<!--[\w\W\r\n]*?-->/gmi, '') !== '';
         },
         ready () {
-            this.compileRender();
+            this.handleResize();
             this.fixedHeader();
             window.addEventListener('resize', this.handleResize, false);
         },
@@ -302,14 +288,14 @@
             data: {
                 handler () {
                     this.cloneData = deepCopy(this.data);
-                    this.compileRender(true);
+                    this.handleResize();
                 },
                 deep: true
             },
             columns: {
                 handler () {
                     this.parseColumns();
-                    this.compileRender(true);
+                    this.handleResize();
                 },
                 deep: true
             },
diff --git a/src/styles/components/table.less b/src/styles/components/table.less
index f8d35df..30f0c83 100644
--- a/src/styles/components/table.less
+++ b/src/styles/components/table.less
@@ -9,10 +9,33 @@
     background-color: #fff;
     border: 1px solid @border-color-base;
     border-bottom: 0;
+    border-right: 0;
     border-collapse: collapse;
     box-sizing: border-box;
     position: relative;
 
+    &:before{
+        content: '';
+        width: 100%;
+        height: 1px;
+        position: absolute;
+        left: 0;
+        bottom: 0;
+        background-color: @border-color-base;
+        z-index: 1;
+    }
+
+    &:after{
+        content: '';
+        width: 1px;
+        height: 100%;
+        position: absolute;
+        top: 0;
+        right: 0;
+        background-color: @border-color-base;
+        z-index: 1;
+    }
+
     &-with-header{
         border-radius: @border-radius-base @border-radius-base 0 0;
     }
@@ -36,8 +59,9 @@
     }
 
     &-body{
-        overflow-x: hidden;
-        overflow-y: auto;
+        //overflow-x: hidden;
+        //overflow-y: auto;
+        overflow: auto;
         position: relative;
     }
 
@@ -91,7 +115,8 @@
     }
 
     & table{
-        width: 100%;
+        //width: 100%;
+        table-layout: fixed;
     }
     &-border{
         th,td{
diff --git a/test/routers/table.vue b/test/routers/table.vue
index b1af924..7be2d62 100644
--- a/test/routers/table.vue
+++ b/test/routers/table.vue
@@ -8,6 +8,7 @@
         <!--<i-table size="large" border stripe :columns="columns" :data="data"></i-table>-->
         <br>
         <i-table
+                style="width:450px"
                 border
                 highlight-row
                 :columns="columns"
@@ -57,7 +58,7 @@
                         title: '地址',
                         key: 'address',
                         align: 'center',
-//                        width: 100
+                        width: 100,
 //                        render (row, column, index) {
 //                            if (row.edit) {
 //                                return `<i-input :value.sync="data[${index}].name"></i-input>`;
@@ -72,7 +73,8 @@
                         fixed: 'right',
                         width: 200,
                         render (row, column, index) {
-                            return `<i-button @click="edit(${index})">编辑</i-button>`
+                            return `<i-button @click="edit(${index})">${row.name}</i-button>`
+//                            return `<a>${row.name}</a>`
                         }
                     }
                 ],
@@ -140,14 +142,16 @@
         },
         ready () {
             setTimeout(() => {
+                return;
 //                this.height = 150;
-                return
-                this.data.push({
-                    name: '刘天娇2',
-                    age: 272,
-                    address: '北京市东城区2',
-                    edit: false
-                });
+//                return
+//                this.data.push({
+//                    name: '刘天娇2',
+//                    age: 272,
+//                    address: '北京市东城区2',
+//                    edit: false
+//                });
+                this.data.splice(1, 1)
             }, 1000);
         }
     }
--
libgit2 0.21.4