创建vue项目在使用v-cli和使用vite中的区别
比如mian.js中引入app.vue文件时后要把后缀名加上
1、除了.js的后缀名不需要加后缀名,其他的都去要加上;而用v-cli中则不需要;
2、index.html文件vite搭建的项目这个文件不是放在public文件夹下,而是放在根目录下
3、打包vite做了优化,js文件体积变小了
在App.vue导入vue的区别
-
vue2
import Vue from 'vue' import App from './App.vue'
-
vue3 具名导出
import { createApp } from 'vue' import App from './App.vue'
使用vue创建vue实例不一样。vue3不存在构造函数,如何创建vue应用呢
-
vue2
const app =new Vue(options);//返回的像组件实例 app.$mount('#app');
-
vue3
const app =new createApp(App);//返回的时一个纯vue实例对象,没有过多的$方法 app.mount('#app')
组件中this的区别
vue2中this指代的就是这个vue组件实例
vue3中this指定时代理对象proxy,通过代理对象获取组件实例
template中的变化
在vue2中template中必须得用一个主元素包裹不然会报错 而在vue3中则不需要
vue2与vue3在标签或者组件中的ref="formRef"的dom元素的使用
-
vue2中直接使用this.$refs.formRef或者this.$refs['formRef']的方式就可以获取该组件或者dom的内容
-
vue3中由于setup函数中没有了this,那该如何使用呢?
<div ref="mainContainer" ></div> setup() { const mainContainer = ref(null) onMounted(()=>{console.log(mainContainer)}) return { mainContainer, } }
- 由于setup函数创建时还没有VNode 所以想要使用该属性必须得在onMounted函数里面可以使用获取
vue3的效率提升主要表现在那些方面?
1、静态提升
2、预字符串化
3、缓存事件处理
4、Block tree
5、PatchFlag
具体说说这些的方面?
-
静态节点
- 没有绑定动态内容。什么是动态内容:比如动态绑定class/style,{{userInfo.name}}一些需要获取的数据
- vue2与vue3作比较静态节点
-
1、vue2的静态节点,通过预编译把template内容编译成render函数
render(){ createVNode('h1',null,'Hello World'); //... }
-
2、vue3的静态节点:首先直接定义一个变量去接收它,防止每次渲染的时候都去重新创建一个h1的虚拟节点【这个h1节点是不会变的所以不需要重新创建】
const hoisted= createVNode('h1',null,'Hello World'); function render(){ //直接使用histed }
-
-
静态属性提升
<div class="user"> {{userInfo.name}} </div>
-
这里div是动态的;但是div的class属性是静态的 vue3这里直接是把他定义出来
**const histed={class:"user"}** function render(){ createVNode('div',**histed**,userInfo.name); //... }
-
-
预字符串化
<div class="menu-bar-container"> <div class="logo"> <h1>logo</h1> </div> <ul class="nav"> <li>< a href="" >menu</ a></li> <li>< a href="" >menu</ a> </li><li>< a href="" >menu</ a></li> <li>< a href="">menu</ a></li> <li>< a href="">menu</ a></li></ul> <div class="user"> <span>{{ user.name }}</span> </div> </div>
-
当编译器遇到大量连续的静态内容,绘制节将其编译为一个普通字符串节点
const hoisted 2 =_ createStaticVNode("<div class=1"logol"><h1>logo</h1></div> <ul class=l"navl"<li>< a href= "l" >menu</ a></li><li><ahref="">menu</ a></li> <li>< a href=l"l">menu</ a>/li>li><ahref=l"l" >menu</a></li> <li>a href=V"N">menu</ a></li></ul>")
-
vue2会重新渲染虚拟节点,不管你是改变和不改变的都给你重新渲染 而vue3则是只重新创建动态的节点,而静态的改变数据时不会重新再去渲染,大大节省性能消耗 SSR(服务端渲染)里最明显
-
-
缓存事件处理函数
<button @click="count++" >puls</button>
-
vue2编译
render(h){ return createVNode("button",{ onClick:function($event){ h.count++; } }) }
-
vue3编译 【_cache缓存对象,编译的时候看一下这个缓存对象里面有没有这个函数,有的化就直接拿就不用再去创建,没有的化创建函数在赋值给缓存对象,大大节省性能消耗】
render(h,_cache){ return createVNode("button",{ onClick:_cache[0]||(_cache[0]=($event)=>(h.count++)) } }) }
-
-
Block tree
- vue2在对比新旧树的时候,并不知道那些节点是静态的,那些是动态的,因此只能一层一层比较,这就浪费了大部分事件在对比静态节点上
- vue3在对比的时候可以标记那些是动态节点,然后把这些动态节点放到根节点中,用一个数组记录这些动态节点,然后循环数组重新渲染这些,
-
PatchFlag
-
vue2在对比每一个节点时,并不知道这个节点那些星官信息会发生变化,因此只能将信息依次对比
-
vue3则会告诉你哪个地方什么东西时动态节点
<div :class="user.name" data-id="1" title="user"> <span :class="user.name">{{user.name}}</span> </div> 编译后 export function render(_ctx,_cache) { return(_openBlock(),_createBlock("div", hoisted_1, [_ hoisted 2,_createVNode("div", f], { class:[ "user", ctx.user. name ] },[_createVNode("span", {class:_ctx.user.name]}, _toDisplayString(_ctx.user.name), 3 /* TEXT, CLASS */) ],2/* CLASS */) } 如这里的: 3 /* TEXT, CLASS */就会告诉你,在span元素里面的text和class属性是动态的 2/* CLASS */ 表示div中的class属性是动态的
-
为什么vue3中去掉了vue的构造函数?
- vue2的全局构造函数的静态方法会对所有vue应用生效,不利于隔离不同的应用如在一个html页面中, 可能会创建多个vue实例,但是你想给其中一个vue实例引入插件,但是一旦使用插件、全局的组件、全局的混合、全局的指令, 这样就会影响到其他vue应用,就相当于每个实例都得去获取这些插件,组件,混合和指令,有些不想用到,但是没办法改
- vue2的构造函数集成了太多功能,不利于tree shaking,vue3把这些功能使用普通函数导出,能够充分利用 tree shacking优化打包体积
- vue2没有把组件实例和vue应用两个概念区分开来,在vue2 中,通过new Vue创建的对象,既是一个vue应用,同时优势又一个特殊的vue组件。
- vue3中把这两个概念区分开来了,通过createAPP创建的对象,是一个vue应用,它内部提供的方法是针对整个应用,而不再是一个特殊的组件
vue3数据响应式的理解
vue3不再使用Object.defineProperty的方式定义完成数据响应式,而是使用Proxy。
除了Proxy本身效率比Object.defineProperty更高之外,由于不必递归遍历所有属性,而是直接得到一个Proxy。
所以再vue3中,对数据的访问时动态的,当访问某个属性的时候,再看动态的获取和设置,这就极大的提升了再组件初始化阶段的效率
同时由于Proxy可以监控到成员的新增和删除,因此,再vue3中新增成员、删除成员,索引方式访问等均可以触发重新渲染,而这些再vue2中是难以做到的