代码在文末,均可直接复制使用
Este artículo describe principalmente cuestiones como la transferencia de valores y la llamada de componentes padre-hijo.
Directorio de artículos
-
- Problema 1: el componente secundario no puede recibir el valor pasado por el componente principal
- Pregunta 2: Después de modificar el valor aceptado por el componente secundario, se descubrió que el valor del componente principal también cambió.
- Problema 3: el subcomponente acepta un valor, pero la página no se actualiza después de la modificación.
- Problema 4: el hijo pasa el evento principal, el componente principal acepta el valor y la asignación no es válida
- 5, padre del niño
- 6. El padre llama al niño
- 7. Código
Problema 1: el componente secundario no puede recibir el valor pasado por el componente principal
Si el valor del componente principal se asigna durante onMounted, o se asigna de forma asincrónica, como una interfaz , el componente secundario no podrá obtener el valor modificado directamente. Los subcomponentes deben utilizar la supervisión de vigilancia . Busque la vista de vigilancia
del subcomponente son.vue
Pregunta 2: Después de modificar el valor aceptado por el componente secundario, se descubrió que el valor del componente principal también cambió.
Si no desea realizar cambios, debe realizar una asignación de copia profunda cuando el subcomponente la acepte . Se recomienda utilizar copia profunda. Si desea cambiar el valor del componente principal, pase la modificación al evento principal por separado.
Problema 3: el subcomponente acepta un valor, pero la página no se actualiza después de la modificación.
Cuando el subcomponente acepta tipos de datos simples, cámbielo a ref para aceptarlo y generar datos receptivos
. Para obtener más detalles, deje num1VALUE = ref(props.num1) // Generar datos receptivos; de lo contrario, la página de datos modificados no cambiará.
Problema 4: el hijo pasa el evento principal, el componente principal acepta el valor y la asignación no es válida
Esto se debe a que la variable en su componente principal se declara mediante reactivo. reactivo No asignar valor directamente a datos variables =! ! ! Se perderá la capacidad de respuesta. Si usa ref, no necesita asignar valores, o debe usar un solo atributo para asignar valores uno por uno Obj.atributo = valor de atributo, o envuelva una capa adicional de objetos alrededor del objeto original.
由此可见:声明尽量用ref。。。。
5, padre del niño
Vista de búsqueda
update:obj
.
6. El padre llama al niño
sonRef.value.childMethod()
Vista de búsqueda
7. Código
Componente principal far.vue
<template>
<div>
<div>父:{
{
state.str1 }}--{
{
state.data1 }}--{
{
obj1 }} -- {
{
num1 }}</div>
<button style="border: 1px solid cyan;" @click="callChildMethod">父调子事件</button>
<hr>
<son ref="sonRef" :str1="state.str1" :data1="state.data1" :obj1="obj1" :num1="num1" @update:obj="getObj" />
</div>
</template>
<script>
import {
defineComponent, onMounted, reactive ,toRefs,ref} from 'vue'
import Son from './son.vue'
export default defineComponent({
components: {
Son
},
setup() {
const state = reactive({
str1: '',
data1: {
}
})
let obj1 = reactive({
a:1,
})
let num1 = ref(1)
// 父接受子
function getObj(val){
obj1.a = val.a // reactive 不要直接data=赋值!!!会丢失响应式的,如果用ref就不会 非要赋值要不就使用 obj.属性 = 属性值 要不就给原对象多包裹一层对象
// obj1 = val
// obj1 = reactive({
...val})
console.log('父接受子',val,obj1);
}
// 父调用子事件
const sonRef = ref(null)
function callChildMethod() {
sonRef.value.childMethod()
}
onMounted(() => {
// 对于在onMounted或异步的数据 传递给子组件 子组件应该使用watch监听接受 否则拿不到数据
setTimeout(() => {
state.str1 = '二次赋值!'
state.data1 = {
name: 'Alice',
age: 25
}
}, 1000);
})
return {
state,
obj1,
num1,
sonRef,
getObj,
callChildMethod
}
}
})
</script>
Subcomponente son.vue
<template>
<div>
<div>子:{
{
state.str1VALUE }}--{
{
state.data1VALUE }}--{
{
obj1VALUE }} -- {
{
num1VALUE }}</div>
<button style="border: 1px solid cyan;" @click="setVal">按钮该值</button>
<button style="border: 1px solid cyan;" @click="setFarVal">子传父</button>
</div>
</template>
<script>
import {
defineComponent, reactive, watch,toRefs,toRef,ref } from 'vue'
export default defineComponent({
props: {
str1: String,
data1: Object,
obj1: Object,
num1: Number,
},
emits: ['update:obj'],
setup(props, {
emit }) {
const state = reactive({
str1VALUE: '',
data1VALUE: {
}
})
let obj1VALUE = JSON.parse(JSON.stringify(props.obj1)) // 复杂数据类型obj如果不用深拷贝赋值 修改对象obj.name单一属性时候(state.data1VALUE.age = 33) 会导致父组件的源值改变 也会导致监听事件再次执行
let num1VALUE = ref(props.num1) // 生成响应式数据 否则修改数据 页面不变化
// 同时监听str1和data1 对于在onMounted或异步的数据 传递给子组件 子组件应该使用watch监听接受 否则拿不到数据
watch([() => props.str1, () => props.data1], ([str1, data1]) => {
console.log('监听',str1,data1);
state.str1VALUE = JSON.parse(JSON.stringify(str1)) // 复杂数据类型obj如果不用深拷贝赋值 修改对象obj.name单一属性时候(state.data1VALUE.age = 33) 会导致父组件的源值改变 也会导致监听事件再次执行
state.data1VALUE = JSON.parse(JSON.stringify(data1))
}, {
deep:true, immediate: true })
// setTimeout(() => {
// state.str1VALUE = 'str1'
// }, 2000);
function setVal(){
state.str1VALUE = '三次修改赋值'
// state.data1VALUE = {
// name: '张三',
// age: 11
// }
state.data1VALUE.age = 33
obj1VALUE.a = 3
num1VALUE.value = 3
}
// 子传父
function setFarVal(){
let obj = {
a: 123456
}
emit('update:obj', obj);
console.log('子传父',obj);
}
function childMethod(){
console.log('子事件');
}
return {
state,
obj1VALUE,
num1VALUE,
setVal,
setFarVal,
childMethod
}
}
})
</script>