I'm using vue.js to set data boolean to change after a few seconds with setTimeout, but the result shows that the data remain same. If I have already returned the data value, what's causing this?
new Vue({
el: "#app",
data: {
showMsg: false,
},
methods: {
activeMsg() {
this.showMsg = true
this.msgNone
}
},
computed: {
msgNone() {
const msgCounter = setTimeout(()=>{
clearTimeout(msgCounter)
return this.showMsg = false
},2500)
},
},
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<button #click="activeMsg">click me</button>
<p v-if="showMsg">hello</p>
</div>
computed property doesn't do asynchronous calls, Just called the setTimeout inside the method:
new Vue({
el: "#app",
data: {
showMsg: false,
},
methods: {
activeMsg() {
this.showMsg = true
const msgCounter = setTimeout(() => {
this.showMsg = false
clearTimeout(msgCounter)
}, 2500)
}
},
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<button #click="activeMsg">click me</button>
<p v-if="showMsg">hello</p>
</div>
Related
I generate a random number when the model is mounted. I want to remove the "0." The 0. and decimal. I tried adding Math.round() but that gives me a NaN. Can someone tell me what I am missing.
new Vue({
el: '#app',
data: {
mixNumber:''
},
mounted: function(){
this.myFunction();
},
methods:{
myFunction: function () {
this.mixNumber = Math.random();
this.roundNumber=Math.round();
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
My ID is: {{mixNumber}}
</div>
You can use the following code:
new Vue({
el: '#app',
data: {
mixNumber:'',
roundNumber: ''
},
mounted: function(){
this.myFunction();
},
methods:{
myFunction: function () {
this.mixNumber = Math.random();
this.roundNumber = this.mixNumber.toString().split(".")[1];
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
My ID is: {{roundNumber}}
</div>
I have this js fiddle code. I want to create a suggestions autocomplete using vuejs. At the moment I've achived only in part the scope, I have a problem with the suggestions. They will be placed under the user input chars and it's not exactly what I was expecting, I want to do something similar to the autocompleto of a smartphone keyboard where the suggested words will be displayed while the user digit a word. Can anyone help me?
<div id="app">
<textarea id="input" v-model="input" #input="predictWord()"></textarea>
<span id="suggestion" ref="suggestion"></span>
</div>
#app {
.input {
position: relative;
}
#suggestion {
position: absolute;
left: 0;
}
}
Vue prototype code
new Vue({
el: "#app",
data() {
return {
input: null,
t9: null,
words: []
}
},
mounted() {
this.init();
},
methods: {
init() {
axios({
method: 'GET',
url: 'https://raw.githubusercontent.com/napolux/paroleitaliane/master/paroleitaliane/660000_parole_italiane.txt'
}).then( (res) => {
this.words = res.data.split('\n');
this.t9 = Predictionary.instance();
this.t9.addWords(this.words);
});
},
predictWord() {
let suggestion;
this.countChars();
suggestion = this.t9.predict(this.input);
this.$refs.suggestion.innerText = suggestion[0];
},
countChars() {
console.log(this.input.length);
}
}
});
I created a working snippet: simplified it a bit, added a loading state (as the dictionary is quite large), updated the resulting output, so it's not dependent on any DOM element.
new Vue({
el: "#app",
data() {
return {
loading: false,
input: null,
t9: null,
suggestion: [],
}
},
mounted() {
this.init();
},
methods: {
async init() {
this.loading = true
try {
const {
data = ''
} = await axios({
method: 'GET',
url: 'https://raw.githubusercontent.com/napolux/paroleitaliane/master/paroleitaliane/660000_parole_italiane.txt'
})
this.t9 = Predictionary.instance();
const a = data.split('\n').filter(e => e)
this.t9.addWords(a)
} catch (err) {
console.error(err)
} finally {
this.loading = false
}
},
predictWord: _.debounce(function() {
this.suggestion = this.input ? this.t9.predict(this.input) : [];
}, 300),
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/axios#0.21.1/dist/axios.min.js"></script>
<script src="https://unpkg.com/predictionary/dist/predictionary.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/lodash#4.17.21/lodash.min.js"></script>
<div id="app">
<textarea id="input" v-model="input" #input="predictWord" :disabled="loading"></textarea><br />
<span id="suggestion">{{ suggestion.join(', ') }}</span>
</div>
Also added a debounce function, so the prediction doesn't have to run so many times - 300ms is a reasonable delay in my experience.
I am trying to use iMask.js to change 'yyyy-mm-dd' to 'dd/mm/yyyy' with my component however when I am setting the value I think it is taking the value before the iMask has finished. I think using maskee.updateValue() would work but don't know how to access maskee from my component.
I am also not sure if I should be using a directive to do this.
Vue.component("inputx", {
template: `
<div>
<input v-mask="" v-model="comp_date"></input>
</div>
`,
props: {
value: { type: String }
},
computed: {
comp_date: {
get: function () {
return this.value.split("-").reverse().join("/");
},
set: function (val) {
const iso = val.split("/").reverse().join("-");
this.$emit("input", iso);
}
}
},
directives: {
mask: {
bind(el, binding) {
var maskee = IMask(el, {
mask: "00/00/0000",
overwrite: true,
});
}
}
}
});
var app = new Vue({
el: "#app",
data: {
date: "2020-12-30"
}
});
<script src="https://cdn.jsdelivr.net/npm/vue#2.6.12"></script>
<script src="https://unpkg.com/imask"></script>
<div id="app">
<inputx v-model="date"></inputx>
Date: {{date}}
</div>
The easiest way you can achieve this is by installing the external functionality on the mounted hook of your Vue component, instead of using a directive.
In this way you can store the 'maskee' object on your component's data object to later access it from the setter method.
Inside the setter method you can then call the 'updateValue' method as you hinted. Then, you can extract the processed value just by accessing the '_value' prop of the 'maskee' object.
Here is a working example:
Vue.component("inputx", {
template: `
<div>
<input ref="input" v-model="comp_date"></input>
</div>
`,
data: {
maskee: false,
},
props: {
value: { type: String },
},
computed: {
comp_date: {
get: function () {
return this.value.split("-").reverse().join("/");
},
set: function () {
this.maskee.updateValue()
const iso = this.maskee._value.split("/").reverse().join("-");
this.$emit("input", iso);
}
}
},
mounted(){
console.log('mounted');
const el = this.$refs.input;
this.maskee = IMask(el, {
mask: "00/00/0000",
overwrite: true,
});
console.log('maskee created');
}
});
var app = new Vue({
el: "#app",
data: {
date: "2020-12-30"
}
});
<script src="https://cdn.jsdelivr.net/npm/vue#2.6.12"></script>
<script src="https://unpkg.com/imask"></script>
<div id="app">
<inputx v-model="date"></inputx>
Date: {{date}}
</div>
I have the following definition for the Vue element:
new Vue({
el: "#app",
data: {
latitude1: 'a',
name: 'aa'
},
mounted() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(position => {
this.latitude1 = position.coords.latitude;
})
} else {
this.latitude1 = "WTF??"
// this doesn't work either:
// this.$nextTick(() => { this.latitude1 = "WTF??" })
}
},
methods: {
// button works... WTF?!?
doIt() {
this.latitude1 = "WTF??"
}
}
});
<script src="https://cdn.jsdelivr.net/npm/vue#2.5.16/dist/vue.js"></script>
<div id="app">
<div>{{ latitude1 }}: {{ name }}</div>
<button #click="doIt">Do it</button>
</div>
I can see the location data being populated. The alert displays the latitude but the 2 way binding for the data field latitude1 is not working.
I have tried storing the object state using this and that also did not work.
My html is as follows:
<div class="form-group" id="app">
<p>
{{latitude1}}
</p>
</div>
One of the things to do inside the Vue.js is to use the defined methods for reactive properties changes.
Here is a code I've provided for it:
function error(err) {
console.warn(`ERROR(${err.code}): ${err.message}`);
}
var options = {
enableHighAccuracy: true,
timeout: 5000,
maximumAge: 0
};
new Vue({
el: "#app",
data: {
latitude1: 'a',
name: 'aa'
},
mounted: function() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(position => {
console.log(position.coords.latitude);
Vue.set(this, 'latitude1', position.coords.latitude);
}, error, options)
}
}
});
I also set error handler and options for the navigator query. For following the results please check the console.
I am trying to declare getTemp variable global so that i can use it in other function. VUE.JS
var weather = new Vue({
el: '#weather',
data: {
getTemp: []
},
created: function () {
this.fetchData();
},
methods: {
fetchData: function () {
this.$http.get('https://vt')
.then(response => {
this.getTemp = response.data;
})
}
},
})
;
Root instance data properties are accessible throughout the app with this.$root.variableName:
new Vue({
el: '#app',
data: {
getTemp: 'Hello World!'
},
components: {
'child1': {
template: `<div><p>child1, getTemp: {{ $root.getTemp }}</p>
<subchild></subchild>
</div>`,
components: {
'subchild': {
template: `<span>Subchild test: {{ $root.getTemp }}</span>`
}
}
},
'child2': {
template: `<p>child2, getTemp: {{ $root.getTemp }}</p>`
}
}
});
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<div id="app">
<child1></child1>
<child2></child2>
</div>