1、使用vue/cli
,确保版本大于4.5.0
2、使用vite
,vue团队打造
// 不再是引入Vue构造函数,而是引入createApp工厂函数
import { createApp } from 'vue'
import App from './App.vue'
//创建应用实例对象,类似于Vue实例对象,但是比Vue实例对象更轻
createApp(App).mount('#app')
<!-- vue3中的组件模板可以没有根标签 -->
<template>
<img alt="Vue logo" src="./assets/logo.png">
<HelloWorld msg="Welcome to Your Vue.js App"/>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
name: 'App',
components: {
HelloWorld
}
}
</script>
<style>
</style>
vue3中的一个新的组件配置项,值是一个函数,setup是所有Composition API表演的舞台
组件中用到的所有数据、方法、计算属性,全部要配置在setup中
<template>
<h1>name:{{name}}</h1>
<h1>age:{{age}}</h1>
<button @click="show">show</button>
</template>
<script>
export default {
name: 'App',
setup(){
//数据
let name = "lucy";
let age = 18;
//方法
function show(){
alert("姓名:" + name + ",年龄:" + age);
}
return {name,age,show}
}
}
</script>
注意:尽量不要和vue2配置混用(vue2配置可以读取setup的属性和方法,但是setup不能访问vue2配置的);setup不能使用async修饰
在beforeCreate之前执行一次,this是undefined,也就是说,setup中不要写this
对于在setup函数中返回的属性,虽然组件可以直接使用,但是不是响应式(页面随着数据进行改变)的,如果需要该属性是响应式的,也就是需要vue监测该属性,那么需要使用vue提供的ref函数
ref函数,接受的数据可以是基本类型也可以是对象类型
对于基本类型:底层依靠的是defineProperty()
的get()
和set()
实现
对于对象类型:底层利用vue3的一个新函数reactive()
实现
<template>
<h1>name:{{name}}</h1>
<h1>age:{{age}}</h1>
<button @click="ageAdd10">ageAdd10</button>
</template>
<script>
//引入ref函数
import {ref} from 'vue';
export default {
name: 'App',
setup(){
let name = "lucy";
//需要响应式的属性使用ref函数,生成引用实现对象
let age = ref(18);
//方法
function ageAdd10(){
//修改值的时候需要修改引用实现对象的value属性
age.value += 10;
}
return {name,age,ageAdd10}
}
}
</script>
和ref作用、用法都一样,定义响应式数据,通常用来定义对象类型数据,虽然ref也可以定义对象数据类型,但是底层调用的还是reactive
用于在setup中定义计算属性
<template>
<input type="text" v-model="name">
<h1>{{sayHello}}</h1>
</template>
<script>
import {ref,computed} from 'vue';
export default {
name: 'App',
setup(){
let name = ref("lucy");
let sayHello = computed(() => {
return "Hello " + name.value;
});
return {name,sayHello}
}
}
</script>
用于在setup中定义监视属性
注意:可以同时监视多个变量,只需要多个变量放到一个数组,传到第一个参数即可
<template>
<input type="text" v-model="name">
</template>
<script>
import {ref,watch} from 'vue';
export default {
name: 'App',
setup(){
let name = ref("lucy");
watch(name,(after,before)=>{
console.log(before,after);
})
watch(name,(after,before)=>{
console.log(before,after);
},{immediate: true}) //如果使用immediate:true,那么回调会在组件创建时调用一次
return {name}
}
}
</script>
这个函数的参数是一个回调函数(无参),可以智能的监视这个回调函数里面使用的数据,如果数据发生变化,就会调用该回调,并且在组件创建时调用一次
<template>
<input type="text" v-model="name">
</template>
<script>
import {ref,watchEffect} from 'vue';
export default {
name: 'App',
setup(){
let name = ref("lucy");
watchEffect(()=>{
console.log(before,after);
})
return {name}
}
}
</script>
创建一个ref对象,其value值指向另一个响应式对象中的某个属性,这个value也是响应式的
setup(){
let student = reactive({
name: 'lucy',
age: 18,
clazz: {
level: 9
}
})
let name = toRef(student,'name');
let level = toRef(student.clazz,'level');
return {name}
}
可以将一个响应式对象中的所有属性(第一层属性)都变成响应式对象,也就是不会将下面level变成响应式
setup(){
let student = reactive({
name: 'lucy',
age: 18,
clazz: {
level: 9
}
})
let stu = toRefs(student);
return {name}
}
可以将一个响应式对象转换为一个普通对象并返回
1、由于vue3中setup函数的执行时机要比beforeCreate早,所以在setup中无法拿到this
2、由于vue3不是使用Vue构造进行构建,而是使用App,所以如果要挂载一些属性到Vue原型对象上,方法和vue2不同
例如挂载axios
// 引入axios
import axios from 'axios';
const app = createApp(App);
//挂载全局属性
app.config.globalProperties.$axios = axios;
app.use(router).mount("#app");
在组件中使用
setup(){
const{proxy} = getCurrentInstance();
proxy.$axios.get();
}
Hook的本质就是一个函数,是对setup函数里面的组合式API进行封装,类似于Vue2中的mixin
选项式 API | Hook inside setup |
---|---|
beforeCreate |
setup |
created |
setup |
beforeMount |
onBeforeMount |
mounted |
onMounted |
beforeUpdate |
onBeforeUpdate |
updated |
onUpdated |
beforeUnmount |
onBeforeUnmount |
unmounted |
onUnmounted |
errorCaptured |
onErrorCaptured |
renderTracked |
onRenderTracked |
renderTriggered |
onRenderTriggered |
activated |
onActivated |
deactivated |
onDeactivated |
import {onMounted} from 'vue'
<script>
export default {
name: 'Demo',
setup() {
// 可以在setup中直接写
onMounted(() => {
})
}
}
</script>
在src/hooks/
中新建一个js文件,将多组件复用的组合式API抽离,并将组件需要的属性返回即可
import {ref} from 'vue';
export default () => {
//此处写组合式API的逻辑
let name = ref('lucy');
return name;
}
在需要该组合API的组件中引入并调用,一般函数名以use开头
import useName from '@/hooks/name.js';
<script>
export default {
name: 'Demo',
setup() {
// 在setup中调用,并接收参数
let name = useName();
return {name}
}
}
</script>
在vue2中,所有组件必须有跟标签
在vue3中,组件可以没有跟标签,所有元素在Fragment虚拟元素中
可以将指定的html结构移动到指定位置
<template>
<!-- 传送到body标签中 -->
<teleport to="body">
<input/>
</teleport>
</template>
vue2 | vue3 |
---|---|
Vue.config.productionTip | 移除 |
Vue.config.ignoredElements | app.config.isCustomElement() |
Vue.component | app.component |
Vue.directive | app.directive |
Vue.mixin | app.mixin |
Vue.use | app.use() |
Vue.filter | 移除 |
Vue.prototype | app.config.globalProperties |
1、移除v-on.native
2、由于vue3中setup没有this,所以获取ref的方法有所改变
<template>
<input type="text" ref="inputRef">
</template>
<script>
import { onMounted, ref } from 'vue'
/*
ref获取元素: 利用ref函数获取组件中的标签元素
功能需求: 让输入框自动获取焦点
*/
export default {
setup() {
const inputRef = ref(null)
onMounted(() => {
inputRef.value.focus()
})
return {
inputRef
}
},
}
</script>