I'm new to VueJS.
I had written an alert box using jquery. Now I'm trying to provide that in VueJS.
Here is what I have done:
1- Created a ponent named NovinAlert.vue including:
<template>
<div id="novin-alert-container">
<div v-for="message in messages" class="alert novin-alert" :class="message.class">
<a href="#" class="close" data-dismiss="alert" aria-label="close">×</a>
{{ message.body }}
</div>
</div>
</template>
<script>
export default {
data: function () {
return {
messages: [],
}
},
methods: {
novinAlert: function (message) {
let app = this;
message.type = typeof message.type !== 'undefined' ? message.type : 'info';
message.class = 'alert' + message.type;
let index = app.messages.push(message) - 1;
if (typeof message.duration !== 'undefined') {
window.setTimeout(function () {
app.messages.splice(index, 1);
}, message.duration * 1000);
}
}
}
}
</script>
2- My example ponent is Dashboard.vue
<template>
...
</template>
<script>
export default {
mounted() {
novinAlert('test');
}
}
</script>
3- My main layout is:
<body>
<div id="app">
<novin-alert></novin-alert>
<router-view></router-view>
</div>
</body>
4- And this is my app.js:
require('./bootstrap');
window.Vue = require('vue');
import VueRouter from 'vue-router';
window.Vue.use(VueRouter);
import Dashboard from './ponents/Dashboard.vue';
const routes = [
{path: '/', ponent: Dashboard, name: 'dashboard'},
];
import NovinAlert from './ponents/utils/NovinAlert.vue';
Vueponent('novin-alert', NovinAlert);
const router = new VueRouter({ routes: routes });
const app = new Vue({
router,
el: '#app'
});
When I run dashboard page, it doesn't know novinAlert
function.
What I have done wrong? And what is best practice for what I'm trying to do?
Any help is appreciated.
I'm new to VueJS.
I had written an alert box using jquery. Now I'm trying to provide that in VueJS.
Here is what I have done:
1- Created a ponent named NovinAlert.vue including:
<template>
<div id="novin-alert-container">
<div v-for="message in messages" class="alert novin-alert" :class="message.class">
<a href="#" class="close" data-dismiss="alert" aria-label="close">×</a>
{{ message.body }}
</div>
</div>
</template>
<script>
export default {
data: function () {
return {
messages: [],
}
},
methods: {
novinAlert: function (message) {
let app = this;
message.type = typeof message.type !== 'undefined' ? message.type : 'info';
message.class = 'alert' + message.type;
let index = app.messages.push(message) - 1;
if (typeof message.duration !== 'undefined') {
window.setTimeout(function () {
app.messages.splice(index, 1);
}, message.duration * 1000);
}
}
}
}
</script>
2- My example ponent is Dashboard.vue
<template>
...
</template>
<script>
export default {
mounted() {
novinAlert('test');
}
}
</script>
3- My main layout is:
<body>
<div id="app">
<novin-alert></novin-alert>
<router-view></router-view>
</div>
</body>
4- And this is my app.js:
require('./bootstrap');
window.Vue = require('vue');
import VueRouter from 'vue-router';
window.Vue.use(VueRouter);
import Dashboard from './ponents/Dashboard.vue';
const routes = [
{path: '/', ponent: Dashboard, name: 'dashboard'},
];
import NovinAlert from './ponents/utils/NovinAlert.vue';
Vue.ponent('novin-alert', NovinAlert);
const router = new VueRouter({ routes: routes });
const app = new Vue({
router,
el: '#app'
});
When I run dashboard page, it doesn't know novinAlert
function.
What I have done wrong? And what is best practice for what I'm trying to do?
Any help is appreciated.
3 Answers
Reset to default 2i've designed a SIMPLE popup right now with Vuejs 2.* and it works well.
In this example, popup is included as a Local ponent. This would be one of the best practices to follow. Let me know if this helps.
App.vue
<template>
<div>
<div>Main page</div>
<button @click="openpopup">Open popup</button>
<popup :popupData="popupData" ></popup>
</div>
</template>
<script>
import Popup from'./Popup.vue';
export default {
ponents:{
"popup" : Popup
},
data() {
return {
popupData : {
"header" : "My popup",
"body" : "hello world",
"footer" : "divine inc.",
"display" : "none"
}
}
},
methods : {
openpopup(){
this.popupData.display = "block";
}
},
mounted(){
this.popupData.display = "block";
}
}
</script>
Popup.vue
<template>
<div id="popup" :style="{display : popupData.display}">
<div class="inner">
<div class="header">
<div>{{popupData.header}}</div>
<div @click="closeFunction">Close</div>
</div>
<div class="body">{{popupData.body}}</div>
<div class="footer">{{popupData.footer}}</div>
</div>
</div>
</template>
<script>
export default {
props : ["popupData"],
methods : {
closeFunction(){
this.popupData.display = "none";
}
}
}
</script>
<style>
html,body{
padding: 0;
margin:0;
}
#popup{
position: absolute;
width: 100%;
height :100%;
top: 0;
}
#popup .inner{
background-color: green;
position: inherit;
top: 10%;
left: 39%;
width: 300px;
}
#popup .inner div{
text-align: left;
}
#popup .inner .header{
display: flex;
justify-content: space-between;
}
</style>
You can't access one ponent's method from another. you need to move the novinAlert
function to the Dashboard
ponent and pass messages as a property to NovinAlert
ponent:
NovinAlert.vue
<template>
<div id="novin-alert-container">
<div v-for="message in messages" class="alert novin-alert" :class="message.class">
<a href="#" class="close" data-dismiss="alert" aria-label="close">×</a>
{{ message.body }}
</div>
</div>
</template>
<script>
export default {
props: ['messages']
}
</script>
Dashboard.vue
<template>
<!-- pass the messages prop to the ponent -->
<novin-alert :messages="messages"></novin-alert>
</template>
<script>
export default {
mounted() {
this.novinAlert('test');
},
data() {
return {
messages: []
}
},
methods: {
novinAlert: function (message) {
let app = this;
message.type = typeof message.type !== 'undefined' ? message.type : 'info';
message.class = 'alert' + message.type;
let index = app.messages.push(message) - 1;
if (typeof message.duration !== 'undefined') {
window.setTimeout(function () {
app.messages.splice(index, 1);
}, message.duration * 1000);
}
}
}
}
</script>
if you want the novin alert in the app level, you'll need to pass the function to the app ponent
This is what I finally did:
I created an instance of Vue in my app.js
:
window.eventBus = new Vue();
I use this event but for multiple purposes. Whenever I need I trigger(emit) an event and the listener does required action.
For alert box, I emit the event like this:
window.eventBus.$emit('alert', {
text: app.trans('general.error_in_reading_data'),
type: 'danger',
duration: 5,
});
Then my alert ponent reacts like this:
mounted() {
window.eventBus.$on('alert', (message) => {
this.novinAlert(message);
});
},