Hable sobre ref y reactivo en Vue3

1. ¿Qué es?

Ref y reactivo son las API utilizadas para implementar la capacidad de respuesta de datos en Vue 3. En
general, refdefina tipos de datos básicos y reactivedefina tipos de datos de referencia
(me gusta usarlo para definir objetos, no para definir matrices, la razón se explicará más adelante)
Entiendoref es esencialmente un reempaquetado de reactivo

Segundo, reactivo

Reactivo define tipos de datos de referencia (por ejemplo, objetos y matrices), que pueden declarar las propiedades internas o elementos de datos de tipos de datos complejos como datos de respuesta, por lo que la capacidad de respuesta de reactivo es profunda y su capa inferior es implementar datos a través de ES6 ResponsiveProxy , a diferencia de Vue2 Object.defineProperty, tienePuede monitorear las operaciones de adición y eliminación, y puede monitorear los cambios en las propiedades de los objetosEtc

Ejemplo de uso de reactivos para definir el tipo de datos del objeto

const paginationConfig = reactive({
    
    
	pageNum: 1,
	pageSize: 10
}) // 定义

const onChange = () => {
    
    
	paginationConfig.pageNum = 2 // js使用
	paginationConfig.pageSize = 20 // js使用
}
<!-- Vue3模板引用使用 -->
<a-pagination v-model:current="paginationConfig.pageNum"></a-pagination>

Si usa reactivo para definir el tipo de datos básico, Vue3 informará un error de advertencia, como se muestra en la figura

const str = reactive('我是字符串')

error de la consola
Análisis de código fuente
El análisis del código fuente de Vue3 muestra que cuando se usa reactivo para definir datos receptivos, si los datos no son un tipo de objeto y se devuelven directamente, no se realizará el procesamiento receptivo de datos posterior. Es por eso que solo uso reactivo para definir el tipo de objeto datos de respuesta. , ¿qué pasa con los datos de tipo de matriz? La respuesta se puede encontrar a continuación

3. Hablemos de ref.

¿Por qué entiendo que ref es un reempaquetado de reactivo, porque en el código fuente subyacente de ref, finalmente se implementa mediante reactivo ().
inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí
Según el análisis del código fuente,Si es un tipo de objeto, la lógica subyacente sigue siendo reactiva()Además, sabemos que al usar ref para definir tipos de datos básicos, se deben agregar sufijos cuando se usan en scripts, .valuepero no en plantillas, porque Vue3 los agregará automáticamente, lo que hace que ref sea más simple que reactivo.

let num = ref(0) // 定义
let isShow = ref(false)  // 定义

const onChange = () => {
    
    
	num.value++  // js使用
	isShow.value = true  // js使用
}
<!-- Vue3模板引用使用 -->
<a-modal v-model:visible="isShow"></a-modal>

Cuatro, comparación de matriz de definición reactiva y ref

Un ejemplo del uso de ref para definir una matriz es el siguiente

const tableData = ref([]) // 定义

const getTableData = async () => {
    
    
	const {
    
     data } = await getTableDataApi() // 模拟接口获取表格数据
	tableData.value = data // 修改
}
<!-- Vue3模板引用使用 -->
<a-table v-model:dataSource="tableData"></a-table>

En la figura, tomamos nuestros datos de tabla de uso común como ejemplo. Puede ver que no hay diferencia entre la definición de matrices de referencia y la definición de tipos de datos básicos. A continuación, veamos los datos reactivos.

const tableData = reactive([]) // 定义

const getTableData = async () => {
    
    
	const {
    
     data } = await getTableDataApi() // 模拟接口获取表格数据
	tableData = data // 修改,错误示例,这样赋值会使tableData失去响应式
}
<!-- Vue3模板引用使用 -->
<a-table v-model:dataSource="tableData"></a-table>

Tenga en cuenta que usandotableData = datosEl método de modificación hará que tableDatapérdida de respuesta, la solución es la siguiente (para referencia)

// 方法一:改为 ref 定义
const tableData = ref([])
const getTableData = async () => {
    
    
	const {
    
     data } = await getTableDataApi()
	tableData.value = data // 使用.value重新赋值
}
// 方法二:使用 push 方法
const tableData = reactive([])
const getTableData = async () => {
    
    
	const {
    
     data } = await getTableDataApi()
	tableData.push(...data) // 先使用...将data解构,再使用push方法
}
// 方法三:定义时数组外层嵌套一个对象
const tableData = reactive({
    
     list:[] })
const getTableData = async () => {
    
    
	const {
    
     data } = await getTableDataApi()
	tableData.list = data // 通过访问list属性重新赋值
}
// 方法四:赋值前再包一层 reactive
const tableData = reactive([])
const getTableData = async () => {
    
    
	const {
    
     data } = await getTableDataApi()
	tableData = reactive(data) // 赋值前再包一层reactive
}

5. Resumen comparativo

  1. refSe usa para definir tipos básicos y tipos de referencia, reactivesolo se usa para definir tipos de referencia
  2. reactiveProxyLa razón por la que solo se puede usar para definir tipos de datos de referencia es que la implementación interna Proxyresponde a través de ES6 y no es aplicable a los tipos de datos básicos.
  3. refAl definir un objeto, la capa inferior se transformará reactiveen un objeto receptivo con un nivel profundo, por lo que ref es esencialmente un reempaquetado de reactivo
  4. refCuando utilice los datos definidos en el script , recuerde agregar .valueel sufijo
  5. Al definir una matriz, se recomienda utilizarla refpara evitar reactiveel problema de la pérdida de capacidad de respuesta causada por la modificación del valor durante la definición.

おすすめ

転載: blog.csdn.net/poppingJ/article/details/125429506