vue provide传递ref对象 子组件在computed中响应的问题
·
项目场景:
在父组件上provide(ref对象) 子组件无法通过computed完成响应的问题,并进行v-bind 进行项目绑定的问题
下面是我遇到的问题
<!-- eslint-disable vue/multi-word-component-names -->
<template>
<div class="app">
<h2>多状态表单切换系统</h2>
<select v-model="selectValue">
<option value="red">深色模式</option>
<option value="black">浅色模式</option>
</select>
<!-- 切换按钮组 -->
<div class="btn-group">
<button @click="currentForm = LoginForm" class="switch-btn">登录</button>
<button @click="currentForm = RegisterForm" class="switch-btn">注册</button>
<button @click="currentForm = ForgotPwdForm" class="switch-btn">忘记密码</button>
</div>
<!-- KeepAlive包裹动态组件:实现状态缓存 -->
<KeepAlive include="logn,register">
<component :is="currentForm">
<!-- 具名插槽:为不同表单传递自定义标题 -->
<template #title v-if="currentForm === LoginForm">
<h3 class="form-title">用户登录</h3>
</template>
<template #title v-else-if="currentForm === RegisterForm">
<h3 class="form-title">账号注册</h3>
</template>
<template #title v-else>
<h3 class="form-title">密码重置</h3>
</template>
</component>
</KeepAlive>
</div>
</template>
<script setup>
import { shallowRef,ref, provide } from 'vue'
// 导入子组件:setup语法糖下自动局部注册
import LoginForm from './logn.vue'
import RegisterForm from './register.vue'
import ForgotPwdForm from './forget1.vue'
// 响应式组件引用:使用shallowRef避免深层响应式开销
const currentForm = shallowRef(LoginForm)
const selectValue = ref('red')
//使用watch来监视值得变化然后我使用provide来发送change
//我操了本来很简单但provide只能用在setup 中
provide("change",selectValue)
</script>
<style scoped>
.app {
padding: 30px;
max-width: 400px;
margin: 0 auto;
}
.app h2 {
color: #2c3e50;
text-align: center;
margin-bottom: 20px;
}
.btn-group {
display: flex;
gap: 10px;
margin-bottom: 20px;
}
.switch-btn {
flex: 1;
padding: 10px;
background-color: #ecf0f1;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 16px;
}
.switch-btn:hover {
background-color: #bdc3c7;
}
.form-title {
color: #2c3e50;
margin-top: 0;
margin-bottom: 15px;
}
</style>
在父组件中我使用 provide(ref对象)放送了一个ref对象给它的子组件,如下所示,上面的是完整father.vue
const selectValue = ref('red')
//使用watch来监视值得变化然后我使用provide来发送change
//我操了本来很简单但provide只能用在setup 中
provide("change",selectValue)
那我在子组件中如何接收
下面是我错误的做法,以及son.vue 的完整代码
<template>
<div class="form-container" :style="{'background-color':color1}">
<!-- 标题插槽:支持父组件自定义标题 -->
<slot name="title">默认登录标题</slot>
<div class="form-content" >
<input v-model="username" placeholder="请输入用户名" class="form-input" />
<input v-model="password" type="password" placeholder="请输入密码" class="form-input" />
<div class="form-checkbox">
<input type="checkbox" v-model="rememberMe" id="remember" />
<label for="remember">记住我</label>
</div>
<button class="form-btn">登录</button>
</div>
</div>
</template>
<script setup>
import { ref, onMounted, onActivated, onDeactivated,inject, computed, onUpdated} from 'vue'
// 表单绑定数据
const username = ref('')
const password = ref('')
const rememberMe = ref(false)
// 生命周期监听:打印组件状态
onMounted(() => {
console.log('登录表单组件已挂载')
})
onActivated(() => {
console.log('登录表单组件被激活')
})
onDeactivated(() => {
console.log('登录表单组件已缓存')
})
//下面我使用
// const injectedColor = inject('change', 'red') // 默认值 'red'
// 如果父组件提供的是 ref,则直接使用;如果是普通值,则创建 ref
// const color = ref(injectedColor)
const color =ref('red')
color.value= inject('change')
// 计算属性:返回颜色值
const color1 = computed(() => {
return color.value
})
</script>
<style scoped>
.form-container {
border: 1px solid #eee;
border-radius: 8px;
padding: 20px;
width: 350px;
}
.form-input {
width: 100%;
padding: 10px;
margin: 8px 0;
border: 1px solid #ddd;
border-radius: 4px;
box-sizing: border-box;
}
.form-checkbox {
margin: 10px 0;
font-size: 14px;
}
.form-btn {
width: 100%;
padding: 10px;
background-color: #42b983;
color: #fff;
border: none;
border-radius: 4px;
cursor: pointer;
}
.dlight{
background-color: red;
}
</style>
错误的点在于下面,如果我接收了父组件传来的ref对象我这个代码就会无法响应
const color =ref('red')
color.value= inject('change')
// 计算属性:返回颜色值
const color1 = computed(() => {
return color.value
})
如何解决
1. 父组件直接传递数据而不是传递ref 对象
就可以直接使用原方法的方法
2. 父组件传递 ref对象的解决方法
- 既然是ref 对象 然后你又封装了一个ref对象给父组件传递的ref对象就相当于两个ref了,这个时候我们使用ref对象.value.value就可以解决了
const color =ref('red')
color.value= inject('change')
// 计算属性:返回颜色值
const color1 = computed(() => {
return color.value.value
})
- 直接使用 const 来接收 ref对象,如何就可以直接color.value 也可以直接解决问题
const color= inject('change')
// 计算属性:返回颜色值
const color1 = computed(() => {
return color.value
})
const injectedColor = inject('change', 'red') // 默认值 'red'
// 如果父组件提供的是 ref,则直接使用;如果是普通值,则创建 ref
const color = ref(injectedColor)
// 计算属性:返回颜色值
const color1 = computed(() => {
return color.value
})
更多推荐



所有评论(0)