vue 与 dot 渲染表格 时间复杂度分析

    doT.js,用过的都知道,渲染表格贼快。doT.js特点是快,小,无依赖其他插件。压缩版仅有4K大小。

  1. dot的基本语法:
    {{= }} for interpolation
    {{ }} for evaluation
    {{~ }} for array iteration
    {{? }} for conditionals
    {{! }} for interpolation with encoding
    {{# }} for compile-time evaluation/includes and partials
    {{## #}} for compile-time defines
    是不是看着和vue有点像?
  2. dot的基本用法(基本上分为三个部分你就能运用到项目中):
    在.cshtml中:
    `

这部分就是单纯的写在一个js标签中,看着上面的id,必须为ID。然后,在你需要布局的地方写下<br>


`
这里就是挂载上面模板的地方

最后的就是在我们js获取数据源的地方,将请求过来的json数据与模板绑定到dot上

     var interText = doT.template($("#" + tmpName).text());
                        $("." + className).html(interText(res));

这样就能够渲染到界面上了,但dot里面没有排序,插件,搜索,就单单的渲染一个表格。
3. 同样的,用vue也做了一个表格渲染的模板,代码如下:

define(['Vue'], function(Vue){
    Vue.component('tra-common',{
        props:['it','list'],
        template: `
        <div class='componentContainer' v-if="it != null">
            <div class='fund-panel'>
            <div class="title">
                <span class="fund-title-inline">交易申请表</span>
            </div>
            <div class="fund-row">
                <div class="fund-col-6">
                    <div class="fund-selpanel-title fund-label fund-col-5">所属产品</div>
                    <div class="fund-col-7 spanStyle">
                        <span>{{it.FundName}} </span>
                    </div>
                </div>
                <div class="fund-col-6">
                    <div class="fund-selpanel-title fund-label fund-col-5">交易方式</div>
                    <div class="fund-col-7 spanStyle">
                        <span>{{it.TransactionMeans}} </span>
                    </div>
                </div>
            </div>
            <div class="fund-row">
                <div class="fund-col-6">
                    <div class="fund-selpanel-title fund-label fund-col-5">证券名称</div>
                    <div class="fund-col-7 spanStyle">
                        <span>{{it.SecurityName}} </span>
                    </div>
                </div>
                <div class="fund-col-6">
                    <div class="fund-selpanel-title fund-label fund-col-5">发行人性质</div>
                    <div class="fund-col-7 spanStyle">
                        <span>{{it.IssuerNature}} </span>
                    </div>
                </div>
            </div>
            <div class="fund-row">
                <div class="fund-col-6">
                    <div class="fund-selpanel-title fund-label fund-col-5">发行期代码</div>
                    <div class="fund-col-7 spanStyle">
                        <span>{{it.IssuingCode||"--"}} </span>
                    </div>
                </div>
                <div class="fund-col-6">
                    <div class="fund-selpanel-title fund-label fund-col-5">正式代码</div>
                    <div class="fund-col-7 spanStyle">
                        <span>{{it.SecurityCode||"--"}} </span>
                    </div>
                </div>
            </div>
            <div class="fund-row">
                <div class="fund-col-6">
                    <div class="fund-selpanel-title fund-label fund-col-5">资产类别</div>
                    <div class="fund-col-7 spanStyle">
                        <span>{{it.AssetClass}} </span>
                    </div>
                </div>
                <div class="fund-col-6">
                    <div class="fund-selpanel-title fund-label fund-col-5">主体评级</div>
                    <div class="fund-col-7 spanStyle">
                        <span>{{it.IssuerRating}} </span>
                    </div>
                </div>
            </div>
            <div class="fund-row">
                <div class="fund-col-6">
                    <div class="fund-selpanel-title fund-label fund-col-5">债券属性</div>
                    <div class="fund-col-7 spanStyle">
                        <span>{{it.WindIndustry}} </span>
                    </div>
                </div>
                <div class="fund-col-6">
                    <div class="fund-selpanel-title fund-label fund-col-5">债券评级</div>
                    <div class="fund-col-7 spanStyle">
                        <span>{{it.DebtRating||"--"}} </span>
                    </div>
                </div>
            </div>
            <div class="fund-row">
                <div class="fund-col-6">
                    <div class="fund-selpanel-title fund-label fund-col-5">票面利率</div>
                    <div class="fund-col-7 spanStyle">
                        <span>{{it.CouponRate}}</span>
                    </div>
                </div>
                <div class="fund-col-6">
                    <div class="fund-selpanel-title fund-label fund-col-5">存续期限</div>
                    <div class="fund-col-7 spanStyle">
                        <span>{{it.RemainTerm}} </span>
                    </div>
                </div>
            </div>
            <div class="fund-row">
                <div class="fund-col-6">
                    <div class="fund-selpanel-title fund-label fund-col-5">发行规模(亿元)</div>
                    <div class="fund-col-7 spanStyle">
                        <span>{{it.IssueScale}} </span>
                    </div>
                </div>
            </div>
            <div class="fund-row">
                <div class="fund-col-6">
                    <div class="fund-selpanel-title fund-label fund-col-5">买卖方向</div>
                    <div class="fund-col-7 spanStyle">
                        <span>{{it.TransactionDirection}} </span>
                    </div>
                </div>
                <div class="fund-col-6">
                    <div class="fund-selpanel-title fund-label fund-col-5">预计交易时间</div>
                    <div class="fund-col-7 spanStyle">
                        <span>{{it.EstimatedTransactionTime}} </span>
                    </div>
                </div>
            </div>
            <div class="fund-row">
                <div class="fund-col-6">
                    <div class="fund-selpanel-title fund-label fund-col-5">交易平台</div>
                    <div class="fund-col-7 spanStyle">
                        <span>{{it.TradingPlatform}} </span>
                    </div>
                </div>
                <div class="fund-col-6">
                    <div class="fund-selpanel-title fund-label fund-col-5">预计交易价格(元)</div>
                    <div class="fund-col-7 spanStyle">
                        <span>{{it.TransactionPriceMin}}-{{it.TransactionPriceMax}} </span>
                    </div>
                </div>
            </div>
            <div class="fund-row">
                <div class="fund-col-6">
                    <div class="fund-selpanel-title fund-label fund-col-5 ">预计交易规模(万元)</div>
                    <div class="fund-col-7 spanStyle">
                        <span>{{it.TransactionVolume}} </span>
                    </div>
                </div>
                <div class="fund-col-6">
                    <div class="fund-selpanel-title fund-label fund-col-5 ">收益率</div>
                    <div class="fund-col-7 spanStyle">
                        <span>{{it.YtmMin}}-{{it.YtmMax}} </span>
                    </div>
                </div>
            </div>
            <div class="fund-row">
                <div class="fund-col-6">
                    <div class="fund-selpanel-title fund-label fund-col-5">代持方式</div>
                    <div class="fund-col-7 spanStyle">
                        <span>{{it.AgreementMeans}} </span>
                    </div>
                </div>
            </div>
            <div class="fund-row">
                <div class="fund-col-6">
                    <div class="fund-selpanel-title fund-label fund-col-5">其他需要载明的事项</div>
                    <div class="fund-col-7 spanStyle ">
                        <span>{{it.Remarks}} </span>
                    </div>
                </div>
            </div>
            <div class="fund-row">
                <div class="fund-col-12">
                    <div class="fund-selpanel-title fund-label" style='width:210px;float:left'>附件</div>
                    <div class="fund-col-7 spanStyle">
                        <div>
                            <span v-if="list[0]==='--'">
                                {{list[0]}}
                            </span>
                            <span style = "margin-bottom:8px;display:inline-block" v-for="(item,index) in list" :key='index'>
                                <a class="fund-link" :href ="'/FileManage/FilePreview?fileid='+item.FileId"> {{item.FileName }}</a>
                            </span>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        <div class='fund-panel' style='margin-top:10px'>
            <div class="fund-row">
                <div class="title">
                    <span class="fund-title-inline">审核明细</span>
                </div>
            </div>
            <div v-if="it.ApplicationOperList.length>0">
                <div v-for="item in it.ApplicationOperList">
                    <div class="fund-row">
                        <div class="fund-col-6">
                            <div class="fund-selpanel-title fund-label fund-col-5 ">审核人</div>
                            <div class="fund-col-7 spanStyle">
                                <span>{{item.Operator}} </span>
                            </div>
                        </div>
                        <div class="fund-col-6">
                            <div class="fund-selpanel-title fund-label fund-col-5 ">审核时间</div>
                            <div class="fund-col-7 spanStyle">
                                <span>{{item.OperationTime}}</span>
                            </div>
                        </div>
                    </div>
                    <div class="fund-row">
                        <div class="fund-col-6">
                            <div class="fund-selpanel-title fund-label fund-col-5 ">审核结果</div>
                            <div class="fund-col-7 spanStyle">
                                <span>{{item.AuditResult}} </span>
                            </div>
                        </div>
                    </div>
                    <div class="fund-row">
                        <div class="fund-col-12">
                            <div class="fund-selpanel-title fund-label fund-col-2 ">审核意见</div>
                            <div class="fund-col-9 spanStyle" style='padding-left:42px'>
                                <span>{{item.AuditOpinion}}</span>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
            <div v-else>暂无审核意见</span></div>
        </div>
    </div>
    `
    }),
    Vue.component('fix-thead-table',{
        props:['datatable'],
        computed: {
            col:function(){
                return this.datatable.thead.length;
            },
            field:function(){
                return this.datatable.fields;
            },
            thead:function(){
                return this.datatable.thead;
            },
            tbody:function(){
                return this.datatable.tbody
            },
            theadWidth:function (param) {
                var Twidth=null;
                $.each(this.datatable.thead,function(index,value){
                    if(value.width){
                        Twidth +=value.width.split('p')[0]-0+10;
                    }   
                })
                return (Twidth+30)+"px"
            }
        },
        beforeCreate:function() {
            console.time("vue")
            console.time("Updata-vue")  
        },
        mounted:function () {
            console.timeEnd("vue")  
            console.log(1)
        },
        updated() {
            console.log(2)
            console.timeEnd("Updata-vue")  
        },
        template:`
        <div>
            <table class="fund-table thead" :style="{width:theadWidth}">
                <thead :class=''>
                    <tr>
                        <td v-for="item in thead" :style="{textAlign:item.align,width:item.width}">
                            {{item.title}}
                        </td>
                    </tr>
                </thead>
            </table>
            <div :style="{overflow:'auto',height:datatable.height,width:theadWidth,overflowX: 'hidden' }">
                <table class="fund-table tbody" :style="{width:theadWidth}">
                    <tbody>
                        //注意这里(第一种)↓
                        <tr v-for='item in tbody'>
                            <td> 
                             {{item.Category}}
                            </td><td> 
                            {{item.FromLogin}}
                           </td><td> 
                           {{item.Frequency}}
                          </td><td> 
                          {{item.Percent}}
                         </td>
                        </tr>
                        //注意这里↑
                        //注意这里(第二种)↓
                        <tr v-for='item in tbody'>
                        <td v-for = '(i,index) in thead' 
                        :style="{width:i.width,textAlign:i.align,overflow:'hidden',whiteSpace:'nowrap',textOverflow:'ellipsis'}">
                            <a v-if='item[i.link]↓↓▩' :href="item[i.link]">
                                {{item[i.field]}}
                            </a>
                            <span v-else>
                                {{item[i.field]}}
                            </span>
                        </td>
                    </tr>
                         //注意这里↑
                    </tbody>
                </table>
            </div>
        </div>
        `
    })
})

这是一个公用组件,写的是一个固定表头的table,传入一个表格的基本数据,然后渲染出来。没什么大问题,原来设想的是做一个datatables组件一样的东西,传入一些基本的数据就可以,实现自定义的配置出一个表格。比如td的宽度,text-align,thead,link地址。后来说是第二种方法双层循环会不会渲染很慢?后来就展开了一系列表格性能检测,先顺便展示一下vue生成表格的核心方法。

var app = new Vue({
                el:'#app',
                data:{
                    datatable:[{
                        thead:[{
                            title:'功能分类',
                            align:'left',
                            field:'Category',
                            width:"110px",
                            link :'Url'
                        },
                        {
                            title:'登录跳转次数',
                            align:'right',
                            field:'FromLogin',
                            width:"90px",
                        },
                        {
                            title:'频次',
                            align:'right',
                            field:'Frequency',
                            width:"105px",
                            link :'CountLink'
                        },{
                            title:'百分比',
                            align:'right',
                            field:'Percent',
                            width:"120px"
                        }],
                        tbody:{},
                        height:'264px'
                    }],
                        tbody:{}
                    }]
                },
                beforeCreate() {
                    console.time("data")
                },
                mounted() {
                    console.timeEnd("data")
                },
            })

这里的title就是表格的头部显示。field就是第一种方法中我们循环的时候需要的字段。通过
<tr v-for='item in tbody'> <td v-for = '(i,index) in thead' :style="{width:i.width,textAlign:i.align,overflow:'hidden',whiteSpace:'nowrap',textOverflow:'ellipsis'}"> <a v-if='item[i.link]↓↓▩' :href="item[i.link]"> {{item[i.field]}} </a> <span v-else> {{item[i.field]}} </span> </td> </tr>
双层循环动态的生成td,这样我们只需要配置好一个表格的基本属性,就可以动态的生成不定列表格。同样双层循环渲染td也带来了很大的时间消耗。

beforeCreate:function() {
            console.time("vue")
            console.time("Updata-vue")  
        },
        mounted:function () {
            console.timeEnd("vue")  
        },
        beforUpdata(){
            console.time("Updata2")  
        },
        updated() {
            console.timeEnd("Updata-vue")  
            console.timeEnd("Updata2")  
        },

这里就是说创建组件到挂载成功,以及更新数据渲染成功,分别打印出时间。
这里写图片描述
可以看到当加载组件是vue:1.9 ms,然后更新完data以后,重新渲染表格Updata-vue:56.7ms.我们再来看看dot的渲染时间:

 renderList: function (tmpName, className, res) {
                    
                    return new Promise(function (resolve, reject) {
                        console.time("dot")
                        var interText = doT.template($("#" + tmpName).text());
                        $("." + className).html(interText(res));
                        $(".behaviorAnalysis").unblock();
                        resolve();
                        console.timeEnd("dot")
                    });
                    
                },

代码是上面的,运行结果:这里写图片描述
这不是偶然结果,我运行了很多次,vue在挂载组件的时候可能很快,但按照我这样写的双循环去渲染td的时候就是很消耗时间了。但请看到最后–>

  • vue重点是在组件复用,数据交互,我同时应用了三次组件在一个el:#app下,同样,我也调用了dot的模板,做了三次表格渲染。界面数据条数是不一样的:这里写图片描述
    -这个是运行的结果
    这里写图片描述
    数据的多少对dot结果有影响,但这里我就有点不懂了
    这里写图片描述
    最后那个是beforeupdate-updated的时间。
    可以清楚的看到dot渲染的时间和数据列有关系,但对于vue来说,组件挂载了一次以后,后面的时间都成了0ms,可能是对vue了解的不多。 updata2都是0,这一点我以为它会每个组件渲染的时候都回去执行一次呢!!而且可以看到三个表格,结构都是不一样的。这是我这次code中不理解的地方,先记录下来。如果有哪位有耐心读到这里,多谢帮忙解惑!
  • 疑问的地方:vue的这个监听器我是可以理解,就是created到mounted,但后面的那两次vue:0ms是怎么回事,如果说组件只创建一次的话,那怎么就跑了三次监听器?也就是第一个红方框的那三个数据。
  • 还有后面的update-vue后面的两个怎么是0ms
  • updata-vue 这里时间这么长是代码写的有问题,还是vue这样用就需要这么长的时间?
  • //注意这里(第一种)↓ <tr v-for='item in tbody'> <td> {{item.Category}} </td><td> {{item.FromLogin}} </td><td> {{item.Frequency}} </td><td> {{item.Percent}} </td> </tr> //注意这里↑
    我曾把渲染的过程先用字段代替,不走双循环,需要的时间同样也是50多ms.
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值