一、创建vue3项目
1、创建vue3的项目
vue create my-app
2、选择vue3,然后回车安装
二、vue3中setup的使用
1、setup在组件中的写法
<template>
<div class="home">
{{name}}
</div>
</template>
<script>
// @ is an alias to /src
import {ref} from 'vue'
export default {
setup(){
let name=ref('444')
return{
name
}
}
}
</script>
执行结果:
2、setup函数是处于生命周期函数beforeCreate和created两个钩子函数之前的函数,在setup函数中是无法使用data和methods中的数据和方法
<template>
<div class="home">
{{name}}
</div>
</template>
<script>
// @ is an alias to /src
import {ref} from 'vue'
export default {
created(){
console.log('created');
},
setup(){
let name=ref('444')
console.log(name);
return{
name
}
},
beforeCreate(){
console.log('beforeCreate');
}
}
</script>
执行结果:
3.在setup函数中定义的变量和方法最后要return,不然无法使用
(1)有return:
<template>
<div class="home">
{{name}}
</div>
</template>
<script>
// @ is an alias to /src
import {ref} from 'vue'
export default {
setup(){
let name=ref('444')
return{
name
}
}
}
</script>
执行结果:
(2)无return:
<template>
<div class="home">
{{name}}
</div>
</template>
<script>
// @ is an alias to /src
import {ref} from 'vue'
export default {
setup(){
let name=ref('444')
console.log(name);
return{
// name
}
}
}
</script>
执行结果:
4、setup中使用的响应式数据绑定ref、reactive
(1)ref用于基本数据类型的绑定和引用类型的绑定
核心原理:如果使用的是基本数据类型响应式依赖Object.defineProperty()的get()和set()
如果是引用数据类型,ref会借助reactive的proxy定义响应式
<template>
<div class="home">
{{name}}
</div>
</template>
<script>
// @ is an alias to /src
import {ref} from 'vue'
export default {
setup(){
let name=ref('444')//基本类型
//通过.value获取数据
console.log(name);
//打印结果
// RefImpl {__v_isShallow: false, dep: undefined, __v_isRef: true, _rawValue: '444', _value: '444'}
// dep: Set(1)
// [[Entries]]
// 0: ReactiveEffect
// n: 0
// w: 0
// size: 1
// [[Prototype]]: Set
// __v_isRef: true
// __v_isShallow: false
// _rawValue: "444"
// _value: "444"
// value: "444"
// [[Prototype]]: Object
let arr=ref([])//引用数据类型 ref会借助reactive的proxy
arr.value=[1,2,3,4]
console.log(arr);
//打印结果
//RefImpl {__v_isShallow: false, dep: undefined, __v_isRef: true, _rawValue: Array(4), _value: Proxy}
// dep: undefined
// __v_isRef: true
// __v_isShallow: false
// _rawValue: (4) [1, 2, 3, 4]
// _value: Proxy
// [[Handler]]: Object
// [[Target]]: Array(4)
// [[IsRevoked]]: false
// value: Proxy //ref使用是数组,ref会借助reactive的proxy
// [[Handler]]: Object
// [[Target]]: Array(4)
// 0: 1
// 1: 2
// 2: 3
// 3: 4
// length: 4
// [[Prototype]]: Array(0)
// [[IsRevoked]]: false
// [[Prototype]]: Object
return{
name,
arr
}
}
}
</script>
在setup方法中通过ref实现响应式对象,最后在return中返回,如果ref使用的是对象或者数组,ref会借助reactive生成proxy
(2)reactive主要是基于引用类型的绑定
核心原理:基于Es6的proxy实现,通过Reflect反射代理操作源对象,相对于reactive定义的浅层次响应式数据对象,reactive定义的是更深层次的响应式数据对象
<template>
<div class="home">
{{name}}
</div>
</template>
<script>
// @ is an alias to /src
import {reactive} from 'vue'
export default {
setup(){
//reactive无法定义基本类型的proxy,且设置值无法响应数据
let name=reactive('444')
console.log(name);
//打印结果
//444
//如果reactive使用的是引用类型
let arr=reactive([1,2,3,4,5])
console.log(arr)
//打印结果
// Proxy {0: 1, 1: 2, 2: 3, 3: 4, 4: 5}
// [[Handler]]: Object
// [[Target]]: Array(5)
// 0: 1
// 1: 2
// 2: 3
// 3: 4
// 4: 5
// length: 5
// [[Prototype]]: Array(0)
// [[IsRevoked]]: false
return{
name,
}
}
}
</script>
5、toRefs的使用
toRefs可以把一个响应式对象转换为普通对象,每个值都是ref,用.value获取值
<template>
<div class="home">
{{name}}
</div>
</template>
<script>
// @ is an alias to /src
import {reactive} from 'vue'
export default {
setup(){
let arr=reactive([1,2,3,4,5])
let state=toRefs(arr)
console.log(state)
return{
arr,
state,
}
}
}
</script>
执行结果:
6、vue3中的生命周期函数
vue3中的生命周期函数都是从vue中导入,在进行调用
<script>
// @ is an alias to /src
//引入
import {onBeforeMount,onMounted,onBeforeUpdate,onUpdated,onBeforeUnmount,onUnmounted} from 'vue'
export default {
setup(){
onBeforeMount(()=>{
//在挂载前执行
})
onMounted(()=>{
//在挂载后执行
})
onBeforeUpdate(()=>{
//在更新前执行
})
onUpdated(()=>{
//在更新后执行
})
onBeforeUnmount(()=>{
//在组件销毁前执行
})
onMounted(()=>{
//在组件销毁后执行
})
return{
}
}
}
</script>
7、vue3的watch监听
(1)监听ref的值
首先引入
import {watch} from 'vue'
使用:第一个值:数组形式监听的值,第二个值为执行函数,当监听的值发生变化(newValue:改变后的值,aldValue:改变前的值),第三个值为深度监视deep或默认执行
<template>
<div class="home">
{{name}}
<input type="text" v-model="name">
</div>
</template>
<script>
// @ is an alias to /src
import {ref,watch} from 'vue'
export default {
setup(){
let name=ref('4444')
//watch监听 数组形式监听的值
watch([name],(newValue,aldValue)=>{
//输出改变后新值和改变前的值
console.log(newValue,aldValue);
})
return{
name
}
}
}
</script>
执行结果:
8、computed的使用
<template>
<div class="home">
<input type="text" v-model="age">
<input type="text" v-model="nextAge">
</div>
</template>
<script>
// @ is an alias to /src
import {computed, ref,} from 'vue'
export default {
setup(){
let age=ref(18)
let nextAge=computed(()=>{
return age.value+1
})
return{
age,
nextAge
}
}
}
</script>
执行结果:
9、父子组件传值,props的使用
父组件:
<template>
<div>
父组件
<div>{{msg}}</div>
//调用子组件
<Child :msg='msg' @changeFather="changeFather"></Child>
</div>
</template>
<script>
//引入子组件
import Child from './Child.vue'
import {ref} from 'vue'
export default {
//注册子组件
components:{
Child
},
setup(){
//传给子组件的值
let msg=ref('我是父组件传来的消息')
//定义一个函数接收子组件传过来的值,默认值val
let changeFather=(val)=>{
msg.value=val
}
return{
msg,
changeFather
}
}
}
</script>
子组件:
<template>
<div>
子组件
<div @click="detailFn">{{msg1}}</div>
</div>
</template>
<script>
import {ref} from 'vue'
export default {
//props接收
props:{
msg:{
type:String,
default:''
}
},
setup(props,ctx){
//setup接收两个参数props,context
//setup函数中的props是响应式的,当传入新的props时,它将被更新
console.log(props);
//定义变量重新赋值
const msg1=ref(props.msg)
let name=ref('yd')
//设点击事件,ctx.exmit把子组件的值传给父组件并修改父组件的值,
let detailFn=()=>{
//触发事件等同于$emit
ctx.emit('changeFather',name.value)
}
return {
msg1,
detailFn
}
}
}
</script>