vue2.x与vue3.x的一些区别

520 阅读3分钟

1,vue实例创建方式不同,vue2.x使用new Vue()创建实例。vue3.x则是通过createApp()来创建实例了。

vue2.x

import Vue from 'vue'
import App from './App'

Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
  el: '#app',
  components: { App },
  template: '<App/>'
})

vue3.x

import { createApp } from 'vue'
import App from './App.vue'
const app = createApp(App);
// 通过createApp注册引入vue
app.mount('#app')
// 没有全局的Vue

2,router路由不同,vue3.x需要引入createRouter创建地址路由。createWebHashHistory对应之前的hash,createWebHistory对应之前的history。

vue2.x

import Vue from 'vue'import VueRouter from 'vue-router'Vue.use(VueRouter);

// 通过mode指定路由模式
const router = new VueRouter({  
    // mode: "history",  // history模式
    // base: routerBaseUrl,  // history模式需指定路径
    routes
})

vue3.x

import { createRouter, createWebHashHistory } from 'vue-router';

const routes = [
    {
        path: "/",
        components: "",
    }
];

// 通过createRouter创建路由, createWebHashHistory指定为history模式
const router = createRouter({  
    history: createWebHashHistory(),  
    routes
})

3,filters过滤器在vue3.x已不再使用。

4,将公共方法或者组件挂载到vue实例里,vue3.x的使用方法也不同了,app.config.globalProperties替代了Vue.prototype。

vue2.x

import Vue from 'vue'import DomMessage from "./utils/DonMessage";
// 将封装的弹窗组件挂载到vue实例上
Vue.prototype.$tip = DomMessage;

vue3.x

import { createApp } from 'vue'
import App from './App.vue'const app = createApp(App);import toast from './components/common/toast/index'// app.config.globalProperties替代了Vue.prototype
app.config.globalProperties.$toast = toast;

5,vuex的使用也不同,vue2.x通过new Vuex.Store实例化一个store,而vue3.x通过createStore去创建一个store。

vue2.x

import Vue from 'vue'import Vuex from "vuex";
import persistedState from "vuex-persistedstate"; // 将vuex里的数据默认保存到localStorage里,防止刷新浏览器数据消失
import HomeState from "./modules/home";
import UserState from "./modules/user";

Vue.use(Vuex);
export default new Vuex.Store({  
    modules: { HomeState, UserState },  
    plugins: [
        persistedState({ 
            storage: window.sessionStorage// 自定义保存到sessionStorage
        })
    ],   
    strict: process.env.NODE_ENV !== "production",
})

vue3.x

import { createStore } from 'vuex';
import persistedState from "vuex-persistedstate"; // 将vuex里的数据默认保存到localStorage里,防止刷新浏览器数据消失
import HomeState from "./home/index";

export default createStore({  // 多个模板管理vuex  
    modules: {    HomeState,  },  
    plugins: [    
        persistedState({      // 缓存数据时的key      
            key: 'client-pc-store',      // 哪些模块需要被缓存      
            paths: ['HomeState'],      
            storage: window.sessionStorage, // 自定义保存到sessionStorage    
        })  
    ]
})

6,vue3.x的proxy就相当于vue2.x的this。vue3.x的setup是在onBeforeMounted之前的,setup是获取不到this的,想要获取到this,可以通过getCurrentInstance()这个方法去获取proxy。

import {onMounted, getCurrentInstance} form "vue";

const {proxy} = getCurrentInstance(); // proxy相当于vue2.x的this

console.log("setup:", proxy);

onMounted(() => {
    console.log("mounted:", proxy);
})

7,生命周期也有了一些改变。vue3.x舍弃了beforeCreate和created,用setup替代了它们,其他的生命周期都加多了“on"前缀。

import {ref, reactive, getCurrentInstance, onMounted, onBeforeMount, onBeforeUpdate, onUpdated, onBeforeUnmount, onUnmounted} from "vue";

const {proxy} = getCurrentInstance();

console.log("proxy:我是最先打印的~", proxy);

onBeforeMount(() => {  console.log("onBeforeMount");})
onMounted(() => {  console.log("onMounted");})
onBeforeUpdate(() => {  console.log("onBeforeUpdate");})
onUpdated(() => {  console.log("onUpdated");})
onBeforeUnmount(() => {  console.log("onBeforeUnmount");})
onUnmounted(() => {  console.log("onUnmounted");})

8,vue3.x的setup,带有2个参数,props和context。

  • props:接受父组件传过来的值,具有响应性,不可用es6解构;

  • context:vue3.x里面没有this,提供了一个context上下文属性,可以通过context去获取attrs,slots,parent,root,emit,refs。

    import {ref, reactive} form "vue";

    setup(props, context) { console.log(props, context); }

9,获取ref的dom节点也不同。在vue2.x中通过this.refs可以获取到对应的虚拟Dom节点,而在vue3.x中,ref是被用来给元素或子组件注册引用信息的。而且需要定义一个ref变量接着该ref。引用信息将会别注册到父组件的refs可以获取到对应的虚拟Dom节点,而在vue3.x中,ref是被用来给元素或子组件注册引用信息的。而且需要定义一个ref变量接着该ref。引用信息将会别注册到父组件的refs对象上。如果在普通的Dom元素上使用,引用指向的就是那个Dom元素,如果用在子组件上,引用指向组件实例。

vue2.x

<div class="title" ref="titleDom">{{title}}</div>

// 打印获取的虚拟Dom节点
console.log(this.$refs["titleDom"]);

vue3.x

// 1、在普通Dom元素上使用,通过ref获取到的是虚拟Dom节点
<div class="title" ref="titleDom">{{title}}</div>

import {ref, reactive, getCurrentInstance} form "vue";const {proxy} = getCurrentInstance();

// 该ref获取的虚拟Dom节点可以在context上下文中的root获取到
const titleDom = ref(null); // 需要定义一个ref对象接着该ref虚拟Dom名称(不可缺少)
console.log("获取到的ref:", proxy.$refs.titleDom);


// 2、在子组件使用,通过ref获取到的是子组件的实例
<childComponent class="title" ref="childDom">{{title}}</childComponent>
import {ref, reactive, getCurrentInstance} form "vue";
const {proxy} = getCurrentInstance();

const childDom= ref(null); 

console.log("child", childDom); // 通过ref获取到的是子组件的实例

10,vue3.x中子组件元素上不支持添加class属性。

// 不支持添加class属性
<childComponent class="childDom" />

11,二次封装的input组件时,vue2.x和vue3.x父组件都是通过v-model绑定value值,但是子组件获取父组件的参数和$emit事件不同,具体可以看下面的例子:  

  • vue2.x只能v-model双向绑定一个变量,多的变量只能通过.sync去双向绑定;
  • vue3.x可以v-model双向绑定多个变量,已舍弃.sync;
  • vue3.x子组件里的input组件需要:modelValue绑定值,使用v-model绑定报错;

vue2.x的使用:

父组件:
<InputBox v-model="keyWord"/>

子组件:
props: {
    value: { // 通过value接受父组件传过来的值
        type: String
    }
}

子组件通过input事件将更新之后的值传回去给父组件
this.$emit("input", "更新后的值");

vue3.x的使用:

父组件:
<InputBox v-model="keyWord"/>

子组件:
import {defineProps, getCurrentInstance} form "vue";const {proxy} = getCurrentInstance(); // proxy相当于vue2.x的this
defineProps: {
    modelValue: { // 通过modelValue接受父组件传过来的值
        type: String
    }
}

子组件通过update:modelValue事件将更新之后的值传回去给父组件 
proxy.$emit("update:modelValue", "更新后的值");

vue3.x支持同一个组件同时双向数据绑定多个变量:

<ChildComponent v-model:title="pageTitle" v-model:content="pageContent" />

<!-- 是以下的简写: -->

<ChildComponent
  :title="pageTitle"
  @update:title="pageTitle = $event"
  :content="pageContent"
  @update:content="pageContent = $event"
/>