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元素上使用,引用指向的就是那个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"
/>