VueJS 显示和隐藏消息
[英] VueJS Showing and Hiding Messages
本文介绍了VueJS 显示和隐藏消息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我创建了一个基本的 CLI 结构环境.我有一个组件来显示消息/警报,即:登录失败等......
由于这个组件将在整个应用程序中重复使用,我想将它导入到根 App.vue 文件并在那里处理.它正在工作......有点.
它可以很好地显示消息/警报,但我希望它在设定的秒数后隐藏/消失/蒸发.或者单击一个按钮,它会隐藏/消失/蒸发 - 我在下面的警报组件示例中显示了这一点.在某个预定义的时间之后,我根本无法隐藏,并且单击和隐藏有效,但是取消隐藏也会产生问题.我在 App.vue 文件中使用 setTimeout 方法在 5 秒后自动隐藏,但不会发生任何事情我认为该方法在导入 Alert 模块之前触发......我认为.
到目前为止,这是我的代码......似乎是一项简单的任务,但在过去的几个小时里它一直在破坏我的大脑:
应用组件:
<div id="应用程序"><alert v-if="alert" v-bind:message="alert"></alert><路由器视图></路由器视图>
模板><脚本>从'./components/frontend/alert'导入警报导出默认{name: '应用程序',数据() {返回 {警报: ''}},更新:函数(){if(this.$route.query.alert){this.alert = this.$route.query.alert;//这是为了我测试点击甚至 - 几秒钟后优先自动隐藏//这会在表单提交时返回错误 - 请参阅下面的错误document.querySelector('.alert').style.display = 'block';}},组件: {'警报':警报}}
这是警报组件:
<div class="alert"><p class="text-brand m-20"><button class="btn btn-small btn-brand" v-on:click="hideAlert()">关闭</button>{{信息}}</p>
模板><脚本>导出默认{name: '警报',道具:['消息'],数据 () {返回 {}},方法: {隐藏警报(){//这是为了我测试点击甚至 - 几秒钟后优先自动隐藏document.querySelector('.alert').style.display = 'none';}}}
使用点击隐藏时出错 - 来自 App.vue 文件:
[Vue 警告]:更新的钩子出错:TypeError:无法读取 null 的属性‘样式’"在发现---><应用程序>在 src/App.vue<根>
我怎样才能让 Alert 组件在 5 秒后从 App 根组件隐藏?这将是我的首选方法,否则我该怎么做才能让点击和隐藏工作?
非常感谢!
解决方案
document.querySelector('.alert').style.display = 'none';
不要这样做.你不应该在方法中操作 DOM,而应该在指定的地方操作,比如指令和生命周期钩子.在它们之外,Vue 希望控制 DOM.
您可以使用内联样式控制你的视图模型.您还可以使用 v-if
进行条件渲染一>.Vue 方法是让您操作模型并让 Vue 使 DOM 反映它.
我已将您的代码修改为下面的可运行代码段.由于您将 hideAlert 方法放在组件中,因此我将关联的 v-if
放在那里.测试是 message
(道具)是否有值,所以关闭是让父级清除消息的问题.这是使用 .sync
修饰符处理的标准通信功能.
关闭按钮调用了 hideAlert
方法,我还放置了一个观察器,以便在设置新消息时,它会等待 5 秒并调用 hideAlert
.
Alert 组件是独立的;它的 prop 如何获取它的值并不重要,例如父组件是否从路由器组件获取它,只重要它是否有值.
const Alert = {模板:'#警报模板',道具:['消息'],方法: {隐藏警报(){//告诉父级清除消息this.$emit('update:message', '');}},手表: {消息(新值){//5 秒后关闭如果(新值){setTimeout(this.hideAlert, 5000);}}}};新的 Vue({el: '#app',数据() {返回 {警报: ''}},组件: {'警报':警报},安装(){//如果alert有值,就会显示出来.如果没有,就没有.setTimeout(() => {this.alert = '现在你有一条消息';}, 500);}});
<script src="//unpkg.com/vue@latest/dist/vue.js"></script><div id="应用程序"><alert v-bind:message.sync="alert"></alert>
<模板 id="警报模板"><div v-if="message" class="alert"><p class="text-brand m-20"><button class="btn btn-small btn-brand" v-on:click="hideAlert()">关闭</button>{{信息}}</p>
</template>
I have a basic CLI structure environment created. I have a component to display messages/alerts Ie: Login Failed etc…
Since this component is going to be reused throughout the entire app, I figured to import it to the root App.vue file and have it handled there. It is working…sort of.
It displays the messages/alerts fine, but I would like for it to hide/disappear/evaporate after a set amount of seconds. Alternatively Click a button and it hides/disappears/evaporates - I have this shown in the Alerts Component example below. I could not get the hide after a certain pre-defined time at all, and the click and hide works, but to un-hide creates an issue as well. I used setTimeout method for the auto hide after 5 seconds in the App.vue file and nothing would happen I think the method was firing before the Alert module was imported…i think.
Here’s my code so far…seems such a simple task but its been wrecking my brain for the past couple of hours:
App Component:
<template>
<div id="app">
<alert v-if="alert" v-bind:message="alert"></alert>
<router-view></router-view>
</div>
</template>
<script>
import Alert from './components/frontend/alert'
export default {
name: 'App',
data() {
return {
alert: ''
}
},
updated: function() {
if(this.$route.query.alert){
this.alert = this.$route.query.alert;
// This was for me to test the click even - PREFER AUTO HIDE AFTER A FEW SECONDS
// This returns an error on form submit - see error below
document.querySelector('.alert').style.display = 'block';
}
},
components: {
'alert': Alert
}
}
</script>
Here is the Alert Component:
<template>
<div class="alert">
<p class="text-brand m-20">
<button class="btn btn-small btn-brand" v-on:click="hideAlert()">Close</button>
{{message}}
</p>
</div>
</template>
<script>
export default {
name: 'alert',
props: ['message'],
data () {
return {
}
},
methods: {
hideAlert() {
// This was for me to test the click even - PREFER AUTO HIDE AFTER A FEW SECONDS
document.querySelector('.alert').style.display = 'none';
}
}
}
</script>
Error using the click to hide - coming from the App.vue file:
[Vue warn]: Error in updated hook: "TypeError: Cannot read property 'style' of null"
found in
---> <App> at src/App.vue
<Root>
How can I have the Alert component hide after, let’s say 5 seconds, from the App root component? This would be my preferred method, otherwise what can I do to have the click and hide working?
Thanks so much!
解决方案
document.querySelector('.alert').style.display = 'none';
Don't do this. You should not be manipulating the DOM in methods, only in prescribed places like directives and lifecycle hooks. Outside of them, Vue expects to have control of the DOM.
You can control inline styles using your viewmodel. You can also do conditional rendering with v-if
. The Vue approach is for you to manipulate your model and have Vue make the DOM reflect it.
I've adapted your code into a runnable snippet below.
Since you put the hideAlert method in the component, I put the associated v-if
there. The test is whether message
(the prop) has a value, so closing is a matter of having the parent clear the message. This is a standard communication function handled with the .sync
modifier.
The close button calls the hideAlert
method, and I also put a watcher in so that any time a new message is set, it waits 5 seconds and calls hideAlert
.
The Alert component is self-contained; it does not matter how its prop gets its value, whether the parent gets it from a router component, for example, it only matters whether it has a value or not.
const Alert = {
template: '#alert-template',
props: ['message'],
methods: {
hideAlert() {
// Tell the parent to clear the message
this.$emit('update:message', '');
}
},
watch: {
message(newValue) {
// Close after 5 seconds
if (newValue) {
setTimeout(this.hideAlert, 5000);
}
}
}
};
new Vue({
el: '#app',
data() {
return {
alert: ''
}
},
components: {
'alert': Alert
},
mounted() {
// If alert has a value, it will display. If not, not.
setTimeout(() => {
this.alert = 'Now you have a message';
}, 500);
}
});
<script src="//unpkg.com/vue@latest/dist/vue.js"></script>
<div id="app">
<alert v-bind:message.sync="alert"></alert>
</div>
<template id="alert-template">
<div v-if="message" class="alert">
<p class="text-brand m-20">
<button class="btn btn-small btn-brand" v-on:click="hideAlert()">Close</button>
{{message}}
</p>
</div>
</template>
这篇关于VueJS 显示和隐藏消息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!