export default issue with VueJS ES5 - vue.js

I am developing a website, partially in Vue using ES5.
I need to get data from a Vue Child component to be sent back up to the parent, the way explained to me was via using export default {} However I am constantly recieving syntax errors and I am not sure why because from what i see, I am following Mozillas recomendations.
My question component:
var question = Vue.component('question', {
props: {
scenarios: Array,
scenario: Object,
post: Boolean
},
data: function () {
return ({
choice: 0,
counter: 0,
finished: false
});
},
export default {
methods: {
onClickButton: function (event) {
this.$emit('clicked', 'someValue')
},
postResponse: function () {
var formData = new FormData();
formData.append(this.choice);
// POST /someUrl
this.$http.post('Study/PostScenarioChoice', formData).then(response => {
// success callback
}, response => {
// error callback
});
},
activatePost: function () {
if (this.counter < this.scenarios.length) {
this.counter++;
}
else {
this.finished = true;
}
}
}
},
template:
`<div>
<div v-if="this.finished === false" class="row justify-content-center">
<div class="col-lg-6">
<button class="btn btn-light" href="#" v-on:click="this.onClickButton">
<img class="img-fluid" v-bind:src="this.scenarios[this.counter].scenarioLeftImg" />
</button>
</div>
<div class="col-lg-6">
<button class="btn btn-light" href="#" v-on:click="this.onClickButton">
<img class="img-fluid" v-bind:src="this.scenarios[this.counter].scenarioRightImg" />
</button>
</div>
</div>
<finished v-else></finished>
</div >
});
I get the error in the browser console Expected ':' which is on the line export default {
Any assistance will be greatly appreciated.

You have written completely wrong syntax of JavaScript. What you are trying to do here is to put "export default" in the place where object key should go. I will provide correct code here, but I strongly suggest you go and learn the fundamentals of JavaScript including arrays and objects in order to be able to read and write correct and valid JavaScript. Here is some good learning material for beginners:
http://eloquentjavascript.net/
https://maximdenisov.gitbooks.io/you-don-t-know-js/content/
And here is the fixed Vue component:
export default Vue.component("question", {
props: {
scenarios: Array,
scenario: Object,
post: Boolean
},
data: function () {
return ({
choice: 0,
counter: 0,
finished: false
});
},
methods: {
onClickButton: function (event) {
this.$emit("clicked", "someValue");
},
postResponse: function () {
var formData = new FormData();
formData.append(this.choice);
// POST /someUrl
this.$http.post("Study/PostScenarioChoice", formData).then(response => {
// success callback
}, response => {
// error callback
});
},
activatePost: function () {
if (this.counter < this.scenarios.length) {
this.counter++;
}
else {
this.finished = true;
}
}
},
template:
`<div>
<div v-if="this.finished === false" class="row justify-content-center">
<div class="col-lg-6">
<button class="btn btn-light" href="#" v-on:click="this.onClickButton">
<img class="img-fluid" v-bind:src="this.scenarios[this.counter].scenarioLeftImg" />
</button>
</div>
<div class="col-lg-6">
<button class="btn btn-light" href="#" v-on:click="this.onClickButton">
<img class="img-fluid" v-bind:src="this.scenarios[this.counter].scenarioRightImg" />
</button>
</div>
</div>
<finished v-else></finished>
</div>`
});

The actual answer was a simple misunderstanding of the information presented here. The use of export default was irrelevant in my implementation however this was not easily visible until I started noticing the emit posting the parent element later on.
The actual implementation was as follows:
var question = Vue.component('question', {
props: {
scenarios: Array,
scenario: Object,
post: Boolean,
counter: Number
},
data: function () {
return ({
choice: 0,
finished: false
});
},
methods: {
onClickButton: function (event) {
this.$emit('clicked', 'someValue');
},
postResponse: function () {
var formData = new FormData();
formData.append(this.choice);
// POST /someUrl
this.$http.post('Study/PostScenarioChoice', formData).then(response => {
// success callback
}, response => {
// error callback
});
}
},
template:
`<div>
<div v-if="this.finished === false" class="row justify-content-center">
<div class="col-lg-6">
<button class="btn btn-light" href="#" v-on:click="this.onClickButton">
<img class="img-fluid" v-bind:src="this.scenarios[this.counter].scenarioLeftImg" />
</button>
</div>
<div class="col-lg-6">
<button class="btn btn-light" href="#" v-on:click="this.onClickButton">
<img class="img-fluid" v-bind:src="this.scenarios[this.counter].scenarioRightImg" />
</button>
</div>
</div>
<finished v-else></finished>
</div >`
});
The receiving method in the parent element is as follows:
onClickChild: function (value) {
console.log(value) // someValue
this.showTimer = true;
this.countdownTimer();
if (this.counter < this.scenarios.length) {
this.counter++;
}
else {
this.finished = true;
}
}

Related

How to pass data on the root components in Vue

How can I pass the page_id to the Sidebar component method highlightNode(), because I want to highlight a newly added item. My current code is the page id is undefined.
This is my code & structure.
my root component is Sidebar.vue
<template>
<div>
<ul>
<li v-for="page in pages">
<div :class="{ 'highlight': highlightedNode == page.id }">
<router-link :to="'/view/' + page.id" #click.native="highlightNode(page.id)">
<span v-title="page.title"></span>
</router-link>
</div>
</li>
</ul>
</div>
</template>
export default {
data () {
return {
pages: [],
highlightedNode: null
}
},
mounted() {
this.getPages()
this.$root.$refs.Sidebar = this
},
methods: {
getPages() {
axios.get('/get-pages').then(response => {
this.pages = response.data
});
},
highlightNode(id) {
this.highlightedNode = id
},
}
}
my add new Page component AddNewPage.vue
<template>
<div>
<div class="main-header">
<div class="page-title">
<input type="text" v-model="page.title" class="form-control">
</div>
</div>
<div class="main-footer text-right">
<button class="btn btn-success btn-sm" #click="saveChanges()">Save and Publish</button>
</div>
</div>
</template>
export default {
data () {
return {
page: {
title: null,
},
}
},
mounted() {
//
},
methods: {
saveChanges() {
axios.post('/store-new-filter', this.page)
.then(response => {
const id = response.data.id // return page id
this.$root.$refs.Sidebar.highlightNode(id) // <-- this line, I want to pass page id to hightlight the newly added page.
})
.catch( error => {
})
},
}
}
Or any alternative way to achieve my expected output.
Thanks in advance.

how to create autocomplete component in vue js?

I am facing an issue with my autocomplete component. whenever i type anything into the input field the input is reset.I mean it does not let me type anything.It just keeps getting reset before i could fully type anything.
main.js
Vue.component('g-autocomplete', {
props: ['list','value','title'],
data() {
return {
input: '',
}
},
template: `<template>
<div class="autocomplete">
<input style="font-size: 12pt; height: 36px; width:1800px; " type="text" v-model="input" #input="handleInput"/>
<ul v-if="input" >
<li v-for="(item, i) in list" :key="i" #click="setInput(item)" >
<!-- {{ autocompleteData }} -->
<template v-if="title!='manager'">
<div class="container">
<p>
<b>ID:</b>
{{item.id}}
</p>
<p>
<b>Description:</b>
{{item.description}}
</p>
</div>
</template>
<template v-else>
<div class="container">
<p>
<b>ID:</b>
{{item.id}}
</p>
<p>
<b>First Name:</b>
{{item.firstName}}
</p>
<p>
<b>Last Name:</b>
{{item.lastName}}
</p>
</div>
</template>
</li>
</ul>
</div>
</template>`,
methods: {
handleInput(e) {
console.log('inside handleInput')
this.$emit('input', e.target.value)
},
setInput(value) {
console.log('inside setInput')
this.input = value
this.$emit('click', value)
},
},
watch: {
$props: {
immediate: true,
deep: true,
handler(newValue, oldValue) {
console.log('new value is'+newValue)
console.log('old value is'+oldValue)
console.log('value inside handler'+this.value)
console.log('list inside handler'+this.list)
console.log('title inside handler'+this.title)
this.input=this.value
}
}
// msg(newVal) {
// this.msgCopy = newVal;
// }
}
})
i reuse the above component from diffrent vue pages's like this-
<b-field label="Custom Business Unit">
<g-autocomplete v-on:input="getAsyncDataBusinessUnit" v-on:click="(option) => {updateValue(option.id,'businessUnit')}" :value="this.objectData.businessUnit" :list="dataBusinessUnit" title='businessUnit' >
</g-autocomplete>
</b-field>
my debounce function that is called when something is typed into the input field.
getAsyncDataBusinessUnit: debounce(function(name) {
if (!name.length) {
this.dataBusinessUnit = [];
return;
}
this.isFetching = true;
api
.getSearchData(this.sessionData.key,`/businessunit/?filter={id} LIKE '%25${name}%25' OR {description} LIKE '%25${name}%25'`)
.then(response => {
this.dataBusinessUnit = [];
response.forEach(item => {
this.dataBusinessUnit.push(item);
});
})
.catch(error => {
this.dataBusinessUnit = [];
throw error;
})
.finally(() => {
this.isFetching = false;
});
}, 500),
what could be the issue here ? Also i noticed that the issue doesn't happen if i comment out the body of the debounce function.So therefore i feel there is something in the debounce function that is causing this.I will try to isolate the problem but i want to understand what exactly is causing this issue. Plz help?

Vue instance's $on method is not work

I just created an event bus in the main.js file like this:
main.js
Vue.prototype.$bus = new Vue()
After that, I just wrote some code to test the event bus like this:
TestComponent
<template>
<div>
<div class="account-modal_form">
<form action="" #submit.prevent="formSubmit">
<div class="account-modal_form__group" :class="{ warning: errors.has('password') }">
<div class="account-modal_form__input">
<input name="password" :type="passwordType" placeholder="" class="width-316" v-validate="'required'" v-model="password">
<i class="account-modal_form__viewpass" #click="togglePassword"></i>
</div>
<span class="account-modal_form__warning" v-show="errors.has('password')">
{{ errors.first('password') }}
</span>
</div>
{{ errors }}
<div class="account-modal_form__group">
<button type="submit" class="btn btn--primary btn--large">next</button>
<button type="button" class="btn btn--default" #click="cancelAction">cancel</button>
</div>
</form>
</div>
</div>
</template>
<script>
import { API } from '#/api'
export default {
data() {
return {
passwordType: 'password',
password: ''
}
},
methods: {
created() {
this.$bus.$on('test', () => console.log('test'));
},
nextStep() {
this.$bus.$emit('test');
},
formSubmit() {
this.nextStep();
}
}
}
</script>
When I click submit button I want to submit form first and call nextstep to emit an event, but the $on event output nothing.
You're running $emit before $on, so when you fire the event there are no listeners at that point, and it's better to register your listeners on the component created life cycle event, otherwise whenever you run your test method you'll register a new listener:
Vue.prototype.$bus = new Vue();
Vue.component('spy-component', {
template: '<p>{{this.text}}</p>',
data() {
return {
text: '',
}
},
created() {
this.$bus.$on('sendOriginPassword', (text) => {
this.text = text;
});
}
})
Vue.component('test-component', {
template: '<button #click="test">Click me</button>',
created() {
this.$bus.$on('sendOriginPassword', () => {
console.log('I am listening event')
});
},
methods: {
test() {
this.$bus.$emit('sendOriginPassword', 'Can you hear me?');
}
}
});
new Vue({
el: "#app",
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>
<div id="app">
<spy-component></spy-component>
<test-component></test-component>
</div>

Vue.JS: turn every matching case to a hyperlink

I'm trying to turn every matching case from an array to a link
// I call the message component using this from another component
<ul>
<li
v-for="message in message"
v-bind:message="message"
is="message"
</ul>
// in the message component I have a mounted that reads the text message
// from the server and filters hashtags
data () {
return {
hashtagsInMessages: ''
};
},
mounted () {
const filterMessageHashtags = _.filter( this.message,text.split( ' ' ), value => hashtags.indexOf(value) != -1 );
this.hashtagsInMessages = filterMessageHashtags;
}
With this, how can I turn a message to a link, for instance:
hey how you doing #cool #fire #water bro?
To this, using Vue.js
hey how you doing #cool #fire #water bro?
This is my solution:
Vue.component("message-el", {
template: "#message",
props: ["message"],
created: function (){
this.messages = this.message.split(" ");
this.hashTags = this.messages.filter(function (message){
return message[0] === "#";
});
},
data: function (){
return {
messages: [],
hashTags: [],
};
},
methods: {
}
});
var app = new Vue({
el: "#app",
data: function (){
return {
}
},
methods: {
}
});
.none {
display: none;
}
<script src="https://unpkg.com/vue#2.5.2/dist/vue.js"></script>
<div id="app">
<message-el message="this is a message #tag1 #tag2">
</message-el>
</div>
<div id="message" class="none">
<div>
<div>
<template v-for="message in messages">
<a v-if="hashTags.indexOf(message) > -1" :href="'#' + message">
{{ message }}
</a>
<span v-else>
{{ message }}
</span>
&nbsp
</template>
</div>
</div>
</div>

How to call $get from Vue.extend?

Examples do not show how to call such function from Vue.extend. Now I am getting error:
ReferenceError: $get is not defined
var guestContent = Vue.extend({
template: `
<p>Guest content</p>
<div v-for="question in questions">
<template v-if="question.isEnabled">
<h3 v-if="question.isEnabled">{{question.question}}</h3>
<!-- First Level -->
<div v-for="firstLevelAnswer in question.answers">
<label v-if="!question.isRadioButton"><span class="firstLevelAnswer"><input type="checkbox" class="big-checkbox" v-on:onclick="setIsSelectedTrue()"/>{{firstLevelAnswer.answer}}</span></label>
<label v-if="question.isRadioButton"><span class="firstLevelAnswer"><input type="radio" class="big-checkbox" name="myvalue"/>{{firstLevelAnswer.answer}}</span></label>
<span v-if="firstLevelAnswer.isTextInput"><input type="text"/></span>
| firstLevelAnswer.isSelected: {{firstLevelAnswer.isSelected}}
</div>
</template>
</div>
</li>
`,
data: function () {
return {
questions: []
}
},
ready()
{
this.getQuestionsContent(),
this.foo()
},
methods:
{
getQuestionsContent()
{
this.$http.get('http://127.0.0.1:8080/js/questions.json').then(function(response)
{
this.questions = response.data;
});
},
foo()
{
console.log($get('questions.question')); //HERE IS PROBLEM
}
}
}
);
Also can I check of value firstLevelAnswer.isSelected from foo? How can I reach it? It's generated in for loop and do not like that it can exists here...
$get is an instance method of Vue components, so you have to call it with this.$get:
foo()
{
console.log(this.$get('questions.question'));
}