Vue3.0与Vue2.0的响应式对比

想必大多数人都被defineProperty的机制坑过,因此在Vue3.0即将到来之际,我作了一个Vue3.0与2.x的响应式效果的比对。没有对比就没有伤害,对比以后才会知道3.0用了Proxy以后有多么强大。javascript

打包

Vue3.0源码仓库 clone一份源码。html

安装

npm i
复制代码

打包

npm run build
复制代码

发现出错了,ts的类型检查有问题,更新一下 source-mapvue

npm i source-map
复制代码

继续打包,发现又出错,仍是ts的类型错误,在transformExpression.ts这个文件中,把报错的类型所有声明为any(反正咱们只是为了打包),继续打包java

此次打包成功了,生成的文件在packages/vue/dist目录下,共有7个文件:git

  • vue.cjs.js
  • vue.cjs.prod.js
  • vue.esm-browser.js
  • vue.esm-browser.prod.js
  • vue.esm-bundler.js
  • vue.global.js
  • vue.global.prod.js

咱们选择vue.global.prod.js,能够在浏览器中直接使用github

准备示例代码

建立文件

  1. 使用IDEA(WebStorm也同样)建立一个空的项目
  2. 新建static文件夹(我的习惯)
  3. 在static文件夹下加入刚刚打包的Vue3.0的js文件以及Vue2的js文件
  4. 在static文件夹下分别建立Vue2.x和Vue3.x的测试文件 Vue2.x: index2.html, vue2.js Vue3.0: index3.html, vue3.js
  5. 建立一个可用于展现响应式特性的组件文件comp.js

这个时候,static下的文件结构是这样的:shell

  • comp.js
  • index2.html
  • index3.html
  • vue.global.prod.js
  • vue.js
  • vue2.js
  • vue3.js

准备测试代码

编写html文件npm

index2.html内容以下:数组

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <script src="./vue.js"></script>
</head>
<body>
  <div id="app"></div>
  <script src="./comp.js"></script>
  <script src="./vue2.js"></script>
</body>
</html>
复制代码

index3.html浏览器

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <script src="./vue.global.prod.js"></script>
</head>
<body>
  <div id="app"></div>
  <script src="./comp.js"></script>
  <script src="./vue3.js"></script>
</body>
</html>
复制代码

除了引用文件的不一样没有任何其余的区别

编写公共组件

const Comp = {
  template: ` <div> <h2>测试对象添加属性</h2> <div>{{person}}</div> <div> <button @click="addProperty">添加属性</button> <button @click="deleteProperty">删除属性age</button> </div> <h2>测试数组修改</h2> <div>{{array}}</div> <div> <button @click="addArrayItemProperty">添加元素0属性</button> <button @click="deleteArrayItemProperty">删除元素0属性</button> <button @click="replaceArrayItem">替换元素1</button> </div> </div> `,
  data() {
    return {
      msg: 'abc',
      person: { name: 'aa', age: 22 },
      array: [{
        name: '1'
      }, {
        name: '2'
      }]
    };
  },
  methods: {
    addProperty() {
      this.msg = this.msg + '1';
      this.person[this.msg] = this.msg;
    },
    deleteProperty() {
      delete this.person.age;
    },
    addArrayItemProperty() {
      this.array[0].enname = 'abc';
    },
    deleteArrayItemProperty() {
      delete this.array[0].name;
    },
    replaceArrayItem() {
      this.array[1] = { name: '222' };
    }
  }
};
复制代码

组件内的操做分别验证的是:

  • 对象属性添加
  • 对象属性删除
  • 对象数组内已存在元素的属性添加
  • 对象数组内已存在元素的属性删除
  • 对象数组内已存在元素的替换(使用索引)

这里有个小插曲,一开始我只是验证3.0的响应式,因此编写组件的时候template没有用div包裹,直接声明了多个根节点(也是无意插柳,毕竟不多直接写浏览器渲染的组件),原本没发现问题,结果一样的组件用在2.x上的时候,提示我组件不能存在多个根节点...

编写Vue3.0与2.x的入口文件

vue2.js

new Vue({
  el: '#app',
  template: '<Comp/>',
  components: {
    Comp: Comp
  }
});
复制代码

vue3.js

const app = Vue.createApp();
app.mount(Comp, '#app');
复制代码

事实显示Vue3.0的入口编写更为简便,不过这不是今天的主题,接下来就是见证的时刻:

在IDE中直接运行index2.html和index3.html

是否是一毛同样?这里发现一个小问题,Vue2.x渲染出来的内容,并排的button之间有间隙,而Vue3.0渲染的内容没有。我审查元素发现两个页面的源码是一毛同样的。这个若是有人知道为何的话请告诉我一下。

接下来咱们依次点击两个页面上的5个按钮后看页面的变化:

2.x

点完以后,海棠依旧,没有任何的变化

3.0

内容发生变化,5个操做所有生效

结束语

此次的验证到这里就结束了,此次的验证一方面是想尽快尝试一下3.0的使用(等发布不知道还要多久,估计还得几个月,核心代码还在开发,配套的工具估计在开发完以后还要一段时间),另外我写了一个Vue的表单解决方案(没有在掘金发布过,只在公司内部使用),踩过defineProperty的很多坑,因此可能会提早开发适配3.0的版本。OK,让咱们共同期待Vue3.0的正式发布吧!

相关文章
相关标签/搜索