我有两个组件,我想通过provide一个响应式对象实现父子之间的双向数据传输,但是我发现对象类型可以正确实现响应式,但是基本数据类型无法实现,请问这是为什么?
我个人的猜想是选项式的api会对基本数据类型触发自动解包,但是setup函数里面不会触发,因此造成了不一致的问题。
//父组件
<script>
import Child from './Child.vue'
import { computed } from 'vue'
export default {
components: { Child },
data() {
return {
message: {"name":"hello"},flag:false
}
}, methods:{
change()
{
this.flag=!this.flag
}
},
provide() {
return {
message: this.message,flag:this.flag
}
}
}
</script>
<template>
<div>
<input v-model="message.name">
<button @change="change">click</button>
{{ flag}}
</div>
<Child />
</template>
//子组件
<script>
export default {
inject:["message","flag"],
methods:{
change()
{
this.flag=!this.flag
}
}
}
</script>
<template>
<div>
<input v-model="message.name">
<button @change="change">click</button>
{{ flag}}
</div>
</template>
尝试:我查阅官方文档发现data返回的都是响应式对象,并且使用setup函数传递基本数据类型可以正确传递.
预期结果:使用选项式的provide传递基本数据类型时可以实现双向绑定
我一般会通过 provide
暴露出来两个函数,而不是直接暴露原本的响应式对象给子级来直接修改。
一个函数是获取响应式对象的函数,一个是给响应式对象更新的函数。
举个例子:
<!-- 在供给方组件内 -->
<script setup>
import { provide, ref } from 'vue'
const location = ref('North Pole')
provide('location', {
getLocation: () => location,
updateLocation: (newValue) => location.value = newValue
})
</script>
<!-- 在注入方组件 -->
<script setup>
import { inject, computed } from 'vue'
const { getLocation, updateLocation } = inject('location')
const location = computed(() => getLocation())
</script>
<template>
<button @click="updateLocation('newValue')">{{ location }}</button>
</template>
不过我看现在 Vue3 最新的文档,已经不需要通过函数返回的方式,来保持 provide
变量的响应式了,那么就可以直接和文档中的一样这样写:
<!-- 在供给方组件内 -->
<script setup>
import { provide, ref } from 'vue'
const location = ref('North Pole')
function updateLocation() {
location.value = 'South Pole'
}
provide('location', {
location,
updateLocation
})
</script>
<!-- 在注入方组件 -->
<script setup>
import { inject } from 'vue'
const { location, updateLocation } = inject('location')
</script>
<template>
<button @click="updateLocation">{{ location }}</button>
</template>
#和响应式数据配合使用 依赖注入 | Vue.js
在 Vue 的选项式 API 中,provide
和 inject
主要用于依赖注入,它们并不直接支持基本数据类型的双向绑定。当你在 provide
方法中直接返回非响应式引用(比如基本数据类型 boolean
、number
、string
等)时,你其实是在传递一个值的副本,而不是对原始数据的引用。因此,当在父组件或子组件中修改这个值时,并不会影响到对方组件。
为了使用 provide
和 inject
来进行基本数据类型的“双向数据传输”(注意这并不是真正的双向绑定,但可以实现类似的功能),你需要在 provide
中提供的是一个可以被修改的对象或响应式引用,而不是基本数据类型。
对于基本数据类型,你可以通过提供一个对象或响应式引用来封装它们,然后在父组件和子组件中修改这个对象的属性来实现类似的效果。
但是,对于你给出的代码示例,即使你尝试通过对象封装基本数据类型(如 flag
),由于你直接在 provide
中返回了 this.flag
的值(一个基本数据类型的副本),它仍然不会按预期工作。
以下是一个修改后的示例,展示了如何使用一个响应式对象来封装基本数据类型,并通过 provide
和 inject
在父子组件之间共享它:
// 父组件
<script>
import { reactive, toRefs } from 'vue';
import Child from './Child.vue';
export default {
components: { Child },
setup() {
const state = reactive({
message: { name: "hello" },
flag: false
});
function changeFlag() {
state.flag = !state.flag;
}
return {
...toRefs(state),
changeFlag
};
},
provide() {
return {
// 注意这里返回的是整个响应式对象
// 或者,你也可以通过 `toRefs` 将状态分解为响应式引用并返回
state: this.state
};
}
};
</script>
<template>
<div>
<input v-model="state.message.name">
<button @click="changeFlag">click</button>
{{ state.flag }}
</div>
<Child />
</template>
// 子组件
<script>
export default {
inject: ["state"],
methods: {
changeFlag() {
this.state.flag = !this.state.flag;
}
}
};
</script>
<template>
<div>
<input v-model="state.message.name">
<button @click="changeFlag">click</button>
{{ state.flag }}
</div>
</template>
在这个修改后的示例中,我们使用了 Vue 3 的 setup
函数和 reactive
API 来创建一个响应式状态对象。然后我们使用 provide
来共享这个状态对象,并在父组件和子组件中都通过 inject
来接收它。现在,当我们修改 state.flag
时,无论是在父组件还是子组件中,都会影响到另一个组件。
本文向大家介绍Vue实现双向数据绑定,包括了Vue实现双向数据绑定的使用技巧和注意事项,需要的朋友参考一下 Vue实现双向数据绑定的方式,具体内容如下 Vue是如何实现双向数据绑定的呢?答案是前端数据劫持。其通过Object.defineProperty()方法,这个方法可以设置getter和setter函数,在setter函数中,就可以监听到数据的变化,从而更新绑定的元素的值。 实现对象属性变化
本文向大家介绍Vue.js中provide/inject实现响应式数据更新的方法示例,包括了Vue.js中provide/inject实现响应式数据更新的方法示例的使用技巧和注意事项,需要的朋友参考一下 vue.js官方文档:https://cn.vuejs.org/v2/api/#provide-inject 首先假设我们在祖辈时候传入进来是个动态的数据,官方不是说如果你传入了一个可监听的对象,
变量只是用于存储值的保留内存位置。 这意味着当您创建变量时,您会在内存中保留一些空间。 根据变量的数据类型,操作系统分配内存并决定可以存储在保留内存中的内容。 因此,通过为变量分配不同的数据类型,可以在这些变量中存储整数,小数或字符。 Java中有两种数据类型 - 原始数据类型 参考/对象数据类型 原始数据类型 Java支持八种原始数据类型。 原始数据类型由语言预定义,并由关键字命名。 现在让我们
着色器语言GLSL的基本数据类型和C语言一样具有常见的整型数int、浮点数float和布尔值bool类型数据。 关键字 数据类型 值 bool 布尔值 布尔变量值为true或false int 整型数 值为整数,比如0,1,2,3... float 单精度浮点数 浮点数用小数点表示,比如0.6,3.14,2.8 // bool关键字声明一个数据类型是布尔值的变量,并赋值为true bool lig
在之前的 JavaScript 基础文章中(编号 02、编号 07),我们介绍过,变量有以下数据类型: 基本数据类型(值类型):String 字符串、Number 数值、Boolean 布尔值、Null 空值、Undefined 未定义。 引用数据类型(引用类型):Object 对象。 本文,我们针对这两种类型,做个详细介绍。我们先来看个例子。 基本数据类型举例: var a = 23;
1. 前言 本小节我们将介绍 Vue 中数据的双向绑定指令 v-model。v-model 的学习相对简单 我们可以用 v-model 指令在表单 、 及 元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。它负责监听用户的输入事件以更新数据,并对一些极端场景进行一些特殊处理。 2. 慕课解释 用 v-model 指令在表单 、 及 元素上创建双向数据绑定。它会根据控件类型自动选