问题描述
所以我已经阅读了 this 几篇文章,据我所知,我可以使用 v-model 而不是 props,将值从父组件传递给子组件,并在 prop 的时候自动发出事件值在子级中被修改,从而以更少的代码获得双向绑定(无需在父级中捕获已发出的事件)。然而,它并不像我认为的那样工作。
这是我的代码:
<template>
<!-- This is ParentComponent.vue -->
<ChildComponent v-model:documents="user.documents" />
</template>
<script lang="ts">
// This is ParentComponent.vue
import { Vue,Options } from 'vue-class-component';
import UserClass from '@/some/place/UserClass';
import ChildComponent from '@/components/ChildComponent.vue';
@Options({
components: {
ChildComponent,}
})
export default class ParentComponent extends Vue {
// Local state.
user: UserClass = new UserClass();
}
</script>
<template>
<!-- This is ChildComponent.vue -->
<section v-for="document in documents" :key="document.id">
{{ document.name }}
<button @click="remove(document.id)">Delete document</button>
</section>
</template>
<script lang="ts">
// This is ChildComponent.vue
import { Vue,Options } from 'vue-class-component';
import IDocument from '@/interfaces/IDocument';
@Options({
props: ['documents'],emits: ['update:documents'],})
export default class ChildComponent extends Vue {
// Types.
documents!: IDocument[];
// Methods.
remove(documentId: string): void {
this.documents = this.documents.filter((document) => document.id !== documentId);
}
}
</script>
我希望当单击子组件内的按钮时,它应该触发“remove()”方法,而不是直接将新值分配给 this.documents,它应该发出 update:documents 事件,反过来应该被父组件捕获并应该用于更新父组件的本地状态。
但是,我收到以下警告:
试图改变道具“文档”。道具是只读的。
还有以下错误:
未捕获的类型错误:代理集处理程序为属性“文档”返回 false
我哪里错了?提前致谢。
解决方法
我想我错过了 v-model 工作原理的一个重要功能。我假设像这样使用 v-model 传递值
public class WeekChallengeBroadcast extends BroadcastReceiver {
@Override
public void onReceive(Context context,Intent intent) {
String userID = FirebaseAuth.getInstance().getCurrentUser().getUid();
DatabaseReference myRef = FirebaseDatabase.getInstance().getReference().child(userID).child("CurrentChallenge");
myRef.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot snapshot) {
int id = snapshot.child("numOfActiveChallenge").getValue(Integer.class);
MyDBHandler myDBHandler = new MyDBHandler(context,null,MyDBHandler.DB_VERSION);
int challengeWeek = id;
Vibrator v = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
if (challengeWeek != 0) {
NotificationCompat.Builder notification = new NotificationCompat.Builder(context,CHANNEL_1_ID)
.setSmallIcon(R.drawable.ic_stat_name)
.setContentTitle("Challenge for this week :")
.setContentText(myDBHandler.loadChallengeNotification(challengeWeek))
.setStyle(new NotificationCompat.BigTextStyle())
.setPriority(Notification.PRIORITY_MAX)
.setSound(Settings.System.DEFAULT_NOTIFICATION_URI)
.setAutoCancel(false);
v.vibrate(500);
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
notificationManager.notify(2,notification.build());
} else
return;
}
@Override
public void onCancelled(@NonNull DatabaseError error) {
}
});
}
}
当 ChildComponent 中的文档属性值发生更改时,将自动发出 update:documents 事件。但似乎您仍然需要手动发出此事件,如下所示:
public void MyAlarmWeekChallenge() {
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY,12);
calendar.set(Calendar.MINUTE,0);
calendar.set(Calendar.SECOND,0);
if (calendar.getTime().compareTo((new Date())) < 0)
{
calendar.add(Calendar.DAY_OF_MONTH,1);
}
Intent intent = new Intent(getApplicationContext(),WeekChallengeBroadcast.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(),intent,0);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
if(alarmManager != null){
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,calendar.getTimeInMillis(),AlarmManager.INTERVAL_DAY,pendingIntent);
}
}