VUE2.0和VUE3.0的区别
数据的双向绑定:重构响应式系统,使用Proxy替换Object.defineProperty****Object.defineProperty的原理:通过使用 Object.defineProperty 来劫持对象属性的 geter 和 seter 操作,当数据发生改变发出通知```javascript<script>var obj = {};Object.defineProperty
-
数据的双向绑定的原理
重构响应式系统,使用Proxy替换Object.defineProperty
Object.defineProperty的原理:通过使用 Object.defineProperty 来劫持对象属性的 geter 和 seter 操作,当数据发生改变发出通知。Vue2.x版本中的双向绑定不能检测到下标的变化
。<script> var obj = {}; Object.defineProperty(obj, 'prop', { get: function () { return val; }, set: function (newVal) { val = newVal; document.getElementById('text').innerHTML = val; } }); document.addEventListener('keyup', function (e) { obj.prop = e.target.value; }); </script>
porxy原理:通过ES6的新特性proxy来劫持数据,当数据改变时发出通知。
proxy可以劫持整个对象,并返回一个新对象
。<script> var obj = {}; var obj1 = new Proxy(obj, { // target就是第一个参数obj, receive就是返回的obj(返回的proxy对象) get: function (target, key, receive) { // 返回该属性值 return target[key]; }, set: function (target, key, newVal, receive) { // 执行赋值操作 target[key] = newVal; document.getElementById('text').innerHTML = target[key]; } }) document.addEventListener('keyup', function (e) { obj1[0] = e.target.value; }); </script>
-
性能的提升
-
diff方法优化
Vue2 中的虚拟dom是进行全量的杜比
Vue3 新增了静态标记(PatchFlag),只比对带有 PF 的节点,并且通过 Flag 的信息得知
当前节点要比对的具体内容。 -
静态提升
Vue2中无论元素是否参与更新, 每次都会重新创建, 然后再渲染
Vue3中对于不参与更新的元素, 会做静态提升, 只会被创建一次, 在渲染时直接复用即可 -
cacheHandlers 事件侦听器缓存
Vue2默认情况下onClick会被视为动态绑定, 所以每次都会去追踪它的变化
Vue3但是因为是同一个函数,所以没有追踪变化, 直接缓存起来复用即可 -
ssr渲染
Vue2当有大量静态的内容时候,这些内容会被当做纯字符串推进一个buffer里面, 即使存在动态的绑定,会通过模板插值嵌入进去。这样会比通过虚拟dmo来渲染的快上很多很多。
Vue3当静态内容大到一定量级时候,会用_createStaticVNode方法在客户端去生成一个static node,这些静态node,会被直接innerHtml,就不需要创建对象,然后根据对象渲染。 -
按需编译,体积更小(Tree shaking)
Tree-shaking 使编译更友好,比如,如果你的项目没有用到watch,那编译时就会把tree shaking掉。 -
Compostion API: 组合API/注入API
Vue2的组件内,使用的是Option API风格(data/methods/mounted)来组织的代码,这样会让逻辑分散,举个例子就是我们完成一个计数器功能,要在data里声明变量,在methods定义响应函数,在mounted里初始化变量,如果在一个功能比较多、代码量比较大的组件里,你要维护这样一个功能,就需要在data/methods/mounted反复的切换到对应位置,然后进行代码的更改。
Vue3中,使用setup函数。如下所示跟count相关的逻辑,都放到counter.js文件里,跟todo相关的逻辑放到todos.js里。import useCounter from './counter' import useTodo from './todos' setup(){ let { val, todos, addTodo } = useTodo() let {count,add} = useCounter() return { val, todos, addTodo, count,add, } }
-
自定义渲染API(Custom Renderer API)
Vue2.x最开始支持运行在浏览器中,渲染到浏览器的dom上,随着vue的流行,出现了weex和myvue。
Vue2.x项目架构对于这种渲染到不同平台不太友好,
Vue3.0推出了自定义渲染API解决了该问题。下面我们先看vue2和vue3的入口写法有所不同:
// vue2 import Vue from 'vue' import App from './App.vue' new Vue({ => h(App)}).$mount('#app') // vue3 const { createApp } from 'vue' import App from "./src/App" createApp(App).mount(('#app')
vue官方实现的 createApp 会给我们的 template 映射生成 html 代码,但是要是你不想渲染生成到 html ,而是要渲染生成到 canvas 之类的不是html的代码的时候,那就需要用到 Custom Renderer API 来定义自己的 render 渲染生成函数了。
// 你自己实现一个createApp,比如是渲染到canvas的。 import { createApp } from "./runtime-render"; import App from "./src/App"; // 根组件 createApp(App).mount('#app');
-
vite开发构建工具
Vue2是使用webpack作为开发构建工具的,npm run dev都要等一会,项目越大等的时间越长
Vue3是使用vite来做开发构建工具。vite支持浏览器支持import关键字,启动项目时浏览器直接请求路由对应的代码文件,代理服务器针对单个文件进行编译并返回。如果请求的文件里还import了其他文件,同理浏览器继续发请求,代理服务器返回。就这样实现了npm run dev时无需编译,实时请求实时编译。 -
支持TS语法
Vue2结合ts的具体实践中,要用 vue-class-component 强化 vue 组件,让 Script 支持 TypeScript 装饰器,用 vue-property-decorator 来增加更多结合 Vue 特性的装饰器,最终搞的ts的组件写法和js的组件写法差别挺大。
Vue3量身打造了defineComponent函数,使组件在ts下,更好的利用参数类型推断 。Composition API 代码风格中,比较有代表性的api就是 ref 和 reactive,也很好的支持了类型声明。import { defineComponent, ref } from 'vue' const Component = defineComponent({ props: { success: { type: String }, student: { type: Object as PropType<Student>, required: true } }, setup() { const year = ref(2020) const month = ref<string | number>('9') month.value = 9 // OK const result = year.value.split('') // => Property 'split' does not exist on type 'number' }
更多推荐
所有评论(0)