1. ¿Qué es?
Ref y reactivo son las API utilizadas para implementar la capacidad de respuesta de datos en Vue 3. En
general, ref
defina tipos de datos básicos y reactive
defina 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('我是字符串')
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 ().
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, .value
pero 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
ref
Se usa para definir tipos básicos y tipos de referencia,reactive
solo se usa para definir tipos de referenciareactive
Proxy
La razón por la que solo se puede usar para definir tipos de datos de referencia es que la implementación internaProxy
responde a través de ES6 y no es aplicable a los tipos de datos básicos.ref
Al definir un objeto, la capa inferior se transformaráreactive
en un objeto receptivo con un nivel profundo, por lo que ref es esencialmente un reempaquetado de reactivoref
Cuando utilice los datos definidos en el script , recuerde agregar.value
el sufijo- Al definir una matriz, se recomienda utilizarla
ref
para evitarreactive
el problema de la pérdida de capacidad de respuesta causada por la modificación del valor durante la definición.