vue3將全局配置掛在了app實例上而不是構造函數上,好處是是的應用之間的配置互不影響vue
//vue2的全局config配置是直接掛在Vue構造函數上的//例如Vue.config.errorHandler = (err)=>console.log(err)//vue3的全局api是在當前應用實例上修改的,不會影響其餘應用//例如const app1 = createApp(AppComponent1)const app2 = createApp(AppComponent2) app1.config.errorHandler.(err)=>console.log(err,'app1') app2.config.errorHandler.(err)=>console.log(err,'app2')複製代碼
vue3爲了減少打包體積,將不少方法都採用了具名導出的方式(如 createApp、nextTick等),這使得初始化實例的方式也有所區別react
例如:git
const app1 = createApp(AppComponent1)const app2 = createApp(AppComponent2)複製代碼
由於vue3再也不有Vue構造函數,因此一些全局的自定義屬性或者方法也無法經過Vue.prototype.xx掛在到vm實例上,這時候須要藉助app.config.globalProperties來實現這一功能github
例如:vue-router
//若是項目採用了typescript,那麼就須要擴展一下`@vue/runtime-core`模塊,不然在使用的時候會報找不到$http屬性//在main.ts加上以下代碼declare module '@vue/runtime-core' { interface ComponentCustomProperties {$http: any; } } app.config.globalProperties.$http = () => { //do something}複製代碼
附typescript
vue3的中間件也是經過每一個應用實例下的use方法去註冊,且支持鏈式調用api
app1.use(middleware1).use(middleware2).mount('#app')複製代碼
須要注意的是setup返回的變量都是Ref類型,修改ref的值須要修改ref.value,在其餘的方法中也能經過this.xx直接修改app
使例子異步
<template> <div class="test-font">{{ msg }} </div> <button class="test-button" @click="changeMsg">修改msg</button></template><script lang="ts">import { defineComponent, ref } from "vue";export default defineComponent({ setup() {const msg = ref("hello ref");setTimeout(() => { msg.value = "1000ms after"; }, 1000);return { msg, }; }, methods: {changeMsg() { this.msg = "this is change msg"; }, }, });</script>複製代碼
computed接收一個函數,改函數的返回值做爲計算屬性的值ide
<template> <div class="test-font"><div>num:{{ num }}</div><div>double-num:{{ doubleNum }}</div><button class="test-button" @click="addOne">+1</button> </div></template><script lang="ts">import { defineComponent, ref, computed } from "vue";export default defineComponent({ setup() {const num = ref(0);const doubleNum = computed(() => { return num.value * 2; });const addOne = () => { num.value++; };return { num, doubleNum, addOne, }; }, });</script>複製代碼
在setup中,reactive能夠爲咱們集中定義屬性
<template> <div class="test-font"><div>name:{{ name }}</div><div>age:{{ age }}歲</div><div>height:{{ height }}米</div><div>weight:{{ weight }}公斤</div><div>weight-2:{{ weight2 }}斤</div><div>attr:{{ attr }}</div><div>淦飯了沒:{{ eat }}</div><button class="test-button" @click="changeMsg">淦飯</button> </div></template><script lang="ts">import { defineComponent, reactive, toRefs, computed } from "vue"; interface DataProps { name: string; age: number; height: number; weight: number; weight2: number; attr: string; eat: string; changeMsg: () => void; }export default defineComponent({ setup() {const data: DataProps = reactive({ name: "熊志強", age: 18, height: 1.85, weight: 135, weight2: computed(() => {return data.weight / 2; }), attr: "帥一批", eat: "沒有", changeMsg: () => { data.eat = "淦了"; }, });return { ...toRefs(data), }; }, });</script>複製代碼
vue3提供了再setup中使用的數據監聽函數watch,由於setup只是在初始化的時候調用一次,沒法根據數據變化實時調用,因此提供了watch方法解決這個問題
下面是wacth方法的簡單使用實例:
setup(){ //監聽單個的ref const a = ref(0) watch(a,(newval,oldval)=>{ console.log(newval,oldval) }) //監聽多個ref const b = ref(0) watch([a,b],(newval,oldval)=>{ console.log(newval,oldval) }) //監聽reactive const reactiveData = reactive({ a:1, b:2, c:3 }) watch(data,(newVal,oldVal)=>{ console.log(newVal,oldVal) }) //監聽reactive下的某一個屬性 watch([()=>data.a,()=>data.b],(newVal,oldVal)=>{ console.log(newVal,oldVal) }) }複製代碼
根組件注入
//parent Componentimport {provide,ref} from 'vue'setup(){ const foo = ref('') provide('foo',foo) }//descendant componentimport {inject} from 'vue'setup(){ const foo = inject('foo','默認值') return{ foo } }複製代碼
ps:若是setup中有異步操做,inject必須在異步操做以前
import {useRoute,useRouter} from ''vue-routersetup(){ const route = useRoute() //等同於vue2的this.$route const router = useRouter() //等同於vue2的this.$router}複製代碼
有兩個生命週期名稱修改以及兩個新增
// 修改的beforeDestroy -> beforeUnmount destroyed -> unmounted//新增的renderTracked renderTriggered複製代碼
vue3提供了在setup中使用的生命週期函數
/* 生命週期函數對應表 beforeCreate -> 與setup並行 created -> 與setup並行 beforeMount -> onBeforeMount mounted -> onMounted beforeUpdate -> onBeforeUpdate updated -> onUpdated beforeUnmount -> onBeforeUnmount unmounted -> onUnmounted errorCaptured -> onErrorCaptured renderTracked -> onRenderTracked renderTriggered -> onRenderTriggered */import { onMounted } from 'vue'defineComponent({ setup(){ onMounted(() => { console.log('mounted') }) } })複製代碼