• 东航电商前端技术周刊第一期20180601


    这期我们分享如下:

    1.计算金额的小数点怎么才能精准呢?

    2.如何才是正确的比较浮点数的姿势呢?

    3.日历的天数怎么算呢?

    4.JS切面编程之AOP

    5.文本的省略号怎么用css实现?

    6.超出文本的省略号怎么用js实现?

    7.Vue加载变量会闪屏,怎么破?不怕,我有“v-cloak”!

    8.Vue 中为什么使用nextTick,此机制又是如何运作的?

    9.Vue重构-动态组件的创建

     

    ---------------------------------------------------我啥也没说---------------------------------------------------

    闲话不多说,开!始!上!干!货!

    1.计算金额的小数点怎么才能精准呢?

    现实开发当中,我们总是会遇到金额计算问题,
    我们本以为js中0.1+0.2=0.3,结果0.300000000000000004(喵喵喵?我是谁?我在哪 ?怎么多出这么多小尾巴?)

    所以我们显示金额数值的时候,经常会不准,测试经常会提这样有多个小数点的bug,

    遇到这样的问题我们该怎么办?

    解决办法:
    把小数先装成整数计算。比如(0.1*100+0.2*100)/100 = 0.3 ,正确 ✔
    原因:为什么0.1+0.2!=0.3?
    这是因为计算机的计算原因就是先把数值转成二进制,再进行计算,

    所以计算机无法把0.1转成一个有限位数的二进制,而是转成一个跟0.1相近的二进制,

    所以0.1和0.2求和(或者求积)会出现偏差。

    总结:js当中只要涉及到小数点的计算,都必须先转成整数进行计算。

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~感谢孙爱祥老师热情分享~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    2.如何才是正确的比较浮点数的姿势呢? 

    之前已经讲过由于计算机将数值转换成二进制进行比较,

    下例中计算结果与预期并不一致:

    var a = 0.1 + 0.2, b = 0.5 - 0.2;
    a === b // false

    那么如何才是正确的比较浮点数的姿势呢?(假装很认真的思考。。)

    可以通过比较机器精度,确定浮点数是否相等

    if(!Number.EPSILON) {
    Number.EPSILON = Math.pow(2, -52);
    }
    function numberCloseEnoughToEqual(n1, n2) {
    return Math.abs(n1 - n2) < Number.EPSILON;
    }
    var a = 0.1 + 0.2, b = 0.5 - 0.2;
    numberCloseEnoughToEqual(a, b); //true

    需要特别说明的是Number.EPSILON是ES6提供的常量,(敲黑板!)

    可以用来设置浮点运算允许的误差值,

    Number.EPSILON属性的值接近于 2.2204460492503130808472633361816E-16,或者 2-52。

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~感谢严明坤老师情分享~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

     3.日历的天数怎么算呢?

    这次分享内容是项目日历需求,计算某月有多少天的计算代码方法,源码见附件。希望对小伙伴们有用(笔芯.gif)

    不善言辞,上代码!!!

    Function getLastDay(year,month) {
            var new_year = year;    //取当前的年份
            var new_month = month++;//取下一个月的第一天,方便计算(最后一天不固定)
            if (month > 12)            //如果当前大于12月,则年份转到下一年
            {
                new_month -= 12;        //月份减
                new_year++;            //年份增
            }
            var new_date = new Date(new_year, new_month, 1);                //取当年当月中的第一天
            var date_count = (new Date(new_date.getTime() - 1000 * 60 * 60 * 24)).getDate();//获取当月的天数
            var last_date = new Date(new_date.getTime() - 1000 * 60 * 60 * 24);//获得当月最后一天的日期
            return date_count;
        }

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~感谢唐雪峰老师热情分享~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    4.JS切面编程之AOP

    我什么也不说,你看了就会懂,就是这么自信(自信的微笑.jpg)

    <div>
        用户名:<input id="username" type="text"/>
    
        密码: <input id="password" type="password"/>
        <input id="submitBtn" type="button" value="提交"></button>
    </div>
    <script type="text/javascript">
    
        //后端开发中的AOP思想,同样可以应用在前端开发中
    
        
        Function.prototype.before = function( beforefn ){
            // 保存原函数的引用
            var __self = this; 
    
            return function(){
                // 执行新函数,新函数在原函数之前执行,且保证this 不被劫持,新函数接受的参数
                beforefn.apply( this, arguments ); 
                // 执行原函数并返回原函数的执行结果,
                return __self.apply( this, arguments ); 
        }
    }
    
        //同理
        Function.prototype.after = function( afterfn ){
            var __self = this;
            return function(){
                var ret = __self.apply( this, arguments );
                afterfn.apply( this, arguments );
                return ret;
            }
        };
    
    </script>
    <script>
    
        //应用场景
        var username = document.getElementById( 'username' ),
        password = document.getElementById( 'password' ),
        submitBtn = document.getElementById( 'submitBtn' );
    
        Function.prototype.before = function( beforefn ){
            var __self = this;
            return function(){
                if ( beforefn.apply( this, arguments ) === false ){
                    // beforefn 返回false 的情况直接return,不再执行后面的原函数
                    return;
                }
                return __self.apply( this, arguments );
            }
        }
        var validata = function(){
            if ( username.value === '' ){
                alert ( '用户名不能为空' );
                return false;
            }
            if ( password.value === '' ){
                alert ( '密码不能为空' );
                return false;
            }
        }
        var formSubmit = function(){
            var param = {
                username: username.value,
                password: password.value
            }
            ajax( 'http:// xxx.com/login', param );
        }
    
        formSubmit = formSubmit.before( validata );
    
        submitBtn.onclick = function(){
            formSubmit();
        }
        
    </script>

    不信,可以比划比划!

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~感谢李忠国老师热情分享~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    5.文本的省略号怎么用css实现?

    固定宽高,多行实现省略号,嗯,小问题啦~

    200px;
    height:50px;
    overflow : hidden;
    text-overflow: ellipsis;
    word-break: break-word
    display: -webkit-box;
    -webkit-line-clamp: 2;//自己设置的行数
    -webkit-box-orient: vertical;

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~感谢于志平老师热情分享~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    6.超出文本的省略号怎么用js实现?

    如果不能用css来控制省略号,那就用js啦。

    省略号君,我!们!不!怕!

    html:

     <div class="dome">偷偷ce试 一下 enmmmmm</div>

    js:

      tips:

      str: 要截取的字符串
      length:要截取的长度,这里我们取了18个
      insert:截取后,剩下字符用“...”替换
    //计算字符长度
    function GetLeng(str){
    var realLength = 0, len = str.length, charCode = -1;
    for (var i = 0; i < len; i++) {
    charCode = str.charCodeAt(i);
    if (charCode >= 0 && charCode <= 128) realLength += 1;
    else realLength += 2;
    }
    return realLength;
    }
    //截取方法
    function CutStr(str,length,insert){
    if(!str) return "";
    if(length<= 0) return "";
    if(!insert) insert = "";
    var templen=0;
    for(var i=0;i<str.length;i++){
    if(str.charCodeAt(i)>255){
    templen+=2;
    }else{
    templen++
    }
    if(templen == length){
    return str.substring(0,i+1)+insert;
    }else if(templen >length){
    return str.substring(0,i)+insert;
    }
    }
    return str;
    }
    //小使身手
    var domeText=$(".dome").text(),
    domeTextLength = GetLeng(domeText);
    if(domeTextLength>18){
    $(".dome").text(CutStr(domeText, 18, '...'))

    }

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~感谢何玉老师热情分享~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

     7.Vue加载变量会闪屏,怎么破?不怕,我有“v-cloak”!

    在使用vue绑定数据的时候,渲染页面时会出现变量闪烁(啊,闪到我的卡姿兰大了眼睛!)

    例如

    <div class="#app">
    <p>{{value.name}}</p>
    </div>

    在加载的时候会看到

    {{value.name}}

    在页面出现,过了几秒之后才会渲染数据,

    在vue中有个指令可以解决这个问题,v-cloak

    那么,v-cloak要放在什么位置呢?

    是不是每个需要渲染数据的标签都要添加这个指令?(敲黑板,划重点啦!)

    经过试验发现,v-cloak并不需要添加到每个标签,只要在el挂载的标签上添加就可以,这个指令可以隐藏未编译的Mustache 标签直到实例准备完毕。

    <div class="#app" v-cloak>
    <p>{{value.name}}</p>
    </div>

    而且,在css里面要添加

    [v-cloak] {
    display: none;
    }

    这样就可以防止页面闪烁了。

    但是有的时候会不起作用,可能的原因有二

    1、v-cloak的display属性被层级更高的给覆盖掉了,所以要提高层级

    [v-cloak] {
    display: none !important;
    }

    2、样式放在了@import引入的css文件中

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~感谢于志平老师热情分享~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    8.Vue中为什么使用nextTick,此机制又是如何运作的? 

    1、定义[nextTick、事件循环]

    Vue官网对它的解释是:在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。

    我认为这样解释更简单易懂:在同一事件循环中的数据变化后,DOM完成更新,立即执行nextTick(callback)内的回调

    2、应用场景:

    在Vue生命周期的created()钩子函数进行的DOM操作一定要放在Vue.nextTick()的回调函数中;

    3、了解nextTick中定义的三个重要变量:

    callbacks:用来存储所有需要执行的回调函数;

    pending:用来标志是否正在执行回调函数;

    timerFunc:用来触发执行回调函数;

    4、其次了解nextTickHandler()函数:

    先判断是否原生支持promise,如果支持,则利用promise来触发执行回调函数;

    否则,如果支持MutationObserver,则实例化一个观察者对象,观察文本节点发生变化时,触发执行所有回调函数。

    如果都不支持,则利用setTimeout设置延时为0。

    5、nextTick实际运用实例

    <ul id="demo">
        <li v-for="item in list">{{item}}</div>
    </ul>
    new Vue({
    el:'#demo',
    data:{
    list=[0,1,2,3,4,5,6,7,8,9,10]
    },
    methods:{
    push:function(){
    this.list.push(11);
    this.nextTick(function(){
    alert('数据已经更新')
    });
    this.$nextTick(function(){
    alert('v-for渲染已经完成')
    })
    }
    }})

    或者:

    this.$http.post(apiUrl)
    .then((response) => {
    if (response.data.success) {
    this.topFocus.data = response.data.data;
    this.$nextTick(function(){
    //渲染完毕
    });
    }
    }).catch(function(response) {
    console.log(response);
    });

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~感谢许亚男老师热情分享~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    9.Vue重构-动态组件的创建

     1、component 和is配合使用

    通过使用保留的 元素,并对其 is 特性进行动态绑定,你可以在同一个挂载点动态切换多个组件:
    实例如下:
    var vm = new Vue({
    el: '#example',
    data: {
    currentView: 'home'
    },
    components: {
    home: { /* ... */ },
    posts: { /* ... */ },
    archive: { /* ... */ }
    }
    })
    <component v-bind:is="currentView">
        <!-- 组件在 vm.currentview 变化时改变! -->
    </component>

       2、方法二:通过render方法创建

    <script>
        export default {
            data() {
                return {
                };
            },
            render: function(createElement) {
                let _type = bi.chart.data.type;
                let _attr = bi.chart.components[_type]["attr"];
                return createElement(_attr, {
                    props: {
                    }
                });
            }
        };
    </script>

     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~感谢许亚男老师热情分享~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    哇哦!这么多小伙伴分享,惊喜不惊喜~ 

    好啦,这一期我们就到这里,期待下一次分享。

    -------------------------------------------------我是版本信息分界线-------------------------------------------------

    主编:何玉 

    时间:20180601

    刊数:东航电商前端技术周刊第一期

    感谢小伙伴分享,若侵权,请联系我们,谢谢。

    -----------------------------------------------嗯 别拉了 我是有底线的-----------------------------------------------

  • 相关阅读:
    linux 网络编程
    linux之有名管道
    linux之无名管道
    linux进程
    Linux中的内核链表
    dell戴尔服务器配置RAID5(3块硬盘做RAID5+1块热备)(转发)
    盘点SQL on Hadoop中用到的主要技术
    垃圾回收算法
    JDK 中的监控与故障处理工具-05 (jstack)
    JDK 中的监控与故障处理工具-04 (jmap)
  • 原文地址:https://www.cnblogs.com/yuebai/p/9120718.html
Copyright © 2020-2023  润新知