defineComponent
- defineComponent可以给组件的setup方法准确的参数类型定义.
- defineComponent 可以接受显式的自定义 props 接口或从属性验证对象中自动推断
- defineComponent 可以正确适配无 props、数组 props 等形式
- 引入 defineComponent() 以正确推断 setup() 组件的参数类型
setup是一个函数。
- 新的option,所有的组合API函数都在此使用,只在初始化时执行一次。
- 函数如果返回对象,对象中的属性或方法,模板中可以直接使用。
- 代替beforeCreate和Created这两个生命周期 setup执行在beforeCreate之前且执行一次 此时this是
undefined - 两个参数props和context=
{$attrs,$slots,$emit}
ref
ref 创建响应式数据
const count = ref(0);
ref是一个函数,返回的是一个Ref对象。- 作用:用来定义一个响应式的数据。
- 一般用来定义一个基本类型的响应式数据,如果想要定义一个对象类型的响应式数据可以使用函数
reactive。
ref 获取页面元素
ref函数可以获取页面中已经加载完毕的元素。
<template>
<!-- 1. 在标签中使用 ref 属性绑定一个数据 -->
<input type="text" id="demo" ref="inputRef" />
</template>
<script lang="ts">
import { defineComponent, onMounted, ref } from "vue";
export default defineComponent({
setup() {
//2. 调用ref创建初始值为null的响应数据
const inputRef = ref < HTMLElement | null > (null);
onMounted(() => {
//3. 在生命周期函数onMounted页面已经渲染好了,可以在这里拿到页面的元素
console.log(inputRef.value);
//<input type="text" id="demo">
//表示标签存在时,就让该标签自动获取焦点
inputRef.value && inputRef.value.focus();
});
return {
inputRef,
};
},
});
</script>
toRef
const state = reactive({
age: 5,
money: 100,
})
const age = toRef(state, "age")
toRefs
- toRefs 函数可以将一个响应式对象转换为一个普通的对象,该对象的每个属性都是独立的 ref 对象。
- 返回的对象可以进行解构,每个属性都可以像普通的 ref 对象一样访问和修改,而且会保持响应式的关联。
toRefs 的使用场景主要是在将响应式对象作为属性传递给子组件时,确保子组件可以正确地访问和更新这些属性。
reactive
reactive是一个函数,返回一个代理对象Proxy。- 作用:用来定义多个响应式的数据。
const proxy = reactive(obj): 接收一个普通对象然后返回该普通对象的响应式代理器对象。obj是被代理的对象,proxy是代理对象。- 响应式转换是深层的:会影响对象内部所有嵌套的属性。
- 内部基于 ES6 的 Proxy 实现,通过代理对象操作源对象内部数据都是响应式的。
reactive函数接收一个普通对象作为参数,然后返回该普通对象的代理对象Proxy通过代理对象添加属性、或删除属性可以同时更改代理对象与被代理对象,并且还可以实时渲染到界面。但是通过被代理对象操作,也是可以更改被代理对象的,但是不可以渲染到界面。
响应式原理
Proxy 文档:developer.mozilla.org/zh-CN/docs/…
Reflect 文档:developer.mozilla.org/zh-CN/docs/…
- 先通过 Proxy 代理对象拦截目标对象的任意属性的任意(13种)操作,包括属性值的读写、属性的添加,、属性的删除等。
- 然后通过 Reflect 反射对象,动态地对被代理对象的相应属性进行特定的操作。
<script type="text/javascript">
//1. 目标对象(被代理对象)
const user = {
name: '张三',
wife: {
name: '小樱'
}
}
//2. 代理对象
const proxyUser = new Proxy(user, {
//获取目标对象的属性值
get(target, prop) {
return Reflect.get(target, prop)
},
//修改或新增目标对象的属性
set(target, prop, val) {
return Reflect.set(target, prop, val)
},
//删除目标对象属性
deleteProperty(target, prop) {
return Reflect.deleteProperty(target, prop)
}
})
//3. 通过代理对象获取属性
console.log(proxyUser.name)
//张三
//4. 通过代理对象更改属性
proxyUser.name = '王五'
console.log(user)
//{name: '王五', wife: {…}}
//5. 通过代理对象添加新属性
proxyUser.gender = '男'
console.log(user)
//{name: '王五', wife: {…}, gender: '男'}
//6. 通过代理对象删除属性
delete proxyUser.gender
console.log(user)
//{name: '王五', wife: {…}}
</script>
computed计算属性
/* 语法1 */
//当只传入一个回调函数时,该回调函数默认为get函数
//当targetValue发送变化时,computed能够监视到数据的变化,并将变化后的值返回
//computed函数返回一个ComputedRef对象,是一个响应式的对象
const returnVal = computed(() => {
return targetValue
})
/* 语法2 */
//当需要get与set函数时,应该传入一个对象
//当returnVal发送改变时,val就是returnVal改变后的值
const returnVal = computed({
get() { return targetValue }
set(val) { targetValue = val }
})
watch监视
1. 调用语法
/* 语法1:只监视一个数据 */
//data:被监视的数据
//(val) => {}:当data发生变化时该回调函数就会被调用
//val:就是data发生变化后的新数据
//immediate:true则默认自动执行一次,因为当obj发生变化时回调才会被调用,newObj才有值,
// 但是首次初始化obj时obj并没有发生变化,newObj就是一个空对象。
//deep:true则进行深度监视,即obj可能有多层嵌套,每一层都会被监视;false则只监视obj对象的第一层
watch(data, (val) => {}, {immediate: true, deep: true})
//如果data是一个对象{lastName: '', firstName: ''},也可以如下写
watch(data, ({lastName, firstName}) => {}, {immediate: true, deep: true})
/* 语法2:监视多个数据 */
//当 obj.val1 不是响应式数据时,需要以 ()=>obj.val1 声明才能被监视到
//vals是一个数组,顺序就是 [()=>obj.val1, ()=>obj.val2] 的顺序
watch([()=>obj.val1, ()=>obj.val2], (vals) => {})
watchEffect监视
watchEffect与watch的区别是:watchEffect不需要配置{ immediate: true, deep: true },默认初始化时就执行一次并可以深层监视。
1. 调用语法
//直接将targetObj放入回调函数就可以监视targetObj对象的变化了
watchEffect(() => { targetObj })
生命周期
vue2中的生命周期加on重命名
原文在[这里](https://www.kancloud.cn/king_om/uikuangjiazongjie/2734074)