ElementUI message initial render disable - javascript

been trying to use https://element.eleme.io/#/en-US/component/message
in my component via
import Message from "#/components/ElementUi/Message";
and inside that component just normal include from element-ui
<template>
<div>
<el-button :plain="true" #click="open">{{label}}</el-button>
</div>
</template>
<script>
import { Message, Button } from "element-ui";
// import lang from "element-ui/lib/locale/lang/ru-RU";
// import locale from "element-ui/lib/locale";
import "element-ui/lib/theme-chalk/index.css";
import "../../../public/css/element-variables.scss";
//locale.use(lang);
import Vue from "vue";
Vue.use(Message);
Vue.use(Button);
export default {
props: ["label", "content", "type", "duration", "run"],
data() {
return {};
},
methods: {
open() {
Message({
showClose: true,
message: this.content,
type: this.type,
duration: this.duration,
dangerouslyUseHTMLString: true
});
}
},
created() {
if (this.run == 1) {
// this.open();
}
},
beforeCreate() {}
};
</script>
What happens when my component updates this annoying message automatically display with 0 content, but I want to to be rendered only when some conditions are met
like
<div
v-if="searchCompleted.status && searchCompleted.codingType=='reverse' && searchCompleted.fullMatch == false "
>
<message
:duration="3000"
:label="'info'"
:content="'<p>No data</p>'"
:type="'message'"
></message>
</div>
</div>
The documentation lacks of information how not to show the element on initial render of component, so there must be some pure javascript option how to disable that thing and enable when needed?

Related

How to create a reusable Vuetify Snackbar?

I'm trying to create a reusable alert/snackbar component. I declared them like this:
Snackbar.vue
<template>
<v-snackbar transition="true" timeout="2000" :show="`${show}`" :color="`${color}`" absolute top outlined right>
<strong>
{{ message }}
</strong>
</v-snackbar>
</template>
<script>
export default {
name: 'Snackbar',
props: {
show: String,
color: String,
message: String
}
}
</script>
<template>
<v-snackbar transition="true" timeout="2000" :show="`${show}`" :color="`${color}`" absolute top outlined right>
<strong>
{{ message }}
</strong>
</v-snackbar>
</template>
<script>
export default {
name: 'Snackbar',
props: {
show: String,
color: String,
message: String
}
}
</script>
I imported, and pass probs to them like so :
import Snackbar from '../../../components/Snackbar'
<Snackbar v-if="alert" color="alertColor" message="alertMessage" />
<Snackbar show="alert" color="alertColor" message="alertMessage" />
I've tried the 2 lines above, and these are the value of those 3 variables
alert = true
alertColor = green
alertMessage = create.vue?f4fe:631 DB error - insert_marketing_campaign: Duplicate entry 'TEST' for key 'MARKETING_CAMPAIGN_AK'
Result
I see no error in console, but see no snackbar either. pls help
8!
You aren't passing props values correctly, you have to do this instead:
ps. for illustration, i added an event listener(update) to deal with a close button(remove if you dont want to use)
<Snackbar :show="alert" :color="alertColor" :message="alertMessage" v-on:update="alert = $event" />
Snackbar.vue
I changed a few things here too:
the way you are using props in the attributes works, but if dont need to concatenate other values, keep it simple
prop show must be Boolean
added a beautiful button if you want to use
v-model controls snackbar exhibition, but you can't use the prop show directly on v-model, that's why we have a computed property "show2"(very creative) that read(get) the value of prop show and emit a custom event "update" if you want to change it(set)
<template>
<v-snackbar transition="true" timeout="2000" v-model="show2" :color="color" absolute top outlined right>
<strong>
{{ message }}
</strong>
<v-btn color="red" text #click="show2 = false">Close</v-btn>
</v-snackbar>
</template>
<script>
export default {
props: {
show: Boolean,
color: String,
message: String,
},
computed: {
show2: {
get() {
return this.show;
},
set(value) {
this.$emit("update", value);
},
},
},
};
</script>
Hope it helps! ;)
Check this codesandbox I made: https://codesandbox.io/s/stack-71244492-vuex-snackbar-klfunf?file=/src/store/index.js
You can set up a global snackbar in your App.vue file and update it with Vuex. In your vuex store you set up an snackbar object and create a simple update mutation and show action.
// store/index.js
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
export default new Vuex.Store({
state: {
snackbar: { active: false, color: "", message: "", timer: 4000 }
},
mutations: {
UPDATE_SNACKBAR(state, snackbar) {
state.snackbar = snackbar;
}
},
actions: {
showSnack({ commit }, { message, color, timer }) {
commit("UPDATE_SNACKBAR", {
active: true,
color: color,
message: message,
timer: timer
});
}
}
});
Then in your App.vue you set it up like this
<v-snackbar
v-model="snackbar.active"
:color="snackbar.color"
:right="true"
:bottom="true"
:timeout="snackbar.timer"
>
{{ snackbar.message }}
<template #action="{ attrs }">
<v-btn
color="white"
text
v-bind="attrs"
#click="snackbar.active = false"
>
Close
</v-btn>
</template>
</v-snackbar>
<script>
import { mapState } from "vuex";
export default {
name: 'App',
data: () => ({
drawer: false,
}),
computed: {
...mapState(["snackbar"])
}
}
</script>
Then you can trigger your snackbar from any component simply by doing this
// views/Home.vue
this.$store.dispatch('showSnack', {
message: 'Testing, main page.',
color: 'green darken-1'
})
// views/About.vue
this.$store.dispatch('showSnack', {
message: 'Hello from about!',
color: 'red darken-1',
timer: 2000
})

Vue, dynamically import template

I want to be able to swap out a template for a component based on a data property, or a prop. Is this possible?
This is my idea, however this doesn't work of course.
./index.vue
export default {
props:{
},
template: import(`./Themes/Templates/${this.template}`),
data: function() {
return {
template: 'Default'
}
},
./Themes/Templates/Default.vue
<div>
<p>Default template</p>
</div>
Currently getting this error:
invalid template option:[object Module]
Use component that vue.js provide:
<template>
<component :is="myComp"></component>
</template>
...
// You need to import all the possible components
import CompOne from '/CompOne.vue';
import CompTwo from '/CompTwo.vue'
props:{
myComp: {
default: 'comp-one',
type: String,
},
},
...
Try require("./Themes/Templates/Default.vue")
Update:
In Default.vue:
...
export default {
name: "Default"
}
...
and in index.vue:
...
template: this.temp,
data() {
const { Default } = import("./Themes/Templates/Default.vue");
return {
temp: Default
}
}
...

How to auto close a customized vue toast component

I have a customized toast component:
<template>
<div v-show="isToastVisible" class="toast-wrapper">
<div class="toast-conatiner">
{{ message }}
</div>
</div>
</template>
<script>
import { mapState, mapActions } from 'vuex';
export default {
props: {
message: {
type: String,
default: '',
},
isToastVisible: {
type: Boolean,
default: false,
},
},
};
</script>
I pass state to the property:
<toast :is-toast-visible="isToastVisible" message="please say the word again"/>
I have an action to control the value of isToastVisbible. When I want to toast some message , I set the state to true.
What I want is to make the toast auto closed in 3 seconds, it means that I have to call a setTimeout function when I set isToastVisbible to true.
commit('SET_TOAST_VISIBLILITY', true);
setTimeout(() => {
commit('SET_TOAST_VISIBLILITY', false);
}, 3000);
I try to add watch on isToastVisbible, but it only can works at first time.
<template>
<div v-show="localVisible" class="toast-wrapper">
<div class="toast-conatiner">
{{ message }}
</div>
</div>
</template>
<script>
import { mapState, mapActions } from 'vuex';
export default {
props: {
message: {
type: String,
default: '',
},
isToastVisible: {
type: Boolean,
default: false,
},
},
data: () => ({
localVisible: false,
}),
watch: {
isToastVisible(v) {
if (v) {
this.localVisible = true;
setTimeout(() => {
this.localVisible = false;
}, 3000);
}
},
},
};
I am trying to do a better design on the component, but I don't know what is the best practice of this. Hope somebody could give me a hand, thanks a lot.
Try to use toast component with v-model directive. In toast you may use timer to emit hide event:
setTimeout(() => this.$emit('input'), 3000);
On the parent component you may use this one:
<toast-component v-model="isVisible"></toast-component>
Or without v-model sugar:
<toast-component :value="isVisible" #input="isVisible = false"></toast-component>

Vue.js - Dynamic component import in data and computed properties

I have component 'Page' that should display a component which is retrieved via its props.
I managed to get my component loads when I harcode my component path in my component data like this :
<template>
<div>
<div v-if="includeHeader">
<header>
<fv-header/>
</header>
</div>
<component :is="this.componentDisplayed" />
<div v-if="includeFooter">
<footer>
<fv-complete-footer/>
</footer>
</div>
</div>
</template>
<script>
import Header from '#/components/Header/Header';
import CompleteFooter from '#/components/CompleteFooter/CompleteFooter';
export default {
name: 'Page',
props: {
componentPath: String,
includeHeader: Boolean,
includeFooter: Boolean
},
data() {
componentDisplayed: function () {
const path = '#/components/my_component';
return import(path);
},
},
components: {
'fv-header': Header,
'fv-complete-footer': CompleteFooter,
},
}
</script>
But with the data I cannot refer to my props within my function as this is undefined.
I tried to used computed properties instead of data but I have the error "src lazy?0309:5 Uncaught (in promise) Error: Cannot find module '#/components/my_component'. But the module exists! But maybe not at that time ?
computed: {
componentDisplayed: function () {
const path = `#/components/${this.componentPath}`;
return import(path);
},
},
There must be away to deal with that but I am quite a beginner to vue.js :)
Instead of trying to import the component in your child component, instead import it in the parent component and pass the entire component as a prop.
<template>
<div :is="component" />
</template>
<script>
export default {
name: "page",
props: {
component: {
required: true
}
}
};
</script>
And in the parent
<page :component="component" />
and
import Page from './components/Page';
// and further down
data () {
return {
component: HelloWorld
}
}

Adding properties to a vue component

I'm trying to create a "Dropdown List" component. This component should take in a title and a route. I'm having trouble setting up the javascript for this component within the parent. Here is what I'm working with.
PARENT COMPONENT:
<template>
<UserDropdownList v-for="item in items"></UserDropdownList>
</template>
<script>
import SignUp from "../forms/SignUp";
import SignIn from "../forms/SignIn";
import UserDropdownList from "./UserDropdownList";
import { mixin as clickaway } from 'vue-clickaway';
export default {
mixins: [ clickaway ],
components: {
SignUp,
SignIn,
UserDropdownList
},
data: function () {
return {
items: [
{ title: 'Profile', route: "/profile" },
{ title: 'Users', route: "/users" }
]
}
},
computed: {
isLoggedIn () {
return this.$store.getters.isLoggedIn
},
userName () {
return this.$store.getters.currentUser.userName
},
isDropdownOpen () {
return this.$store.getters.dropdownIsOpen
}
},
methods: {
signOut: function(event) {
this.$store.commit("CLOSE_DROPDOWN");
this.$store.commit("LOGOUT");
this.$router.push('/');
},
openDropdown: function() {
if (event.target.id != "button") {
this.$store.commit("OPEN_DROPDOWN");
}
},
closeDropdown: function() {
this.$store.commit("CLOSE_DROPDOWN");
}
}
}
</script>
USER DROPDOWN LIST
<template>
<li v-on:click="closeDropdown"><router-link to={{ item.route }} id="button">{{ item.title }}</router-link></li>
</template>
<script>
export default {
}
</script>
<style>
</style>
ERRORS:
Property or method "item" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property.
Error in render: "TypeError: Cannot read property 'title' of undefined"
Anyone understand what I am doing wrong?
you didn't pass item as a props to UserDropdownList
first, pass item as a prop to UserDropdownList
<template>
<UserDropdownList v-for="item in items" v-bind:item="item"></UserDropdownList>
</template>
then, setup UserDropdownList to receive item prop
export default {
props: ['item']
}

Categories