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不可用
相关文章
相关标签/搜索