想在 vuejs 中使用 vuetify 小吃吧作为全局自定义组件
Posted
技术标签:
【中文标题】想在 vuejs 中使用 vuetify 小吃吧作为全局自定义组件【英文标题】:want to use vuetify snackbar as a global custom component in vuejs 【发布时间】:2020-10-29 14:31:33 【问题描述】:我使用snackbar 在vuejs 中显示成功消息。我想做一个全局自定义的snackbar组件。
<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>
然后我将它作为一个组件导入到我的每个表单中。
<SnackBar :snackbar="snackbar" :color="color" :text="text" />
但我的问题是我不能在我的子组件中使用snackbar 作为道具。它显示了这个错误。
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"
我该如何解决这个问题。谁能帮帮我?
【问题讨论】:
您的错误状态不在道具上使用 v-model。只需使用计算代理它并向父级发送更新 【参考方案1】:我找到了一种使用 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>
在我的 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);
,
,
;
然后我将snackbar子组件导入我的父组件并像这样发送数据。
...mapActions("snackbar", ["showSnack"]),
saveDetails()
this.showSnack(
text: "Successfully Saved!",
color: "success",
timeout: 3500,
);
【讨论】:
我认为您可以删除动作部分并直接在突变中执行,因为您没有任何副作用。【参考方案2】:我意识到这已经过时了,但感谢 google,我将添加我的解决方案。 我使用它,因为我没有看到将 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>
在主应用的根目录中的某处,添加以下内容。(我通常将我的放在 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>
然后像这样访问它......
this.$root.vtoast.show()
this.$root.vtoast.show(message: 'Ahoy there!')
【讨论】:
非常有用,干净又简单!谢谢! 嗨,我使用了你的方法,但它显示错误(this.$root.vtoast.show())【参考方案3】:另一种解决方案是使用带有 getter 和 setter 的计算值。
使用选项 api
<template>
<v-snackbar v-model="show" :color="color">
message
<template v-slot:action=" attrs ">
<v-btn text v-bind="attrs" @click="show = false">Close</v-btn>
</template>
</v-snackbar>
</template>
<script>
import mapGetters from 'vuex';
export default
computed:
...mapGetters(
message: 'snackbar/message',
color: 'snackbar/color'
),
show:
get()
return this.$store.state.snackbar.show
,
set(v)
this.$store.commit('snackbar/SET_SHOW', v)
</script>
使用合成 api 插件
<template>
<v-snackbar v-model="show" :color="color">
message
<template v-slot:action=" attrs ">
<v-btn text v-bind="attrs" @click="show = false">Close</v-btn>
</template>
</v-snackbar>
</template>
<script>
import defineComponent, computed from '@vue/composition-api';
export default defineComponent(
setup(_props, root )
const show = computed(
get: () => root.$store.state.snackbar.show,
set: (v) => root.$store.commit('snackbar/SET_SHOW', v),
);
const message = computed(() => root.$store.state.snackbar.message);
const color = computed(() => root.$store.state.snackbar.color);
return
show,
message,
color,
;
,
);
</script>
在这里使用可组合的更好的实现https://gist.github.com/wobsoriano/2f3f0480f24298e150be0c13f93bac20
【讨论】:
【参考方案4】:你有一个道具和数据相同。
从data()
中删除小吃吧,因为它可从prop
获得。
<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>
【讨论】:
抱歉,这是我的错。我已经删除它但发生同样的错误 @KalanaMihiranga 您能否在代码框中为您提供该问题的代码,因为我无法重现该问题?以上是关于想在 vuejs 中使用 vuetify 小吃吧作为全局自定义组件的主要内容,如果未能解决你的问题,请参考以下文章
Vuejs Vuetify 如何在 v-select 中访问对象的属性
VueJs - Vuetify - v-navigation-drawer 与智能手机的迷你变体
如何在带有 vuetify 和 vuex 的 Vuejs 项目中使用 Jest?节点模块和 Vuetify 问题
Vuejs & Vuetify - 在对话框中使用 Tinymce 作为组件需要重新加载