I have a preloader in Vue js but it's infinite, how could I fix it? I was thinking about doing something to hide the div that contains the preloader when the page is loaded using mounted(), but I am not sure what should I do exactly. I am working in the App.vue file.
EDIT: Tried to add the class d-none when the component is mounted but that didn't work
new Vue({
el: "#app",
data(){
return{
classes: '',
}
},
mounted(){
this.classes='d-none';
}
});
/* Loader */
#preloader {
position: fixed;
left: 0;
top: 0;
z-index: 99999;
width: 100%;
height: 100%;
overflow: visible;
display: table
}
.loader {
display: table-cell;
vertical-align: middle;
position: relative;
width: 200px;
height: 200px
}
#preloader,
.contact-box,
.scroll-to-top {
background: #fff;
text-align: center
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div id="preloader" v-bind:class="classes">
<div class="row loader">
<img src="https://media2.giphy.com/media/3oEjI6SIIHBdRxXI40/giphy.gif" alt="logo" width="220" height="110">
<br><br>
</div>
</div>
<h1>content</h1>
</div>
the best way to do this task in vuejs is using a v-if.
e.g
<div v-if="!isLoaded" id="preloader">
<div class="row loader">
<img src="https://media2.giphy.com/media/3oEjI6SIIHBdRxXI40/giphy.gif" alt="logo" width="220" height="110">
<br><br>
</div>
</div>
new Vue({
el: "#app",
data(){
return{
isLoaded: false,
}
},
mounted: function() {
this.$nextTick(q => {
// Will be executed when the DOM is ready
this.isLoaded = true;
// UPD : you can use this instead for your tests ..
// setTimeout(function () { this.isLoaded = true; }, 2000)
})
}
});
Related
Why does it happen that my Vue router navigates to /#/! without apparent reason?
This seems to happen when I fire an event from an autocomplete form built with Bootstrap Autocomplete and trigger a function.
Calling the same function by clicking a button does not lead to the problem.
This is the parent component where the event is emitted to
<style scoped>
</style>
<template>
<div id="appspace">
<div id="leftbar">
</div>
<div id="workarea">
<div id="mapblock">
</div>
<div id="infoblock">
<div class="form-group"><label for="gotoff">Go to</label>
<autosuggest #locselect="locSelect($event)" id="gotoff"></autosuggest>
</div>
<button v-on:click="searchAround()" type="button" class="btn btn-primary">Search</button>
</div>
</div>
<div id="rightbar">
</div>
</div>
</template>
<script>
module.exports = {
data: function () {
return {
};
},
components: {
autosuggest: httpVueLoader('components/base/autosuggest.vue'),
},
mounted: function(){
},
destroyed: function(){
},
methods: {
setMarkerInCenter: function(){
this.locSelect({ value: { lng: 12, lat: 14 }})
},
locSelect: function(e) {
console.log('locSelect');
console.log(e);
},
},
}
</script>
and this is the component emitting the event:
<style scoped>
.autocomplete {
position: relative;
width: 130px;
}
.autocomplete-results {
padding: 0;
margin: 0;
border: 1px solid #eeeeee;
height: 120px;
overflow: auto;
}
.autocomplete-result {
list-style: none;
text-align: left;
padding: 4px 2px;
cursor: pointer;
}
.autocomplete-result:hover {
background-color: #4AAE9B;
color: white;
}
</style>
<template>
<div class="input-group">
<input ref="ac" class="form-control">
<div class="input-group-append">
<div class="input-group-text"><i class="fa fa-compass" style="height:0.5em;padding:0;margin:0;margin-bottom:4px"></i></div>
</div>
</div>
</template>
<script>
module.exports = {
mounted: function(){
var i = this.$refs.ac;
var c = this
$(i).autoComplete({ resolverSettings: { url: '/api/gc/autocomplete' } });
$(i).on('autocomplete.select', function(e, sel) {
e.preventDefault();
c.$emit('locselect', sel);
e.preventDefault();
});
},
}
</script>
Any leads as to how to debug this?
I couldn't find the reason why this autocomplete changes the route, that behavoir
seems to be undocumented. But here's a method to temporarily prevent this behavior until you find the solution, add this global route guard to your router to prevent navigation to '/#/!' route:
router.js
const router = new VueRouter({ ... })
router.beforeEach((to, from, next) => {
console.log(to)
// TEMP PATCH:
// Autocomplete changes route to '/#/!'
if (to.path !== '/#/!') {
next()
}
})
Just make sure that console.log(to) actually has a property path === '/#/!'
How to animate(toggle) the button it self when click?
I tried as below
<div id="app">
<button class="btn" #click="show = !show">
click
</button>
</div>
<script>
var app = new Vue({
el: '#app',
data: function() {
return {
show: true
}
}
});
</script>
<style>
.button { position:fixed; top:100px; left:100px; }
.button.active { left:0; }
</style>
I expect the output that when click the button, button move to left:0 position. And another click, it move to left 100.
Use class binding to bind the active class when show is true. You should also use the button class instead of btn as that's what you have in your CSS.
var app = new Vue({
el: '#app',
data: {
show: true
}
})
.button {
position: fixed;
top: 100px;
left: 100px;
transition: left 0.2s; /* added this for fun */
}
.button.active {
left: 0;
}
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<div id="app">
<button class="button" :class="{active: show}" #click="show = !show">
click
</button>
</div>
as cood like this
'<div class="item" :class="{'editable':canEdit}"></div>';
set 'canEdit' to false -------the classes of 'div' are "item"
'$("div").addClass("on")' ------the classes of 'div' are "item on"
set 'canEdit' to true -------the classes of 'div' are "item editable"
question:why the classes of 'div' are not "item on editable"
Because you are not using Vue to add class to the element. So Vue doesn't know you have added a new class to the element.
See this example where I add a class NOT using Vue:
new Vue({
el: '#app',
template: `
<div>
<div ref="e" class="a" :class="{ b: b }"></div>
<button #click="toggleB">Toggle B</button>
<button #click="addC">Add C</button>
</div>
`,
data(){
return {
b: true
}
},
methods: {
toggleB(){
this.b = !this.b;
},
addC(){
this.$refs.e.classList.add('c');
}
}
});
.a {
width: 100px;
height: 100px;
}
.b {
border: 1px solid black;
}
.c {
background: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
<div id="app"></div>
Now if I use Vue to add class to it, it will work because now Vue knows:
new Vue({
el: '#app',
template: `
<div>
<div class="a" :class="{ b: b, c: c }"></div>
<button #click="toggleB">Toggle B</button>
<button #click="addC">Add C</button>
</div>
`,
data(){
return {
b: true,
c: false
}
},
methods: {
toggleB(){
this.b = !this.b;
},
addC(){
this.c = true;
}
}
});
.a {
width: 100px;
height: 100px;
}
.b {
border: 1px solid black;
}
.c {
background: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
<div id="app"></div>
So, when you click the blue content, I want to hide it, but not if you click a child element, like a h2, a, p, etc. Is this possible?
Please see the fiddle
html
<html>
<head></head>
<body>
<div id="app">
<div v-if="modal" id="content" #click="toggle">
<h3>
Name
</h3>
<span>
Like this (don't close if clicked)
</span>
</div>
<button #click="toggle">Toggle</button>
</div>
</body>
</html>
.js
new Vue({
el: '#app',
data: {
modal: true
},
methods: {
toggle: function( ){
this.modal = !this.modal
}
}
});
.css
a {
color: white
}
#content {
width: 300px;
height: 300px;
background: blue;
color: white;
}
Fiddle: http://jsfiddle.net/awu752mr/6/
I believe that is what the v-on:click.self modifier does. See here in the docs.
As #LShapz answered, the modifier=.self should be the recommended approach (Vue Style).
Another way is compare $event.target === $event.currentTarget (not recommended for your use case, but you may use these two properties for some other situations in future).
Vue.config.productionTip = false
new Vue({
el: '#app',
data: {
modal: true
},
methods: {
toggle: function(ev){
if(ev.target === ev.currentTarget) this.modal = !this.modal
}
}
});
a {
color: white
}
#content {
width: 300px;
height: 300px;
background: blue;
color: white;
}
<script src="https://unpkg.com/vue#2.5.16/dist/vue.js"></script>
<div id="app">
<div v-if="modal" id="content" #click="toggle($event)">
<h3>
Name
</h3>
<span>
Like this
</span>
</div>
<button #click="toggle">Toggle</button>
</div>
Assign filename to input field on upload and then show success message working fine,but when i try to delete file and upload again it's not working!
new Vue({
el: "#app",
data() {
return {
form: {
message: '',
fileurl: ''
},
loading: false
}
},
methods: {
uploadImage(event) {
this.form.fileurl = 'uploaded!'
},
deleteFile(furl) {
this.form.fileurl = ''
}
}
})
body {
background: #20262E;
padding: 20px;
font-family: Helvetica;
}
#app {
background: #fff;
border-radius: 4px;
padding: 20px;
transition: all 0.2s;
}
span {
color: red;
}
<script src="https://cdn.jsdelivr.net/npm/vue#2.5.16/dist/vue.js"></script>
<div id="app">
<h3>
File Upload / remove Demo
</h3>
<hr />
<div class="custom-file attach_file" v-show="!form.fileurl">
<input type="file" id="file" name="file" #change="uploadImage($event)">
<input type="text" v-model="form.fileurl">
</div>
<p v-if="form.fileurl"> {{ form.fileurl }} <span #click="deleteFile(form.fileurl)">Delete</span></p>
</div>
I am not getting any console error as well.
This is what i have tried so far.
Can you guys please have a look at this!
The problem is that #change is not trigger when you choose the same file. The simplest solution is reset value of input when you click delete
this.$refs.fileToUpload.value = '';
new Vue({
el: "#app",
data() {
return {
form: {
message: '',
fileurl: ''
},
loading: false
}
},
methods: {
uploadImage(event) {
this.form.fileurl = 'uploaded!'
},
deleteFile(furl) {
this.form.fileurl = ''
this.$refs.fileToUpload.value = '';
}
}
})
body {
background: #20262E;
padding: 20px;
font-family: Helvetica;
}
#app {
background: #fff;
border-radius: 4px;
padding: 20px;
transition: all 0.2s;
}
span {
color: red;
}
<script src="https://cdn.jsdelivr.net/npm/vue#2.5.16/dist/vue.js"></script>
<div id="app">
<h3>
File Upload / remove Demo
</h3>
<hr />
<div class="custom-file attach_file" v-show="!form.fileurl">
<input type="file" id="file" name="file" class="custom-file-input" #change="uploadImage($event)" ref="fileToUpload">
<input type="text" v-model="form.fileurl">
</div>
<p v-if="form.fileurl"> {{ form.fileurl }} <span #click="deleteFile(form.fileurl)">Delete</span></p>
</div>
You need to clear you input field first.
Update your upload method with this.
uploadImage(event) {
this.form.fileurl = 'uploaded!'
this.success = false
this.$nextTick(() => {
this.success = true
})
Have a look at this working demo
https://jsfiddle.net/asimshahzad/8c9pcfys/