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') }) } })复制代码