Difference from #event="doThis()" & #event="doThis" in Vuejs - vue.js

I've encountered this error
Cannot read property 'target' of undefined
with an #click event while calling a method with a doThis().
But doThis worked fine
I would like to know what is the difference between
<button type="button" #click="doThis()" data-name="test">Test</button>
And
<button type="button" #click="doThis" data-name="test">Test</button>
with this method
methods: {
doThis(e) {
console.log(e.target.dataset.name);
}
}

Because the e which is the event object being handled is is undefined. You have to pass the object using global $event
<button type="button" #click="doThis($event)" data-name="test">Test</button>
Usually when you invoke the event handler manually is because you need to pass additional arguments to the function. As example
<div v-for="v in values" :key="v.id">
<button type="button" #click="doThis($event, v)" data-name="test">Test</button>
</div>

As I was typing this up, #Chay22 was able to help - for what it's worth, here is an example:
[CodePen Mirror]
const vm = new Vue({
el: "#app",
data: {
title: ''
},
methods: {
doTheNeedful(e) {
this.title = "Coming From: " + e.target.innerHTML;
console.log(e);
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.min.js"></script>
<div id="app">
<div>
<button #click="doTheNeedful">doTheNeedful</button>
<button #click="doTheNeedful($event)">doTheNeedful($event)</button>
<div v-if="title">
<p>{{ title }}</p>
<h3>Check console for event info</h3>
</div>
</div>
</div>

Related

Trouble with binding an nested* object of attributes in Vue 2.6 (Updated)

I am using a simple v-for to loop through an array of objects. In that v-for I have an anchor tag that needs data- attributes set dynamically. To do this I attempt to bind an object of attributes but when I do and reload npm I get this error:
vue.common.dev.js?4650:4479 Uncaught DOMException: Failed to execute 'setAttribute' on 'Element': 'data-url' is not a valid attribute name.
at baseSetAttr (webpack-internal:///./node_modules/vue/dist/vue.common.dev.js:6774:8)
at setAttr (webpack-internal:///./node_modules/vue/dist/vue.common.dev.js:6749:5)
at Array.updateAttrs (webpack-internal:///./node_modules/vue/dist/vue.common.dev.js:6704:7)
at invokeCreateHooks (webpack-internal:///./node_modules/vue/dist/vue.common.dev.js:6060:22)
at createElm (webpack-internal:///./node_modules/vue/dist/vue.common.dev.js:5947:11)
at createChildren (webpack-internal:///./node_modules/vue/dist/vue.common.dev.js:6044:9)
at createElm (webpack-internal:///./node_modules/vue/dist/vue.common.dev.js:5945:9)
at createChildren (webpack-internal:///./node_modules/vue/dist/vue.common.dev.js:6044:9)
at createElm (webpack-internal:///./node_modules/vue/dist/vue.common.dev.js:5945:9)
at createChildren (webpack-internal:///./node_modules/vue/dist/vue.common.dev.js:6044:9)
Vue
<template>
<div>
<div class="student-list">
<div>
<a v-for="student in students" :href="student.url" type="button" class="btn btn-sm is-dark"
v-bind="student.attr" //This line causes the issue
>See Profile</a>
</div>
</div>
</div>
</template>
<script>
export default {
props: {
students: Array,
}
}
</script>
When I comment out the problem line from the code above then the browser console error goes away but the results are not what I want. Why is this occurring?
EDIT: Add student data example
[
{
"fullname":"Robert Chaff",
"age":"26",
"attr":{
"data-url":"http://studentdata.test/student/1",
"data-open-modal":"true"
}
},
{
"fullname":"Jason Bittermeyer",
"age":"23",
"attr":{
"data-url":"http://studentdata.test/student/2",
"data-open-modal":"true"
}
}
]
In the vue docs for 2.x it shows to do this when binding an object of attrs
<!-- binding an object of attributes -->
<div v-bind="{ id: someProp, 'other-attr': otherProp }"></div>
But my attrs are nested within an object which is within an array.
Well, it's working just fine....
const vm = new Vue({
data() {
return {
students: [
{
"fullname":"Robert Chaff",
"age":"26",
"attr":{
"data-url":"http://studentdata.test/student/1",
"data-open-modal":"true"
}
},
{
"fullname":"Jason Bittermeyer",
"age":"23",
"attr":{
"data-url":"http://studentdata.test/student/2",
"data-open-modal":"true"
}
}]
}
}
}).$mount('#app')
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div class="student-list">
<div>
<a v-for="student in students" :href="student.fullname" type="button" class="btn btn-sm is-dark" v-bind="student.attr" >
{{ student.fullname }}
</a>
</div>
</div>
</div>

How can I access text inside an input within a template?

My objective is to get text from an input that's in a template. Not sure how to go about retrieving this. I'm using Vue; Note must be available in Vue.js, no external sources
The Template:
<template id="addmodal">
<div class="modal-mask">
<div class="modal-wrapper">
<div class="modal-container">
<div class="modal-header">
<slot name="header">
Enter Course Information:
</slot>
</div>
<div class="modal-body">
<slot name="body">
Course Name
<input type="text" ref="coursename" placeholder="Numbers Don't Lie 101">
Course Grade
<input type="text" ref ="coursemark" placeholder="100">
</slot>
</div>
<div class="modal-footer">
<slot name="footer">
<button class="modal-default-button" #click="confirmCourse">
Submit New Course
</button>
<button class="modal-cancel-button" #click="cancelCourse">
Cancel
</button>
</slot>
</div>
</div>
</div>
</div>
</template>
I need to access coursename and coursemark. This can be done fairly easily when not inside a template. As it is right now the code executes stating .value is undefined.
var app = new Vue({
el: "#app",
data: {
courses: [],
confirmModal: false,
confirmAdd: false,
selectedCourse: null
},
methods: {
addCourse2: function addCourse2() {
this.confirmAdd = false;
var course = this.$refs.coursename.value;
var mark = this.$refs.coursemark.value;
if (course) {
this.courses.push(new Course(course, mark));
this.$refs.newcourse.value = "";
this.$refs.newmark.value = "";
}
}
}
});
EDIT:
Forgot to add the component section
Vue.component("add-modal", {
template: "#addmodal",
props: ["open", "course", "mark"],
methods: {
confirmCourse: function confirmCourse() {
alert(this.$refs.coursename.value);
this.$emit("confirm");// GET
},
cancelCourse: function cancelCourse() {
this.$emit("cancel");
}
}
});
Forgive me in advance, I feel this is something rather easy I'm missing as a beginner
use v-model. or if it is in other component. you can use $emit

Update component data from the template

Not too sure what is wrong here, it seems fine to me! I'm simply trying to update the data property display to true when I click the input within my component.
I have passed the data to the slot scope, so can't see that being the issue. It just simply won't update, using a function to toggle it works, however not what I really want to do, seems pointless.
<time-select>
<div slot-scope="{ time }" class="is-inline-block">
<label for="businessHoursTimeFrom"><i class="fas fa-clock"></i> From</label>
<input type="text" name="businessHoursTimeFrom[]" v-model="time" v-on:click="display = true">
</div>
</time-select>
The code behind:
<template>
<div>
<p>{{ display }}</p>
<slot :time="time" :display="display"></slot>
<div class="picker" v-if="display">
<p>Test</p>
</div>
</div>
</template>
<script>
export default {
props: [],
data: function () {
return {
time: '',
display: false
}
},
mounted() {
},
methods: {
}
}
</script>

Vuejs Axios data not showing

The problem of not showing information is delayed in fetching , i need any help for this problem.
<h1>#{{message}}</h1>
<div class="panel panel-primary">
<div class="panel-heading">
<div class="row">
<div class="col-md-10"><h3 class="panel-title">Experience</h3></div>
<div class="col-md-2 text-right">
<button class="btn btn-success">Ajouter</button>
</div>
</div>
</div>
<div class="panel-body" >
<ul class="list-group">
<li class="list-group-item" v-for="experience in experiences" >
<div class="pull-right">
<button class="btn btn-warning btn-sm">Editer</button>
</div>
<h3>#{{experience.titre}}</h3>
<p>#{{experience.body}}</p>
<small>#{{experience.debut}} - #{{experience.fin}}</small>
</li>
</ul>
</div>
</div>
Vuejs
<script src="{{asset('js/vue.js')}}"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
var app = new Vue({
el: '#app',
data: {
message: 'Nawfal Kharbouch',
experiences:[]
},
methods:{
getExperiences:function(){
axios.get('http://localhost:8080/getexperiences').then(response=>{
this.experiences=response.data;
console.log(this.experiences);
}).catch(function(error){
console.log('erros : ',error);
})
}
},
mounted:function(){
this.getExperiences();
console.log(this.experiences);
}
})
</script>
The problem of not showing information is delayed in fetching , i need any help for this problem.
//console Google Chrome
[__ob__: Observer]
vue.js:8553 You are running Vue in development mode.
Make sure to turn on production mode when deploying for production.
See more tips at https://vuejs.org/guide/deployment.html
backend.js:1 vue-devtools Detected Vue v2.5.16
5:171 (3) [{…}, {…}, {…}, __ob__: Observer];
//picture view vide
Instead of using this directly you need to pass it to a variable.
methods:{
getExperiences:function(){
var vm = this
axios.get('http://localhost:8080/getexperiences').then(response=>{
vm.experiences=response.data;
console.log(vm.experiences);
}).catch(function(error){
console.log('erros : ',error);
})
}
},
You can not pass "this" inside a promise, you need to add "this" to a variable.
Exemple:
var app = new Vue({
el: '#app',
data: {
message: 'Nawfal Kharbouch',
experiences:[]
},
methods:{
var self = this;
getExperiences:function(){
axios.get('http://localhost:8080/getexperiences').then(response=>{
self.experiences=response.data;
console.log(self.experiences);
}).catch(function(error){
console.log('erros : ',error);
})
}
},
mounted:function(){
this.getExperiences();
console.log(this.experiences);
}
})

captcha form validation required error message in vue-recaptcha

I am following this Package in vue.js and Laravel 5.6.7 to implement captcha.
https://github.com/DanSnow/vue-recaptcha#install
Component code in vue.js
<template>
<div>
<vue-recaptcha v-model="loginForm.recaptcha"
sitekey="My key">
</vue-recaptcha>
<button type="button" class="btn btn-primary">
Login
</button>
</div>
</template>
<script>
</script>
app.js code
import VueRecaptcha from 'vue-recaptcha';
Vue.use(VeeValidate);
Vue.component('vue-recaptcha', VueRecaptcha);
Question:
Is there any property for vue-recaptcha called required which can be passed to show the form validation message?
You can use a property (loginForm.recaptchaVerified below) to track if the recaptcha was verified and prevent submit + display a message if not:
JSFiddle demo: https://jsfiddle.net/acdcjunior/o7aca7sn/3/
Code below:
Vue.component('vue-recaptcha', VueRecaptcha);
new Vue({
el: '#app',
data: {
loginForm: {
recaptchaVerified: false,
pleaseTickRecaptchaMessage: ''
}
},
methods: {
markRecaptchaAsVerified(response) {
this.loginForm.pleaseTickRecaptchaMessage = '';
this.loginForm.recaptchaVerified = true;
},
checkIfRecaptchaVerified() {
if (!this.loginForm.recaptchaVerified) {
this.loginForm.pleaseTickRecaptchaMessage = 'Please tick recaptcha.';
return true; // prevent form from submitting
}
alert('form would be posted!');
}
}
})
<script src="https://www.google.com/recaptcha/api.js?onload=vueRecaptchaApiLoaded&render=explicit" async defer>
</script>
<script src="https://unpkg.com/vue"></script>
<script src="https://unpkg.com/vue-recaptcha#latest/dist/vue-recaptcha.js"></script>
<div id="app">
<form v-on:submit.prevent="checkIfRecaptchaVerified">
<div>
<vue-recaptcha #verify="markRecaptchaAsVerified"
sitekey="6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-">
</vue-recaptcha>
</div>
Some other fields of the form here...
<br>
<button>Submit form</button>
<hr>
<div><strong>{{ loginForm.pleaseTickRecaptchaMessage }}</strong></div>
</form>
</div>