iview的table中嵌套input,select等(附帶一個添加行,刪除行的功能)


最近要做一個table,里邊的內容比較特殊,全都是由下拉框和輸入框等構成的,看到網上大部分人都是通過用render函數解決的,因為之前使用過iview的可編輯表格功能,是通過slot實現的,嘗試着通過slot來

實現了下該功能,相比render,看起來友好多了。

不過還是有缺陷的,可以很明顯的看到下邊v-model中綁定的值,我並沒有從slot-scope中取出,綁定里邊的數據。而是選擇直接手動綁定了頁面的tableData,這是因為我發現如果使用scople中的row的數據綁定,會造成數據沒有辦法完成雙向的綁定,只能完成單向的,造成的結果就是,如果手動修改tableData數組中的值,頁面的值會發生改變,但是如果修改了頁面的輸入框的值,tableData的數據不會發生改變。

具體原因我認為多半是vue的單向數據流造成的,相同的情況之前在封裝組件的時候遇到過,之前的解決方法到這里沒有辦法使用。

如果有高手知道原因或者解決辦法,煩請不吝賜教。

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>iview example</title>
    <link rel="stylesheet" type="text/css" href="http://unpkg.com/view-design/dist/styles/iview.css">
    <script type="text/javascript" src="http://vuejs.org/js/vue.min.js"></script>
    <script type="text/javascript" src="http://unpkg.com/view-design/dist/iview.min.js"></script>
    <style type="text/css">
        .ivu-table-wrapper{
            overflow: visible;
        }
        .ivu-table th {
            text-align: center;
        }
        .ivu-table-cell{
            text-align: center;
        }
    </style>
</head>
<body>
<div id="app">
    
    <i-table :columns="tableHead" :data="tableData">
        
        <template slot-scope="scope" slot="date1">
          <date-picker type="datetime" v-model="tableData[scope.index].date1.value" style="width: 150px">
          </date-picker>
        </template>

        <template slot-scope="scope" slot="date2">
          <date-picker type="datetime" v-model="tableData[scope.index].date2.value" style="width: 150px">
          </date-picker>
        </template>

        <template slot-scope="scope" slot="select1">
            <i-select v-model="tableData[scope.index].select1.value" style="width:130px">
                <i-option v-for="item in scope.row.select1.cityList" :value="item.value" :key="item.value">{{ item.label }}</i-option>
            </i-select>
        </template>
        <template slot-scope="scope" slot="select2">
            <i-select v-model="tableData[scope.index].select2.value" style="width:130px">
                <i-option v-for="item in scope.row.select2.cityList" :value="item.value" :key="item.value">{{ item.label }}</i-option>
            </i-select>
        </template>
        <template slot-scope="scope" slot="select3">
            <i-select v-model="tableData[scope.index].select3.value" style="width:130px">
                <i-option v-for="item in scope.row.select3.cityList" :value="item.value" :key="item.value">{{ item.label }}</i-option>
            </i-select>
        </template>
        <template slot-scope="scope" slot="input1">
          <i-input ref="test" v-model="tableData[scope.index].input1.value"  style="width: 100px" >
          </i-input>
        </template>
        <template slot-scope="scope" slot="input2">
          <i-input v-model="tableData[scope.index].input2.value"  style="width: 100px" >
          </i-input>
        </template>
        <template slot-scope="scope" slot="input3">
          <i-input v-model="tableData[scope.index].input3.value"  style="width: 100px" >
          </i-input>
        </template>
        <template slot-scope="scope" slot="input4">
          <i-input v-model="tableData[scope.index].input4.value"  style="width: 100px" >
          </i-input>
        </template>
        <template slot-scope="scope" slot="input5">
          <i-input v-model="tableData[scope.index].input5.value"  style="width: 100px" >
          </i-input>
        </template>

   
    </i-table>
</div>
<script>
    window.vm = new Vue({
        el: '#app',
        data: {
            tableData: [
              /*測試數據一*/
              {
                date1: {
                    value : new Date()
                },
                date2: {
                    value : new Date()
                },
                select1: {
                    value:'',
                    cityList: [
                        {
                            value: 'New York',
                            label: 'New York'
                        },
                        {
                            value: 'London',
                            label: 'London'
                        }
                    ],
                },
                select2: {
                    value:'',
                    cityList: [
                        {
                            value: 'New York',
                            label: 'New York'
                        },
                        {
                            value: 'London',
                            label: 'London'
                        }
                    ],
                
                },
                select3: {
                    value:'',
                    cityList: [
                        {
                            value: 'train',
                            label: '火車'
                        },
                        {
                            value: 'plane',
                            label: '飛機'
                        },
                    ],
                
                },
                input1: {
                    value : '111'
                },
                input2: {
                    value : '111'
                },
                input3: {
                    value : '111'
                },
                input4: {
                    value : '111'
                },
                input5: {
                    value : '111'
                },
              },
              /*測試數據二*/
              {
                date1: {
                    value : new Date()
                },
                date2: {
                    value : new Date()
                },
                select1: {
                    value:'',
                    cityList: [
                        {
                            value: 'New York',
                            label: 'New York'
                        },
                        {
                            value: 'London',
                            label: 'London'
                        },
                    ],
                },
                select2: {
                    value:'',
                    cityList: [
                        {
                            value: 'New York',
                            label: 'New York'
                        },
                        {
                            value: 'London',
                            label: 'London'
                        },
                    ],
                
                },
                select3: {
                    value:'',
                    cityList: [
                        {
                            value: 'train',
                            label: '火車'
                        },
                        {
                            value: 'plane',
                            label: '飛機'
                        },
                    ],
                
                },
                input1: {
                    value : '222'
                },
                input2: {
                    value : '222'
                },
                input3: {
                    value : '222'
                },
                input4: {
                    value : '222'
                },
                input5: {
                    value : '222'
                },
              },
              /*測試數據三*/
              {
                date1: {
                    value : new Date()
                },
                date2: {
                    value : new Date()
                },
                select1: {
                    value:'',
                    cityList: [
                        {
                            value: 'New York',
                            label: 'New York'
                        },
                        {
                            value: 'London',
                            label: 'London'
                        },
                    ],
                },
                select2: {
                    value:'',
                    cityList: [
                        {
                            value: 'New York',
                            label: 'New York'
                        },
                        {
                            value: 'London',
                            label: 'London'
                        },
                    ],
                
                },
                select3: {
                    value:'',
                    cityList: [
                        {
                            value: 'train',
                            label: '火車'
                        },
                        {
                            value: 'plane',
                            label: '飛機'
                        },
                    ],
                
                },
                input1: {
                    value : '333'
                },
                input2: {
                    value : '333'
                },
                input3: {
                    value : '333'
                },
                input4: {
                    value : '333'
                },
                input5: {
                    value : '333'
                },
              },
            ],
            tableHead: [{title:"出發日期",slot:"date1",width:"170"},{title:"結束日期",slot:"date2",width:"170"},{title:"出發地",slot:"select1"},{title:"目的地",slot:"select2"},{title:"交通工具",slot:"select3"},{title:"項目代碼",slot:"input1"},{title:"出差公司名稱及地址",slot:"input2"},{title:"出差目的",slot:"input3"},{title:"隨行人員",slot:"input4"},{title:"備注",slot:"input5"}]
        },
        created:function(){
        },
        methods: {
            getData : function(){
                let that = this;
                for(let i=0;i<that.tableData.length;i++){
                    let row = that.tableData[i];
                    let str = ''+i+'行的數據為';
                    for(let key in row){
                        if(typeof row[key].value != "undefined"){
                            str += row[key].value+"   ";
                        }
                    }
                    console.log(str);
                }

            }
        }
    })
  </script>
</body>
</html>

代碼中,寫了一個簡單的取數據的方法,運行結果如下圖:

 

另外,基於前邊的功能也完成了一個添加一行,刪除一行的功能,通過render函數寫出來的,代碼如下:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>iview example</title>
    <link rel="stylesheet" type="text/css" href="http://unpkg.com/view-design/dist/styles/iview.css">
    <script type="text/javascript" src="http://vuejs.org/js/vue.min.js"></script>
    <script type="text/javascript" src="http://unpkg.com/view-design/dist/iview.min.js"></script>
    <style type="text/css">
        .ivu-table-wrapper{
            overflow: visible;
        }
        .ivu-table th {
            text-align: center;
        }
        .ivu-table-cell{
            text-align: center;
        }
    </style>
</head>
<body>
<div id="app">
    
    <i-table :columns="tableHead" :data="tableData">
        
        <template slot-scope="scope" slot="date1">
          <date-picker type="datetime" v-model="tableData[scope.index].date1.value" style="width: 150px">
          </date-picker>
        </template>

        <template slot-scope="scope" slot="date2">
          <date-picker type="datetime" v-model="tableData[scope.index].date2.value" style="width: 150px">
          </date-picker>
        </template>

        <template slot-scope="scope" slot="select1">
            <i-select v-model="tableData[scope.index].select1.value" style="width:130px">
                <i-option v-for="item in scope.row.select1.cityList" :value="item.value" :key="item.value">{{ item.label }}</i-option>
            </i-select>
        </template>
        <template slot-scope="scope" slot="select2">
            <i-select v-model="tableData[scope.index].select2.value" style="width:130px">
                <i-option v-for="item in scope.row.select2.cityList" :value="item.value" :key="item.value">{{ item.label }}</i-option>
            </i-select>
        </template>
        <template slot-scope="scope" slot="input1">
          <i-input ref="test" v-model="tableData[scope.index].input1.value"  style="width: 100px" >
          </i-input>
        </template>
        <template slot-scope="scope" slot="input2">
          <i-input v-model="tableData[scope.index].input2.value"  style="width: 100px" >
          </i-input>
        </template>
        <template slot-scope="scope" slot="input3">
          <i-input v-model="tableData[scope.index].input3.value"  style="width: 100px" >
          </i-input>
        </template>

   
    </i-table>
</div>
<script>
    window.vm = new Vue({
        el: '#app',
        data: {
            tableData: [
              /*測試數據一*/
              {
                date1: {
                    value : new Date()
                },
                date2: {
                    value : new Date()
                },
                select1: {
                    value:'',
                    cityList: [
                        {
                            value: 'New York',
                            label: 'New York'
                        },
                        {
                            value: 'London',
                            label: 'London'
                        },
                    ],
                },
                select2: {
                    value:'',
                    cityList: [
                        {
                            value: 'train',
                            label: '火車'
                        },
                        {
                            value: 'plane',
                            label: '飛機'
                        },
                    ],
                
                },
                input1: {
                    value : ''
                },
                input2: {
                    value : ''
                },
                input3: {
                    value : ''
                }
              },
              /*測試數據二*/
              {
                date1: {
                    value : new Date()
                },
                date2: {
                    value : new Date()
                },
                select1: {
                    value:'',
                    cityList: [
                        {
                            value: 'New York',
                            label: 'New York'
                        },
                        {
                            value: 'London',
                            label: 'London'
                        },
                    ],
                },
                select2: {
                    value:'',
                    cityList: [
                        {
                            value: 'train',
                            label: '火車'
                        },
                        {
                            value: 'plane',
                            label: '飛機'
                        },
                    ],
                
                },
                input1: {
                    value : ''
                },
                input2: {
                    value : ''
                },
                input3: {
                    value : ''
                }
              },
            ],
            //表頭相關數據
            tableHead: [
                {title:"出發日期",slot:"date1"},
                {title:"結束日期",slot:"date2"},
                {title:"出發地",slot:"select1"},
                {title:"交通工具",slot:"select2"},
                {title:"出差目的",slot:"input1"},
                {title:"隨行人員",slot:"input2"},
                {title:"備注",slot:"input3"},
                {title:"操作列"}
            ]
        },
        created:function(){
            //最后一列需要使用render函數加一列,添加數據或刪除數據使用
            let header = this.tableHead;
            //列頭添加一個+號用於添加行
            header[header.length-1].renderHeader = function(column,data){
                return column('Icon',{
                        props: {
                            type: 'md-add'
                        },
                        style: {
                            fontSize: "25px",
                            fontWeight: "bolder",
                            color: "blue",
                            cursor:"pointer"
                        },
                        on:{
                            click:function(){ // 點擊事件(新增一行)
                                vm.tblRowAdd();
                            }
                        }
                    })
            }
            //列頭添加一個-號用於刪除行
            header[header.length-1].render = function(column,data){
                return column('Icon',{
                            props: {
                                type: 'md-remove'
                            },
                            style: {
                                fontSize: "25px",
                                fontWeight: "bolder",
                                color: "red",
                                cursor:"pointer"
                            },
                            on:{
                                click:function(){ // 點擊事件(刪除一行)
                                    vm.tblRowDel(data.index);
                                }
                            }
                        }
                    )
            }
        },
        methods: {
            getData : function(){
                let that = this;
                for(let i=0;i<that.tableData.length;i++){
                    let row = that.tableData[i];
                    let str = ''+i+'行的數據為';
                    for(let key in row){
                        if(typeof row[key].value != "undefined"){
                            str += row[key].value+"   ";
                        }
                    }
                    console.log(str);
                }
            },
            //添加一行的方法
            tblRowAdd : function(){
                let row = vm.tableData[0];
                let newRow = JSON.parse(JSON.stringify(row));
                for(let key in newRow){
                    newRow[key].value = "";
                }
                vm.tableData.push(newRow);    
            },
            tblRowDel : function(index){
                if(vm.tableData.length<=1){
                    alert("至少留一行,如果一行都不存在,添加行的方法會有問題!");
                    return false;
                }
                vm.tableData.splice(index,1);
            }
        }
    })
  </script>
</body>
</html>

效果圖:

 

 原理很簡單,在table綁定的列中添加一列,這一列就是單獨為了添加按鈕用的,然后通過renderHead來渲染列頭,render來渲染每行的末尾,就這樣,不懂的可以留言!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM