vue3新特性介紹和基本使用

新特性

  • ref、reactive、computed、watch
  • 新的生命週期
  • 自定義鉤子函數
  • Teleport(組件位置替換)
  • Suspense(異步加載組件實現)
  • 全局Api、配置項的優化
  • 更好的支持typescript

全局api和初始化應用的變化

全局config

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')複製代碼

composition Api

ref

須要注意的是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

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>複製代碼

reactive

在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>複製代碼

watch監聽

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)
  })
}複製代碼

provide、inject

根組件注入

//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') })
  }
})複製代碼

變動

  • .sync修飾符 => v-model:propName

目前遇到的問題

  • keep-alive不可用
相關文章
相關標籤/搜索