• 前端框架 Vue 初探


    一、前言

    前几日使用微信网页版时,好奇这个网页用了什么前端框架。用Chrome的开发人员模式一探到底,发现原来用了一个名叫 Angular 的框架。好吧,既然微信用了。那我也最好还是看看。等等,你这篇文章的标题不是“初探Vue”吗?鬼扯什么Angular呢?

          好吧,我承认有些跑题。

    是的,我原本是要学着用Angular的,可是翻看网贴和资料后。发现有很多类似的框架,着力解决“在浏览器端怎样以优雅的方式动态生成html网页”的问题。当中就有前Google员工,咱大中华子民@youyuxi 尤小右同学开创的框架 Vue。

          OK,总算回到正题了。

          于是借着这个由头。翻看了一些对照各类流行前端框架优劣的文章。终于。我选择先拿 Vue 用用,试着改造我的部分已有业务。

          我选择Vue的原因是:它似乎可以优雅而且简单地解决我的问题——页面布局和数据模型可以有非常清晰的边界,而且可以以松散的方式结合或关联。这里还要插一句:我觉得前端的展现,最后能和js 百分百的兼容。

    我讨厌、反感使用jsp标签,使用s:iterator,使用el表达式!所以。可以使用js语法来实现渲染,是我梦寐以求的!

          好吧,实际体验又是怎样?

    二、列表的渲染

         当然,一般的体验都是关于Hello, world 怎样实现。

    但那个太0基础,我们直接上高级一些的。

          假如我有一个表格须要呈现。该怎样做?

          1. 首先要引入 vue 库的 js,參见后文链接;注意:开发期间一定要引入开发版,否则查起问题来全然找不到北。

          2. 要渲染的表格(略去table头),形如:

        <tbody id="dataList" >
    	<tr v-for="item in items" id="row_{{$index}}" >
      		<td>{{item.dataId}}</td>
      		<td>{{item.appKey}}</td>
                    ....
             </tr>
        </tbody>

        3. js的部分,须要创建 vue 对象,来关联DOM元素和数据。并终于实现数据同步。

         比方下面代码:

    	vueItems = new Vue({
    	  el: '#dataList',
    	  data: {
    	    items: [
    	    ]
    	  }
    	});
        4. OK。到眼下为止。我们的 vueItems 对象已经和 id 为 "dataList" 的 DOM 元素挂钩了。而且。通过在 html 里面 tr 一节的 "v-for" 属性。表明了要通过对 vueItems 对象的 数组元素进行遍历来渲染出表格的行数据。

         5. 因此,接下来就是往 vueItems.items 里面放入数据的过程。稍等一下,为何是 vueItems.items, 而不是 vlueItems.data.items 呢?假设你和我一样有这个想法。那么非常不幸你被误导了。构建 vue 对象时,传入的 对象的 data 属性,并不在兴许的 vue 对象中真实存在。

    要訪问数组的模型,必须用 vueItems.items。

         6. OK。不论数据来源于动态网页的生成过程,还是ajax 请求得到,总归会有一个 JS 的数组对象作为原始的数据。

    如果它就是 list 对象。那么。这时须要对list进行遍历。将list对象经过处理后。形成 vueItems 的真正用来渲染的数据。我的惯例是我宁愿用js来实现。而不愿意把这个过程放到模版里。

         所以就有类似下面的代码:

    for (var key in list) {
    		
    <span style="white-space:pre">	</span>var vueItem = {};
    		
    	var dataItem = list[key];
    		
    	vueItem.app_name = dataItem.app_name == null ?

    "--" : dataItem.app_name; vueItem.app_key = dataItem.app_key == "" ? "--" : dataItem.app_key; vueItem.consume_fund = dataItem.consume_fund / 1000; vueItem.reason = dataItem.reason == 0 ? "成功" : "错误码(" + dataItem.reason + ")"; vueItems.items.push(vueItem); }

    当中,最要紧的是就是最后一句 :

    vueItems.items.push(vueItem);

    这是Vue 这个框架奇妙的地方:将页面渲染的细节隐藏起来。代码简洁、优雅。

    我调试了代码,表格的行依照要求渲染出来,大功告成!除了有个细节以外,即包括 {{}}内容的模版行会显示一下,然后隐藏。这个好解决。就是把tbody先设为隐藏,等数据载入好了。再显示就可以。所以改进后的数据模版是这种:

        <tbody id="dataList" style="display:none;">
    	<tr v-for="item in items" id="row_{{$index}}" >
      		<td>{{item.dataId}}</td>
      		<td>{{item.appKey}}</td>
                    ....
             </tr>
        </tbody>
    然后js代码里要加上一句:

    $("#dataList").show();

           一切显得非常完美。

    正当我准备收工的时候,坏了。

    由此也引出下一个章节。


    三、意料之外的异常

    我突然发现,当我页面上的条件更改后。又一次获取数据,再次使用vue做渲染,结果竟然抛出了异常。

    这个异常不是在我的js里面抛出,而是在另外的线程。在 vue 的延时更新的定时器里抛出的。

    Uncaught TypeError: Cannot read property 'removeChild' of null
    	remove @ vue.js:1176
    	(anonymous function) @ vue.js:1028
    	applyTransition @ vue.js:1056
    	removeWithTransition @ vue.js:1027
    	singleRemove @ vue.js:4483
    	remove @ vue.js:4985
    	diff @ vue.js:4816
    	update @ vue.js:4728
    	Directive._bind._update @ vue.js:7708
    	Watcher.run @ vue.js:3257
    	runBatcherQueue @ vue.js:2990
    	flushBatcherQueue @ vue.js:2964
    	nextTickHandler @ vue.js:434

    看到这个错误,我一下傻了。

    老革命遇到新问题了。

    这,,。这框架怎么了?不是非常行的嘛?不是大牛开发的吗?。!

    我重复看了代码。没问题啊。难道真的是框架的问题。

    OK,我弄一个干净的列表的Demo,试试。

    结果,新做的Demo没问题。

    这下没辙了。又怀疑其它,,,,,,折腾了十几分钟。。。。

    。这里略去N字以及苦水若干升。

    绝望之中,我细致看了看这个异常的内容:Cannot read property 'removeChild' of null

    我似乎悟到一些什么。

    我一拍大腿。明确了。NND(我TM猪头啊,...这里又略去N字)。

    原来,我改造代码时。忘记将原先的一行代码去掉了,这行代码是直接訪问DOM将表格的数据清除。由于当用户再次点击查询时,须要将原数据删除。然后又一次append新的行。

    我将上述这句代码删除。这回最终OK 了!

    原来,在Vue里面。假设DOM元素已经绑定了Vue框架,则不能再通过DOM直接进行删除,必需要通过Vue的对象来删除。至少我使用的Vue 1.0.13 版本号是这个情况。

    好吧。切切!

    以后不能再犯这样的低级错误了。


    四、后记

    前述那个异常。究竟是要容错还是应该抛出异常?似乎容错也说得通。所以我将这个情况发了个推告知给作者。让他评估一下。由于时差的关系,他还没有回复我。

  • 相关阅读:
    转:Git: git stash 用法小结
    Checkbox: ListView 与CheckBox 触发事件冲突的问题
    android: getDimension, getDimensionPixelOffset 和getDimensionPixelSize 区别
    java: 保留两位小数4种方法
    java: 保留两位小数4种方法
    转:在eclipse中 使用7.0及以上手机进行测试时logcat不打印日志的解决办法
    转:Android文件存储路径getFilesDir()与getExternalFilesDir的区别
    Gradle-修改.gradle默认目录
    Windows: 打开关闭网络连接的方法
    dom4j: 生成XML时文本中回车换行无效
  • 原文地址:https://www.cnblogs.com/mfmdaoyou/p/7365231.html
Copyright © 2020-2023  润新知