欢迎各位兄弟 发布技术文章
这里的技术是共享的
本文章向大家介绍浅析Vue3相关基础知识点:setup()入口函数、ref()定义响应式数据、reactive()定义多个响应式数据-深层的、toRefs()转换为每个属性都是一个ref、computed()计算属性、watch()监听数据、watchEffect()监听数据变化执行回调、生命周期对比、provide/inject跨层级组件通信,主要包括浅析Vue3相关基础知识点:setup()入口函数、ref()定义响应式数据、reactive()定义多个响应式数据-深层的、toRefs()转换为每个属性都是一个ref、computed()计算属性、watch()监听数据、watchEffect()监听数据变化执行回调、生命周期对比、provide/inject跨层级组件通信使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
setup
是组合Composition API
中的入口函数,也是第一个要使用的函数。
1、setup
只在初始化时执行一次,所有的Composition API
函数都在此使用。
2、setup
是在beforeCreate
生命周期之前执行的(只执行一次)
beforeCreate() {
console.log('beforeCreate执行了');
},
setup() {
console.log('setup执行了');
return {};
},
//setup执行了
//beforeCreate执行了
由此可以推断出setup
执行的时候,组件对象还没有创建,组件实例对象this
还不可用,此时this
是undefined
, 不能通过this
来访问data/computed/methods/props
。
3、返回对象中的属性会与data
函数返回对象的属性合并成为组件对象的属性,返回对象中的方法会与methods
中的方法合并成功组件对象的方法,如果有重名,setup
优先。
因为在setup
中this
不可用,methods
中可以访问setup
提供的属性和方法, 但在setup
方法中不能访问data
和methods
里的内容,所以还是不建议混合使用。
4、setup
函数如果返回对象, 对象中的 属性 或 方法 , 模板 中可以直接使用
//templete
<div>{{number}}</div>
//JS
setup() {
const number = 18;
return {
number
};
},
5、注意:setup
不能是一个async
函数: 因为返回值不再是return
的对象,而是promise,
模板中就不可以使用return
中返回对象的数据了。
6、setup的参数(props,context)
(1)props: 是一个对象,里面有父级组件向子级组件传递的数据,并且是在子级组件中使用 props
接收到的所有的属性
(2)context:上下文对象,可以通过es6
语法解构 setup(props, {attrs, slots, emit})
attrs:获取当前组件标签上所有没有通过props
接收的属性的对象, 相当于 this.$attrs
slots:包含所有传入的插槽内容的对象,相当于 this.$slots
emit:用来分发自定义事件的函数,相当于 this.$emit
1、作用:定义一个响应式的数据(一般用来定义一个基本类型的响应式数据Undefined
、Null
、Boolean
、Number
和String
)
2、语法:const xxx = ref(initValue);
注意:script
中操作数据需要使用xxx.value
的形式,而模板中不需要添加.value
3、ref 用于定义响应式数据
// 用一个例子来演示:实现一个按钮,点击可以增加数字
<template>
<div>{{count}}</div>
<button @click='updateCount'>增加</button>
</template>
// 在Vue3中
setup() {
// ref用于定义一个响应式的数据,返回的是一个Ref对象,对象中有一个value属性
//如果需要对数据进行操作,需要使用该Ref对象的value属性
const count = ref(0);
function updateCount() {
count.value++;
}
return {
count,
updateCount,
};
},
4、ref 用于获取 dom 节点:在Vue2
中我们通过this.$refs
来获取dom
节点,Vue3
中我们通过ref
来获取节点
首先需要在标签上添加 ref='xxx'
,然后再setup
中定义一个初始值为null
的ref
类型,名字要和标签的ref
属性一致
const xxx = ref(null)
注意:一定要在setup
的return
中返回,不然会报错。
// 还是用一个例子来演示:让输入框自动获取焦点
<template>
<h2>App</h2>
<input type="text" ref="inputRef">
</template>
<script lang="ts">
import { onMounted, ref } from 'vue'
/*
ref获取元素: 利用ref函数获取组件中的标签元素
功能需求: 让输入框自动获取焦点
*/
export default {
setup() {
const inputRef = ref<HTMLElement|null>(null)
onMounted(() => {
inputRef.value && inputRef.value.focus()
})
return {
inputRef
}
},
}
</script>
1、语法:const proxy = reactive(obj)
2、作用:定义多个数据的响应式,接收一个普通对象然后返回该普通对象的响应式代理器对象(Proxy)
,响应式转换是“深层的”:会影响对象内部所有嵌套的属性,所有的数据都是响应式的。
<template>
<h3>姓名:{{user.name}}</h3>
<h3>wife:{{user.wife}}</h3>
<button @click="updateUser">更新</button>
</template>
setup() {
const user = reactive({
name: '**',
wife: {
name: 'xioaohong',
age: 18,
books: [],
},
});
const updateUser = () => {
user.name = '小红';
user.age += 2;
user.wife.books[0] = '**';
};
return {
user,
updateUser,
};
},
1、作用:把一个响应式对象转换成普通对象,该普通对象的每个属性都是一个 ref
2、应用:我们使用 reactive
创建的对象,如果想在模板中使用,就必须得使用 xxx.xxx
的形式;如果大量用到的话还是很麻烦的,但是使用 es6
解构以后,会失去响应式。
那么toRefs
的作用就体现在这,利用toRefs
可以将一个响应式 reactive
对象的所有原始属性转换为响应式的ref
属性。
<template>
<div>
name:{{name}}
</div>
</template>
<script lang='ts'>
import { defineComponent, reactive, toRefs } from 'vue';
export default defineComponent({
name: '',
setup() {
const state = reactive({
name: 'hzw',
});
const state2 = toRefs(state);
setInterval(() => {
state.name += '===';
}, 1000);
return {
//通过toRefs返回的对象,解构出来的属性也是响应式的
...state2,
};
},
});
</script>
1、与Vue2
中的computed
配置功能一致,返回的是一个ref
类型的对象
2、计算属性的函数中如果只传入一个回调函数 表示的是get
操作
3、计算属性的函数中可以传入一个对象,可以包含set
和get
函数,进行读取和修改的操作
const fullName2 = computed({
get() {
return user.firstName + '_' + user.lastName;
},
set(val: string) {
const names = val.split('_');
user.firstName = names[0];
user.lastName = names[1];
},
});
return {
user,
fullName2,
};
1、与Vue2
中的watch
配置功能一致:(1)参数1 - 要监听的数据;(2)参数2 - 回调函数;(3)参数3 - 配置。
2、作用:监视指定的一个或多个响应式数据,一旦数据变化,就自动执行监视回调。
(1)默认初始时不执行回调,但可以通过配置 immediate
为true
来指定初始时立即执行第一次
(2)通过配置 deep
为true
来指定深度监视
import { watch, ref } from 'vue';
const user = reactive({
firstName: '**',
lastName: '**',
});
const fullName3 = ref('');
watch(
user,
({ firstName, lastName }) => {
fullName3.value = firstName + '_' + lastName;
},
{ immediate: true, deep: true }
);
return {
user,
fullName3,
};
3、watch
监听多个数据,使用数组
4、watch
监听非响应式数据的时候需要使用回调函数的形式
1、作用:监视数据发生变化时执行回调,不用直接指定要监视的数据,回调函数中使用的哪些响应式数据就监视哪些响应式数据,
2、默认初始时就会执行第一次,从而可以收集需要监视的数据。
import { watchEffect, ref } from 'vue';
const user = reactive({
firstName: '**',
lastName: '**',
});
const fullName4 = ref('');
watchEffect(() => {
fullName4.value = user.firstName + '_' + user.lastName;
});
return {
user,
fullName4,
};
注意:3.0
中的生命周期钩子要比2.X
中相同生命周期的钩子要快
setup() {
onBeforeMount(() => {
console.log('--onBeforeMount')
})
onMounted(() => {
console.log('--onMounted')
})
......
onBeforeUnmount(() => {
console.log('--onBeforeUnmount')
})
onUnmounted(() => {
console.log('--onUnmounted')
})
}
作用:实现跨层级组件(祖孙)间通信
// 父组件
setup() {
const color = ref('red')
provide('color', color)
return {
color
}
// 孙子组件
setup() {
const color = inject('color')
return {
color
}
这个 vue2 里也有,差不多一样的用法。
来自 http://www.manongjc.com/detail/26-krnsyulausdxmlq.html