我在侦听器中设置了这样一个逻辑:监听日期选择器中绑定的日期,如果选中的日期和当前时间new Date()相同,则根据当前时间所处时段,给单选框的v-model赋值“上午”或“下午”。但是每当我赋值成功之后,单选框组就无法操作了,其他的单选框按钮无法被选中。
<div class="singleRow">
<van-field readonly clickable v-model="formData.startTime" placeholder="开始时间"
label="开始时间:" label-width="70px" @click="showPicker = true" />
<van-radio-group style="min-width: 150px;" v-model="formData.startShiduan" direction="horizontal">
<van-radio name="上午" value="上午">上午</van-radio>
<van-radio name="下午" value="下午">下午</van-radio>
</van-radio-group>
</div>
<div class="singleRow">
<van-field readonly clickable v-model="formData.endTime" placeholder="结束时间"
label="结束时间:" label-width="70px" @click="showPicker2 = true" />
<van-radio-group style="min-width: 150px;" v-model="formData.endShiduan" direction="horizontal">
<van-radio name="上午" value="上午">上午</van-radio>
<van-radio name="下午" value="下午">下午</van-radio>
</van-radio-group>
</div>
watch: {
formData: {
handler: function(newValue, oldValue) {
const startDate = new Date(newValue.startTime).setHours(0, 0, 0, 0);
const endDate = new Date(newValue.endTime).setHours(0, 0, 0, 0);
const todayDate = new Date().setHours(0, 0, 0, 0);
// 如果开始时间是当天
if (startDate == todayDate) {
const hours = new Date().getHours();
if (hours >= 0 && hours < 12) {
this.formData.startShiduan = "上午";
} else if (hours >= 12 && hours < 24) {
this.formData.startShiduan = "下午";
}
}
// 如果结束时间是当天
if (endDate == todayDate) {
const hours = new Date().getHours();
if (hours >= 0 && hours < 12) {
this.formData.endShiduan = "上午";
} else if (hours >= 12 && hours < 24) {
this.formData.endShiduan = "下午";
}
}
},
deep: true,
immediate: true
}
}
代码如上,请各位帮忙看看问题出在哪里
貌似看着没啥大问题,不过你van-radio中的value没用可以删了,还有其实可以不用watch,你应该是点击输入框后弹出日期选择器组件的吧?用组件的confirm事件不就可以进行你的判断了吗,为啥要用watch
以下内容部分参考ChatGPT模型:
问题的原因是在侦听器中给单选框的v-model赋值后,会触发单选框的change事件,从而又触发了formData的更新,形成了无限循环,导致单选框无法操作。
解决思路是在给单选框的v-model赋值之前,先判断当前选中的值是否和要赋的值相同,如果相同则不赋值,避免触发change事件。可以使用Vue.set()方法来实现赋值。示例如下:
if (this.formData.startShiduan !== '上午') {
Vue.set(this.formData, 'startShiduan', '上午');
}
另外,也可以使用计算属性来实现类似的逻辑,避免在侦听器中进行复杂的逻辑处理。具体实现可以参考如下代码:
computed: {
startShiduan: function() {
const startDate = new Date(this.formData.startTime).setHours(0, 0, 0, 0);
const todayDate = new Date().setHours(0, 0, 0, 0);
if (startDate == todayDate) {
const hours = new Date().getHours();
if (hours >= 0 && hours < 12) {
return '上午';
} else if (hours >= 12 && hours < 24) {
return '下午';
}
}
return this.formData.startShiduan;
},
endShiduan: function() {
const endDate = new Date(this.formData.endTime).setHours(0, 0, 0, 0);
const todayDate = new Date().setHours(0, 0, 0, 0);
if (endDate == todayDate) {
const hours = new Date().getHours();
if (hours >= 0 && hours < 12) {
return '上午';
} else if (hours >= 12 && hours < 24) {
return '下午';
}
}
return this.formData.endShiduan;
}
}
然后在模板中使用计算属性即可:
<van-radio-group style="min-width: 150px;" v-model="startShiduan" direction="horizontal">
<van-radio name="上午" value="上午">上午</van-radio>
<van-radio name="下午" value="下午">下午</van-radio>
</van-radio-group>
如果我的建议对您有帮助、请点击采纳、祝您生活愉快
不要监听整个对象啊!就监听开始时间和结束时间就好了
watch: {
"formData.startTime"(newValue){
const startDate = new Date(newValue).setHours(0, 0, 0, 0);
const todayDate = new Date().setHours(0, 0, 0, 0);
// 如果开始时间是当天
if (startDate == todayDate) {
const hours = new Date().getHours();
if (hours >= 0 && hours < 12) {
this.formData.startShiduan = "上午";
} else if (hours >= 12 && hours < 24) {
this.formData.startShiduan = "下午";
}
}
},
"formData.endTime"(newValue){
const endDate = new Date(newValue).setHours(0, 0, 0, 0);
const todayDate = new Date().setHours(0, 0, 0, 0);
// 如果结束时间是当天
if (endDate == todayDate) {
const hours = new Date().getHours();
if (hours >= 0 && hours < 12) {
this.formData.endShiduan = "上午";
} else if (hours >= 12 && hours < 24) {
this.formData.endShiduan = "下午";
}
}
}
},
不知道你这个问题是否已经解决, 如果还没有解决的话:效果示意图:
组合代码如下:
<template>
<div>
<a-card>
<!-- 操作栏 -->
<a-row type="flex" justify="space-around">
<a-col :span="12">
<!-- 月份选择器 -->
<monthpicker @changeMonth="changeMonth"></monthpicker>
</a-col>
<a-col :span="12"></a-col>
</a-row>
<!-- 日历栏 -->
<a-row class="calendar-con">
<calendar :time="time"></calendar>
</a-row>
</a-card>
</div>
</template>
<script>
// 月份选择器
import Monthpicker from './components/Monthpicker.vue'
// 日历组件
import Calendar from './components/Calendar.vue'
export default {
components: {
monthpicker: Monthpicker,
calendar: Calendar
},
data() {
return {
time: {
year: new Date().getFullYear(),
month: new Date().getMonth()
}
}
},
created() {},
methods: {
// 修改月份
changeMonth(time) {
console.log('time', time)
this.time = time
}
}
}
</script>
<style lang="less" scoped>
.month-con {
font-weight: 700;
font-size: 18px;
.month {
margin: 0 10px;
}
}
.calendar-con {
margin-top: 20px;
}
</style>
通过changeMonth事件,将月份选择器的月份传递给日历组件,这样就完成了一个简单的能够修改月份的日历组件了。
以下答案由GPT-3.5大模型与博主波罗歌共同编写:
根据你的代码,这里出现的问题可能是在 formData
中使用的深度观察导致了 radio-group
的不可用。
你可以尝试添加以下代码,减小 formData
对象内部的观察深度,从而防止其影响其他的组件。
watch: {
"formData.startTime": function (newValue, oldValue) { /* your code here */},
"formData.endTime": function (newValue, oldValue) { /* your code here */}
}
最终的代码如下:
<template>
<div>
<div class="singleRow">
<van-field
readonly
clickable
v-model="formData.startTime"
placeholder="开始时间"
label="开始时间:"
label-width="70px"
@click="showPicker = true"
/>
<van-radio-group
style="min-width: 150px;"
v-model="formData.startShiduan"
direction="horizontal"
>
<van-radio name="上午" value="上午">上午</van-radio>
<van-radio name="下午" value="下午">下午</van-radio>
</van-radio-group>
</div>
<div class="singleRow">
<van-field
readonly
clickable
v-model="formData.endTime"
placeholder="结束时间"
label="结束时间:"
label-width="70px"
@click="showPicker2 = true"
/>
<van-radio-group
style="min-width: 150px;"
v-model="formData.endShiduan"
direction="horizontal"
>
<van-radio name="上午" value="上午">上午</van-radio>
<van-radio name="下午" value="下午">下午</van-radio>
</van-radio-group>
</div>
</div>
</template>
<script>
export default {
name: "MyComponent",
data() {
return {
formData: {
startTime: "",
endTime: "",
startShiduan: "",
endShiduan: ""
}
};
},
watch: {
"formData.startTime": function(newValue, oldValue) {
const startDate = new Date(newValue).setHours(0, 0, 0, 0);
const endDate = new Date(this.formData.endTime).setHours(0, 0, 0, 0);
const todayDate = new Date().setHours(0, 0, 0, 0);
// 如果开始时间是当天
if (startDate == todayDate) {
const hours = new Date().getHours();
if (hours >= 0 && hours < 12) {
this.formData.startShiduan = "上午";
} else if (hours >= 12 && hours < 24) {
this.formData.startShiduan = "下午";
}
}
},
"formData.endTime": function(newValue, oldValue) {
const startDate = new Date(this.formData.startTime).setHours(0, 0, 0, 0);
const endDate = new Date(newValue).setHours(0, 0, 0, 0);
const todayDate = new Date().setHours(0, 0, 0, 0);
// 如果结束时间是当天
if (endDate == todayDate) {
const hours = new Date().getHours();
if (hours >= 0 && hours < 12) {
this.formData.endShiduan = "上午";
} else if (hours >= 12 && hours < 24) {
this.formData.endShiduan = "下午";
}
}
}
}
};
</script>
这样应该可以解决你的问题,但是这种做法有一个问题,就是当 formData
的任何一个属性发生变化时,都要进行计算和触发视图更新,这可能会影响性能。因此,更好的做法是将计算和逻辑代码单独提取出来,然后在参数变化时调用它们进行更新。
如果我的回答解决了您的问题,请采纳!