最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 记Vue3.0

    正文概述 掘金(qimukakax)   2020-12-16   435

    记Vue3.0

    前言

    vue3.0正式版本终于在九月低发布了,本人在实习的过程中主要进行的项目也是基于Vue3.0的Beta版本composition-api开发的,就抱着热情学习了下Vue3.0,并在此做如下总结。

    Vue3.0优化

    源码优化

    源码的优化主要体现在使用 monorepo (更好的代码管理方式)和 TypeScript (有类型的JavaScript语言)管理和开发源码,这样做的目标是提升自身代码可维护性。

    性能优化

    性能优化主要体现在:源码的体积优化、数据劫持优化、编译优化

    • 源码的体积优化

    静态资源的体积减少,网络对包的传输时间也会相应的减少,JavaScript解析包的时间也会减少. Vue3.0主要通过移除一些冷门的feature以及tree-shakiing(通过编译阶段的静态分析,找到没有被引用的代码并做上标记)

    举个例子:

    src/math.js

    export function cube(x) {
    	return x*x*x;
    }
    
    export function square(x) {
    	return x*x;
    }
    

    src/index.js

    import { cube } from ./math.js
    

    dist/bundle.js

    /* 1 */
    /***/ (function(module, __webpack_exports__, __webpack_require__) {
    
    "use strict";
    /* unused harmony export square */
    /* harmony export (immutable) */ __webpack_exports__["a"] = cube;
    function square(x) {
      return x * x;
    }
    
    function cube(x) {
      return x * x * x;
    }
    

    build后我们发现没有被import的square被做上了标记,然后的压缩阶段会利用压缩工具删除这些没有被使用的代码.

    • 数据劫持优化

    Vue区分与React的一点是它的数据是响应式的,DOM是数据的一种映射,数据发生修改会自动的响应式的影响DOM,把我们的目光集中在数据而不是视图.这就需要通过数据的劫持,在数据发生更新的时候去自动的更新DOM.这就需要在渲染DOM的时候对其进行依赖收集(源码地址)通过watcher进行依赖的管理,参考下图: 记Vue3.0

    Vue.js 1.x 和 Vue.js 2.x 内部都是通过 Object.defineProperty 这个 API 去劫持数据的 getter 和 setter,具体是这样的:

    Object.defineProperty(data, 'a',{
      get(){
        // track
      },
      set(){
        // trigger
      }
    })
    
    

    这个API的缺陷是我们要知道需要劫持的数据的key,因此我们不能检测对象属性添加或者删除,vue通过setset和set和delete实例方法解决了如下问题,但是他还存在这另一个问题,当我们嵌套的层级较深的时候,如果我们要劫持深层次的属性,就需要遍历这个对象,显然这有着很大的性能负担.

    Vue.js 3.0 使用了 Proxy API 做数据劫持,它的内部是这样的:

    observed = new Proxy(data, {
      get() {
        // track
      },
      set() {
        // trigger
      }
    })
    

    由于它劫持的是整个对象,那么自然对于对象的属性的增加和删除都能检测到,但要注意的是,Proxy API 并不能监听到内部深层次的对象变化,因此 Vue.js 3.0 的处理方式是在 getter 中去递归响应式,这样的好处是真正访问到的内部对象才会变成响应式,而不是无脑递归,这样无疑也在很大程度上提升了性能。

    • 编译优化

    记Vue3.0 这是vue从new Vue 开始到生成DOM的过程,Vue3.0主要进行的优化在patch阶段,举个例子:

    假设我们的代码是这样的:

    <template>
      <div id="content">
        <p class="text">static text</p>
        <p class="text">static text</p>
        <p class="text">{{message}}</p>
        <p class="text">static text</p>
        <p class="text">static text</p>
      </div>
    </template>
    

    我们可以看到这里面只有一个动态节点,但在Vue2.x的版本进行diff的时候我们仍然遍历了所有节点,这就导致了vNode的性能和我们模版的大小正相关的关系,和我们动态节点的数量无关,当一些组件的整个模版内只有少量动态节点时,这些遍历都是性能的浪费。

    Vue.js 3.0 做到了,它通过编译阶段对静态模板的分析,编译生成了 Block tree。借助 Block tree,Vue.js 将 vnode 更新性能由与模版整体大小相关提升为与动态内容的数量相关

    语法 API 优化:Composition API

    使用composition-api达到了:优化逻辑组织、优化逻辑复用

    • 优化逻辑组织

    在vue之前的版本中我们使用Options API去编写组件:主要包括data、computed、methods、props这些选项去分类,当组件很小的时候,可以说是十分的清晰的,但是当我们的组件的代码量十分庞大的时候,我们想要搞清楚一些逻辑就会产生一些“反复横跳”的操作,Vue.js 3.0 提供了一种新的 API:Composition API,它有一个很好的机制去解决这样的问题,就是将某个逻辑关注点相关的代码全都放在一个函数里,这样当需要修改一个功能时,就不再需要在文件中跳来跳去。 记Vue3.0

    • 优化逻辑复用

    在我们开发的比较复杂的时候,尤其是中后台系统,少不了一些复用的逻辑,在之前的vue版本中我们通常用minxins去复用逻辑:

    定义一个混入对象

    
    export const myMinxin = {
        data() {
        		return {
            		name: 'qimukakax'
            	}
        },
        methods: {
        	getToken() {
            	const params = 'qimukakax'
            	getToken(params)
            }
        }
    }
    

    将对象混入当前的模版

    <template>
    	<div>components</div>
    </template>
    
    <script>
    import { myMinxin } from './minxin.js'
    
    export defaut { 
    	minxins: [myMinxin],
        created() {
        	console.log(this.name)//qimukakax
        }
    }
    </script>
    

    使用单个 mixin 似乎问题不大,但是当我们一个组件混入大量不同的 mixins 的时候,会存在两个非常明显的问题:命名冲突和数据来源不清晰。在composition-api中:

    定义一个混入对象

     import {ref} from 'vue'
     export const useMyMinxin = {
      const name = ref('qimukakax')
      const getToken = () => {
          const params = 'qimukakax'
          getToken()
      }
    }
    
    

    将对象混入当前的模版

    <template>
    	<div>components</div>
    </template>
    
    <script>
    import useMyMinxin  from './minxin.js'
    import { onMounted } from 'vue'
    
    export defaut {
      setup() {
          const { name, getToken } = useMyMinxin()
          onMounted(() => console.log(name)) 
      }
    }
    </script>
    
    

    可以看到这样我们的条理变得清晰的一点,Composition API 除了在逻辑复用方面有优势,也会有更好的类型支持,因为它们都是一些函数,在调用函数时,自然所有的类型就被推导出来了,不像 Options API 所有的东西使用 this。另外,Composition API 对 tree-shaking 友好,代码也更容易压缩。

    写在后面

    (个人学习笔记,待完善)

    参考资料

    Vue.js 3.0 核心源码解析 黄轶

    其中还引用了一些大佬的帖子,都留下链接?啦! 大家加油?!


    起源地下载网 » 记Vue3.0

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元