Vue

作者: 斯文的烟鬼去shi吧 | 来源:发表于2018-03-11 18:52 被阅读0次

    为什么用框架

    操作不规范,导致大量的重绘和重排,复杂的读取dom对象(js的计算要比dom便宜),代码可维护性差等。
    比如说:

    • 数组增加100条元素,每一条元素都产生一次重新排列。而不是增加完100条再更新到页面上。
    • 页面数组这100条元素发生改变的时候,重新创建所有 DOM 元素。必要的 DOM 更新。
      虽然框架做的事情,都可以靠双手解决。
      但是谁可以保证都能记得这样写?
      其实使用框架,就是在性能和可维护性,可阅读性做一个取舍。
      框架就起规范代码,脱离底层操作,用声明式的方式编写,让代码更容易看懂。

    用什么框架

    前端三大框架
    angular,react,vue

    • angular:脏查询。ng自定义了很多函数,比如说ng-click, 一旦触发这些函数,就会把所有监听的值都进行一次对比,修改改变的值,然后再重新对比一次,没有更新就渲染到页面上去。(大颗粒度)
      如果使用了ng之外的函数,比如jQuery等,ng是检测不到触发的。得手动触发,$scope... $watch $digest $apply
    • react:虚拟dom + diff, 改进过的diff,只对比同层级的元素,一旦发生改变,把原来位置的直接删除,替换成为新的元素。通过虚拟dom刷新到页面上。(setData() 时候对比)
    • vue:观察者模式。js的特性 Object.defineproperty 里面的get/set用来监听数据的变化。get的时候加入观察者队列,set更新数据的时候发布者分发给队列里面的每一个。(细颗粒度)
      初始化的时候给每一个属性都加上数据监听。

    对比:

    • 首次渲染: Virtual Dom > 脏查询 >= 依赖收集 ()
    • 少量数据: 依赖收集 >> Virtual Dom 优化 > 脏查询 (全部检查) > Virtual Dom 不优化
    • 大量数据更新:脏检查 + 优化 >= 依赖收集 + 优化 > Virtual DOM(无法/无需优化,必须得对比)

    如何使用

    模板渲染
    事件处理
    计算属性
    ...
    Cal Attrs
          <div>
              {{ helloComputed }} <!-- 时间戳3  -->
          </div>
          <div>
              {{ helloMethods() }} <!-- 时间戳 x  -->
          </div>
          <div>
              {{ ms }} <!-- 时间戳4  -->
          </div>
    ...
    props: {
            message: String
    },
    data () {
            return {
                msg: 'hello',
                ms: ''
            }
        },
        computed: {
            helloComputed: function() {
                console.log('computed')
                return this.msg + 'computed' + Date.now() + this.message
            }
        },
        mounted: function () {
          console.log(this.helloComputed)   // 时间戳 1
          console.log(this.helloMethods())   // 时间戳  2
          this.msg = 'HELLO'
          console.log(this.helloComputed)   // 依赖改变,重新计算时间, 3
          this.ms = this.helloMethods()  // 只在渲染时候计算, 时间戳 4
        },
        methods: {
            helloMethods: function () {
                console.log('methods')
                return this.msg + 'methods' + Date.now() + this.message
            }
        }
    
    • methods: 略。
      methodscomputed 区别。例子的ms,是由父组件传过来计算得到的值,虽然说methods的方法能够监听到改变,但是某些复杂的情况下。比如对象,子组件也就是当前的组件需要对object做处理,而且!不能改变父组件传过来的对象(浅拷贝和深拷贝)

      文档说明
    • computed: (!)

    - 执行异步操作不能串行返回结果,使用watch。
    - 开销较大的操作,避免堵塞主线程,使用watch。
    - 简单且串行返回的,使用computed
    
    • watch: 对某一个data监听
    列表渲染

    js的原因,无法监听特殊对象,数组。Vue 包含一组观察数组的变异方法,所以它们也将会触发视图更新。类似angular的脏检测。

    • :key 唯一标识
      类似react 的diff 算法,track by $index。
    条件渲染
    • v-if 直接销毁
    • v-show css切换hidden
    组件

    什么是组件?
    封装可重用代码。
    如果说函数是JS的一等公民,那么在VUE里面,组件就是一等公民。万物皆组件。
    (在react里面,函数即是组件)
    万法归一,在VUE也是同理。
    既然这样,在写一个组件之前。我们得分清楚业务组件公共组件。然后进行职责划分,其实就是单一原则
    就算业务组件可复用性没有这么高,也是应当做一些抽象,页面不要长了...
    举个🌰:一任务是某个页面内添加一张卡片。一个竖着的带圆角的按钮类似样式。上面是个人信息,下面是头衔信息。数据请求的同一个接口。
    就可以将这个卡片从页面抽离出来,单独做成一个卡片了。
    更进一步,将上下信息分开。卡片组件引入上下部分。

    生命周期: 在做某些事情之前做一些处理。可以用中间件思想看- -。
    • beforeCreate 此时$el、data 的值都为undefined
    • created 此时可以拿到data的值,但是$el依旧为undefined(还没有渲染)
    • beforeMount $el 创建到虚拟dom里面。
    • Mounted : 做数据处理。如果需要完全渲染完毕再处理,则增加this.$nextTick(() => { ... })
    • beforeUpdate:
    • Updated:
      ...
    组件间通信
    • 父组件 => 子组件 , 父组件设置v-bind:key="value" , 子组件接收props: {key}。 或者父组件this.$child

    • 子组件 => 父组件 , 子组件设置vue.$emit(key, value) ,父组件接收v-on:key=" fn " 。或者子组件this.$parent

    • 同级兄弟组件通信:BUS解释思想

    • slot插槽
      栗子:cell
      :title
      :value

    非业务代码

    编写可以重用的组件。尽量解耦合,参数尽量简单。
    一个组件实现一个功能(单一原则)

    纯函数编写思想实现组件。
    一样的输入得到一样的输出
    why?
    方便测试。
    每当需要修改的时候,我都可以得到明确的输出,那么我就可以在外面套一个组件。中间做一些处理。还不需要修改原组件(开闭原则,中间件)
    参数尽量简单
    🌰:组件接收(target, key, value)这样的参数结构
    当进行多次操作的的时候
    外面再加一层组件,接收(target, obj, value = 'default')这样的参数,用for...in之类的处理

    异步组件

    • mixin
      混合起来,被继承的属性组件,混合部分内容达到继承效果?
      使用恰当时,可以为自定义对象注入处理逻辑。怎么举例子
    • extend
    • directives : hook
    JSX
    router hash?

    相关文章

      网友评论

        本文标题:Vue

        本文链接:https://www.haomeiwen.com/subject/khabfftx.html