Vue3.x出来以后跟Vue2.x有很多写法上面的差异差异,最开始的创建就有一定的不同了,以前Vue2.x通过new Vue(),手动生成,并且全局API挂在Vue上,如下:
import Vue from 'vue';
import App from './App.vue';
Vue.component('loading', {})
new Vue({
render: h => h(App)
}).$mount('#app')
现在Vue3.x通过createApp实例化,并且全局API挂在vue实例上 app,如下:
import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import * as ElIconModules from "@element-plus/icons-vue";
import 'element-plus/dist/index.css'
import App from './App.vue'
import router from './router'
import store from './store'
const app = createApp(App)
app.use(store)
app.use(ElementPlus)
app.use(router)
app.component('loading', {})
Object.keys(ElIconModules).forEach(function (key) {
app.component(ElIconModules[key].name, ElIconModules[key]);
});
app.mount('#app')
以下还有一些差异跟大家分享一下
1. 生命周期钩子
① 2.x
export default {
name: '',
data() {
return {}
},
components: {},
methods: {},
computed: {},
beforeCreate() {
console.log('beforeCreate 创建vue实例完成之前所执行的')
},
created() {
console.log('created 实例创建完成之后的,初始化data和methods')
},
beforeMount() {
console.log('beforeMount 开始编译把data里面的数据和vue语法生成html模板')
},
mounted() {
console.log('mounted 开始挂载编译生成的html渲染到页面')
},
beforeUpdate() {
console.log('beforeUpdate 当data里面数据改变时触发')
},
updated() {
console.log('updated data里面的数据和页面保持同步')
},
beforeDestroy() {
console.log('beforeDestroy vue实例从运行状态进入销毁状态,data、methods、指令等还处于可用状态')
},
destroyed() {
console.log('destroyed 组件完全被销毁,data、methods、指令等已经不可用了')
}
}
② 3.x
export default defineComponent({
name: "ed",
props: {
title: {
type: String,
default: "",
},
},
setup(porps, { emit }) {
onBeforeMount(() => {
console.log("onBeforeMount - 组件挂载到节点上之前执行的函数");
});
onMounted(() => {
console.log("onMounted - 组件挂载完成后执行的函数");
});
onBeforeUpdate(() => {
console.log("onBeforeUpdate - 组件更新之前执行的函数");
});
onUpdated(() => {
console.log("onUpdated - 组件更新完成之后执行的函数");
});
onBeforeUnmount(() => {
console.log("onBeforeUnmount - 组件卸载之前执行的函数");
});
onUnmounted(() => {
console.log("onUnmounted - 组件卸载完成后执行的函数");
});
const state = reactive({
username: "",
password: "",
lowerCaseUsername: computed(() => state.username.toLowerCase()),
});
const fn= () => {};
return {
fn,
onMounted,
...toRefs(state),
};
},
computed: {},
components: {},
data() {
return {};
},
methods: {},
});
以上可以看出vue2.0和3.0差异 Vue2--------------Vue3 beforeCreate----setup() created----setup() beforeMount----onBeforeMount mounted----onMounted beforeUpdate---- onBeforeUpdate updated ---- onUpdated beforeDestroy ---- onBeforeUnmount destroyed ---- onUnmounted 并且还可以看出vue2.0中响应性数据一般都在data,computed,方法基本都是局限在methods中使用,而3.0响应性数据正常可以通过引入的reactive,把数据放入reactive中,通过setup()方法来返回我们的响应性数据,函数可以直接放在setup中并return出去,这使代码会更加简便和整洁
2.双向数据绑定原理
Vue2.x 基于Object.definePropert()对数据进行劫持 结合 发布订阅模式的方式来实现的。 Vue3.x基于Proxy来做数据大劫持代理,可以原生支持到数组的响应式,不需要重写数组的原型,还可以直接支持新增和删除属性,比Vue2.x的Object.defineProperty更加的清晰明了。 proxy和definePropert差异: proxy相比于definePropert,defineProperty只能监听某个属性,不能对全对象监听,proxy可以省去for in、闭包等内容来提升效率(直接绑定整个对象即可),也可以监听数组,不用再去单独的对数组做特异性操作 vue3.x可以检测到数组内部数据的变化,但是proxy无法兼容全部浏览器,无法polyfill
3.支持碎片
vue2只能有一个节点
<template>
<div class="form">
<h3></h3>
</div>
</template>
vue3可以有多个节点
<template>
<div class="form"></div>
<h3></h3>
</template>
4.取消filter
2.x经常在组件中可以使用filter,但在 3.x 中,过滤器已移除,且不再支持。建议可以使函数方法调用或计算属性来替换它们。
5. 函数组件写法改变 - h
在 2.x 中,render 函数会自动接收 h 函数当一个参数
Vue.component('loading', {
render(h) {
return h('div', {title: ''}, [''])
},
})
在 3.x 中,h 函数现在是全局通过vue导入的,而不是作为参数自动传递。
import { h } from 'vue'
app.component('loading', {
render(props, context) {
return h('div', {title: ''}, [''])
},
})
6. router、vuex、refs的以及nextTick使用
<div ref="popover"></div>
import {mapState,mapGetters,mapMutations,mapActions} from 'vuex'
this.$router.push('home')
this.$router.push({path: '/login?url=' + this.$route.path});
this.$router.push({ name: 'user', params: { userId: 123 }})
this.$router.push({path: '/backend/order', query: {selected: "2"}});
this.$store.state.name
this.$store.dispatch(‘Login’, this.loginForm)
this.$nextTick(() => {
console.log(this.$refs.popover)
});
methods: {
...mapMutations({add:'JIA',jf:'JIAN'}),
...mapActions(['jadd','delayAdd'])
},
<div ref="popover"></div>
import{ nextTick , ref} from "vue";
import { useRouter } from "vue-router";
import { mapGetters } from "vuex";
import { useStore } from "vuex";
export default defineComponent({
setup() {
const popover= ref(null);
const router = useRouter();
const store = useStore();
const state = reactive({
urls: "",
user: '',
});
const toggleSideBar = () => {
store.dispatch("app/toggleSideBar");
};
const goTO = () => {
router.push({ path: "/user/info" });
};
onMounted(() => {
nextTick(() => {
console.log(popover.value)
})
});
return {
toggleSideBar,
...toRefs(state),
onMounted,
goTO,
popover
};
},
computed: {
...mapGetters(["sidebar", "avatar", "device", "name"]),
},
components: { },
data() {
return {};
},
});
7.computed和watch区别
watch:{
'form.minimumChargeAmount':{
handler(val){
console.log(val)
}
},
name(newValue, oldValue){
console.log("修改了name", newValue, oldValue);
},
result: {
immediate: true,
deep: true,
handler(newValue, oldValue) {
console.log("修改了result", newValue, oldValue);
},
},
},
computed: {
totalPage: function () {
return Math.ceil(this.total / this.pageSize);
},
fullName: {
get() {
return this.firstName + "-" + this.lastName;
},
set(val) {
const nameArr = val.split("-");
this.firstName = nameArr[0];
this.lastName = nameArr[1];
},
},
}
import {
defineComponent,
reactive,
computed,
toRefs,
watch,
ref,
watchEffect,
} from "vue";
export default defineComponent({
name: "",
setup() {
const state = reactive({
username: "",
password: "",
lowerCaseUsername: computed(() => state.username.toLowerCase()),
demo: "demo",
name1: "1",
name2: "2",
});
let name = computed(() => state.name1 + "-" + state.name2);
let sure = computed({
get() {
return state.name1 + "-" + state.name2;
},
set(val) {
const nameArr = val.split("-");
state.name1 = nameArr[0];
state.name2 = nameArr[1];
},
});
let sum = ref(0);
let msg = ref("watch使用");
watch(
[sum, msg],
([s, m], [olds, oldm]) => {
console.log("sum/msg变化", s, m, olds, oldm);
},
{ immediate: true }
);
watchEffect(() => {
console.log("监听state.demo", state.demo);
});
return {
...toRefs(state),
name,
sure,
sum,
msg,
};
},
components: {},
data() {
return {};
},
});
|