我使用snackbar 在vuejs 中显示成功消息。我想制作一个全局自定义小吃店组件。
<template>
<div name="snackbars">
<v-snackbar
v-model="snackbar"
:color="color"
:timeout="timeout"
:top="'top'"
>
{{ text }}
<template v-slot:action="{ attrs }">
<v-btn dark text v-bind="attrs" @click="snackbar = false">
Close
</v-btn>
</template>
</v-snackbar>
</div>
</template>
<script>
export default {
props: {
snackbar: {
type: Boolean,
required: true,
},
color: {
type: String,
required: false,
default: "success",
},
timeout: {
type: Number,
required: false,
default: 3000,
},
text: {
type: String,
required: true,
},
},
};
</script>
Run Code Online (Sandbox Code Playgroud)
然后我将它作为组件导入到我的每个表单中。
<SnackBar :snackbar="snackbar" :color="color" :text="text" />
Run Code Online (Sandbox Code Playgroud)
但我的问题是我不能在我的子组件中使用小吃店作为道具。它向我展示了这个错误。
Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "snackbar"
Run Code Online (Sandbox Code Playgroud)
我该如何解决这个问题。谁能帮我?
Ala*_*ock 18
我意识到这已经过时了,但是感谢谷歌,我将添加我的解决方案。我使用这个,因为我不明白使用 vuex 作为小吃店有什么意义。这比需要的工作还要多。
创建一个名为 vtoast 的 vue 组件
<template>
<v-snackbar
:color="color"
:timeout="timer"
v-model="showSnackbar"
bottom
right
>
<v-icon left>{{icon}}</v-icon>{{message}}
</v-snackbar>
</template>
<script>
export default {
name: "vtoast",
data() {
return{
showSnackbar: false,
message: '',
color: 'success',
icon: 'mdi-check',
timer: 3000
}
},
methods:{
show(data) {
this.message = data.message || 'missing "message".'
this.color = data.color || 'success'
this.timer = data.timer || 3000
this.icon = data.icon || 'mdi-check'
this.showSnackbar = true
}
}
}
</script>
Run Code Online (Sandbox Code Playgroud)
在主应用程序的根目录中的某个位置,添加以下内容。(我通常把我的放在App.vue中)
<template>
...
<!-- toast -->
<vtoast ref="vtoast"/>
...
</template>
<script>
import vtoast from '@/your/vtoast/directory/vtoast'
export default{
name: 'App', //or whatever your root is
components:{
vtoast
},
mounted() {
this.$root.vtoast = this.$refs.vtoast
},
}
</script>
Run Code Online (Sandbox Code Playgroud)
并像这样访问它......
this.$root.vtoast.show()
this.$root.vtoast.show({message: 'Ahoy there!'})
Run Code Online (Sandbox Code Playgroud)
我找到了一种使用 vuex 修复我的解决方案的方法。
<template>
<div name="snackbars">
<v-snackbar v-model="show" :color="color" :timeout="timeout" :top="'top'">
{{ text }}
<template v-slot:action="{ attrs }">
<v-btn dark text v-bind="attrs" @click="snackbar = false">
Close
</v-btn>
</template>
</v-snackbar>
</div>
</template>
<script>
export default {
created() {
this.$store.subscribe((mutation, state) => {
if (mutation.type === "snackbar/SHOW_MESSAGE") {
this.text = state.snackbar.text;
this.color = state.snackbar.color;
this.timeout = state.snackbar.timeout;
this.show = true;
}
});
},
data() {
return {
show: false,
color: "",
text: "",
timeout: 0,
};
},
};
</script>
Run Code Online (Sandbox Code Playgroud)
在我的 vuex 模块中,我是这样写的
export default {
namespaced: true,
state: {
text: "",
color: "",
timeout: "",
},
mutations: {
SHOW_MESSAGE(state, payload) {
state.text = payload.text;
state.color = payload.color;
state.timeout = payload.timeout;
},
},
actions: {
showSnack({ commit }, payload) {
commit("SHOW_MESSAGE", payload);
},
},
};
Run Code Online (Sandbox Code Playgroud)
然后我将零食栏子组件导入我的父组件并发送这样的数据。
...mapActions("snackbar", ["showSnack"]),
saveDetails() {
this.showSnack({
text: "Successfully Saved!",
color: "success",
timeout: 3500,
});
}
Run Code Online (Sandbox Code Playgroud)