Vue syntax error: Unexpected Token - vue.js

I'm, using Vue and Nuxt to build an application, however, I'm getting the following error on compiling the app.
Here is my code:
<template>
<nav class="flex items-center bg-green w-screen justify-between flex-wrap p-6">
<section class="flex items-center flex-no-shrink mr-6">
<nuxt-link to="/" class="block lg:inline-block text-white uppercase lg:mt-0 no-underline mr-4">Ben John Bagley</nuxt-link>
</section>
<section class="block lg:hidden">
<button class="flex items-center p-2" #click="toggle">
<i class="fal fa-bars text-white"></i>
</button>
</section>
<section class="block text-left lg:flex w-full lg:items-center lg:w-auto lg:text-right" :class="open ? 'block': 'hidden'">
<nuxt-link to="/about" class="block mt-3 lg:inline-block text-white lg:mt-0 no-underline mr-4">About</nuxt-link>
<nuxt-link to="/works" class="block mt-3 lg:inline-block text-white lg:mt-0 no-underline mr-4">Works</nuxt-link>
<nuxt-link to="/contact" class="inline-block text-sm px-4 py-2 leading-none text-white border border-green-dark bg-green-dark hover:bg-green-darker hover:border-green-darker rounded no-underline mt-4 mr-4 lg:mt-0">Contact</nuxt-link>
</section>
</nav>
</template>
<script>
export default {
data: function () {
open: false,
},
methods: {
toggle() {
this.open = !this.open
}
}
}
</script>
I'm sure it's a simple fix, however, I'm sure the comma is needed here.

This
data: function () {
open: false,
}
should be
data: function () {
return {
open: false
};
}
data is a function so you have to return a value which in this case is an object.

Related

Why I cant parse the {{task}} variable inside the v-for in the task-panel child?

The for loop is working properly. When I add a new task panel shows but the {{task}} variable inside the component is not showing. It must be something with the component template.
<span class="col-span-3 bg-blue-200 p-2">{{task}}</span>
I have left all the code down here maybe is something that I don't see.
Any idea? Thanks
<body>
<div id="app">
<task-input></task-input>
</div>
<script>
let app = Vue.createApp({ });
app.component(
'task-input',
{
template:
`<div class=" container grid grid-cols-4 mb-5 border-2 border-gray-600 center mt-5 mx-auto bg-gray-400 ">
<input id="taskInput" v-model="task" class="bg-white col-span-3 p-3 text-black font-bold" type="text" placeholder="What you will do next" />
<button #click="addTask()" class="text-white font-extrabold uppercase">Add new task</button>
</div>
<div class="container container mx-auto rounded-top-lg">
<div class=" bg-gray-200 border-2 border-gray-600 center column-1 container mx-auto mt-5 mx-auto rounded-top-lg">
<h1 class="font-sans text-2xl text-center text-white bg-gray-500 uppercase font-extrabold px-4 py-4">
{{title}}
</h1>
<ul class="bg-white">
<task-panel v-for="task in tasks"/>
</ul>
</div>
</div>`,
data() {
return {
title:"Here is a nice title",
task: '',
tasks: [],
}
},
components:['task-panel'],
methods:{
addTask(){
this.tasks.push(this.task);
this.task='';
console.log(this.tasks);
}
}
},
);
app.component('task-panel',{
template:
`<li class="grid bg-gray-200 mt-1">
<div class="grid grid-cols-4">
<span class="col-span-3 bg-blue-200 p-2">{{task}}</span>
<span class="col-span-1 text-center self-center uppercase font-bold">test</span>
</div>
<div class="flex justify-end bg-gray-300 p-1">
<button class="bg-blue-500 text-white px-3 py-1 rounded-md m-1 uppercase font-bold">To Do</button>
<button class="bg-green-500 text-white px-3 py-1 rounded-md m-1 uppercase font-bold">Done</button>
<button class="bg-red-500 text-white px-3 py-1 rounded-md m-1 uppercase font-bold">Blocked</button>
</div>
</li>
`,
data() {
return { }
},
props: ['tasks', 'modelValue'],
computed:{
tasks:{
get(){
return this.tasks;
}
}
}
});
app.mount('#app');
</script>
</body>
The v-for is only in the scope of the parent component. The v-for's iterator prop does not get automatically passed into the task-panel.
You need to explicitly bind the iterator prop to task-panel's prop:
👇
<task-panel v-for="task in tasks" :task="task" />
Also, the prop in task-panel should have the same name. It's currently spelled tasks (with an s at the end). The last s should be removed so that it matches what the template is rendering:
// props: ['tasks', ⋯],
props: ['task', ⋯],
<script src="https://unpkg.com/vue#3.2.31/dist/vue.global.js"></script>
<script src="https://cdn.tailwindcss.com"></script>
<div id="app">
<task-input></task-input>
</div>
<script>
let app = Vue.createApp({ });
app.component(
'task-input',
{
template:
`<div class=" container grid grid-cols-4 mb-5 border-2 border-gray-600 center mt-5 mx-auto bg-gray-400 ">
<input id="taskInput" v-model="task" class="bg-white col-span-3 p-3 text-black font-bold" type="text" placeholder="What you will do next" />
<button #click="addTask()" class="text-white font-extrabold uppercase">Add new task</button>
</div>
<div class="container container mx-auto rounded-top-lg">
<div class=" bg-gray-200 border-2 border-gray-600 center column-1 container mx-auto mt-5 mx-auto rounded-top-lg">
<h1 class="font-sans text-2xl text-center text-white bg-gray-500 uppercase font-extrabold px-4 py-4">
{{title}}
</h1>
<ul class="bg-white">
<task-panel v-for="task in tasks" :task="task" />
</ul>
</div>
</div>`,
data() {
return {
title:"Here is a nice title",
task: '',
tasks: [],
}
},
components:['task-panel'],
methods:{
addTask(){
this.tasks.push(this.task);
this.task='';
console.log(this.tasks);
}
}
},
);
app.component('task-panel',{
template:
`<li class="grid bg-gray-200 mt-1">
<div class="grid grid-cols-4">
<span class="col-span-3 bg-blue-200 p-2">{{task}}</span>
<span class="col-span-1 text-center self-center uppercase font-bold">test</span>
</div>
<div class="flex justify-end bg-gray-300 p-1">
<button class="bg-blue-500 text-white px-3 py-1 rounded-md m-1 uppercase font-bold">To Do</button>
<button class="bg-green-500 text-white px-3 py-1 rounded-md m-1 uppercase font-bold">Done</button>
<button class="bg-red-500 text-white px-3 py-1 rounded-md m-1 uppercase font-bold">Blocked</button>
</div>
</li>
`,
data() {
return { }
},
props: ['task', 'modelValue'],
});
app.mount('#app');
</script>

Vue show menu function

I am trying to make a function that shows my menu but when I click it, I only get errors.
app.js:
const app = new Vue({
el: '#app',
});
new Vue({
el: '#demo',
data: {
show: true
}
})
In my component, I have:
<div class="relative inline-block text-left unselectable" id="demo"> <!-- Menu -->
<button type="button" v-on:click="show = !show" class="menu-btn material-icons">more_vert</button>
<div class="origin-top-right absolute right-0 mt-2 w-56 rounded-md shadow-lg z-50" v-if="show">
<div class="dropdown-list rounded-md bg-white shadow-xs">
<ul>
<li class="block py-2 text-sm leading-5 text-sm"><button class="list-btn">Perfil</button></li>
<li class="block py-2 text-sm leading-5 text-sm"><button class="list-btn">Definições</button></li>
<li class="divider"></li>
<li class="block py-2 text-sm leading-5 text-sm"><button class="list-btn sair" #click.prevent="logout">Sair</button></li>
</ul>
</div>
</div>
</div>
I get these errors:
Property or method "show" 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. See: https://v2.vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.
found in
at resources/js/components/Utils/UserMenu.vue
and
app.js:39733 [Vue warn]: Cannot find element: #example
PS: I just started in vue.js, do I need to export or declare something?
main.js
import Vue from "vue";
import App from "./App.vue";
Vue.config.productionTip = false;
new Vue({
render: h => h(App)
}).$mount("#app");
You have to declare show prop in data so it can be used in template otherwise you'll get error that property is not defined
App.vue
<template>
<div class="relative inline-block text-left unselectable" id="demo"> <!-- Menu -->
<button type="button" v-on:click="show = !show" class="menu-btn material-icons">more_vert</button>
<div class="origin-top-right absolute right-0 mt-2 w-56 rounded-md shadow-lg z-50" v-if="show">
<div class="dropdown-list rounded-md bg-white shadow-xs">
<ul>
<li class="block py-2 text-sm leading-5 text-sm"><button class="list-btn">Perfil</button></li>
<li class="block py-2 text-sm leading-5 text-sm"><button class="list-btn">Definições</button></li>
<li class="divider"></li>
<li class="block py-2 text-sm leading-5 text-sm"><button class="list-btn sair" #click.prevent="logout">Sair</button></li>
</ul>
</div>
</div>
</div>
</template>
<script>
export default {
name: "App",
data(){
return {
show :false
}
},
}
</script>

Run transition on programmatically created component

I'm using this code
var ComponentClass = Vue.extend(Notification);
var instance = new ComponentClass({
propsData: {
notification: notification
}
});
instance.$mount();
this.$refs.notificationContainer.appendChild(instance.$el);
to programmatically create a component when a new notification is received through pusher, this is my notification component
<template>
<transition
enter-active-class="transition ease-out duration-100 transform"
enter-class="opacity-0 scale-95"
enter-to-class="opacity-100 scale-100"
leave-active-class="transition ease-in duration-75 transform"
leave-class="opacity-100 scale-100"
leave-to-class="opacity-0 scale-95"
>
<div class="bg-gray-100 px-4 py-2 border-0 rounded relative mb-4 text-gray-700 flex items-center">
<div class="flex-shrink-0 h-10 w-10">
<img
class="h-10 w-10 rounded-full"
:src="notification.user.profile_photo_url"
:alt="notification.user.username"
>
</div>
<span class="inline-block align-middle flex-1 ml-2 mr-4">
<strong>{{notification.user.username}}</strong> {{notification.message}}
</span>
<button class="focus:outline-none">
<i
class="fad fa-times text-red-600"
></i>
</button>
</div>
</transition>
</template>
<script>
export default {
props: {
notification: Object
}
}
</script>
but for some reason the transition doesnt run when the component is created
Fixed by adding appear to the transition element

Is there a way to get the data from multiple selects as array?

I'm currently stuck on a task on VueJS. Basically I'm trying to create an array from multiple select inside a form to get all the data as an array or Object to process it further. I just searched but got no results or an idea on how to solve my issue.
Parent Component
<template>
<div id="product" class="mt-12">
<div class="flex flex-wrap mb-4">
<div class="w-1/2 pr-12">
<img src="https://placehold.it/800" alt="">
</div>
<div class="w-1/2">
<div class="flex justify-between content-center h-12 mb-4">
<div class="text-gray-700 py-2">
<h2 v-if="product.brand" class="leading-none font-bold text-sm">{{ product.brand }}</h2>
<h1 class="text-xl leading-snug">{{ product.name }}</h1>
</div>
<div class="text-gray-700 py-2">
<p class="text-xl font-bold leading-none">{{ product.price }}</p>
<p class="text-xs text-right leading-none">Inkl. 19% MwSt.</p>
</div>
</div>
<div class="divider bg-gray-400 mt-4 mb-4" />
<div id="variations">
<form action="">
<ProductVariation v-for="(variations, type) in product.variations" :type="type" :variations="variations" :key="type" v-model="form.variation"/>
<div class="flex w-full">
<button class="w-full leading-none bg-blue-500 hover:bg-blue-600 text-white py-2 rounded" type="submit">Add to cart</button>
</div>
</form>
</div>
</div>
</div>
</div>
</template>
<script>
import ProductVariation from '#/components/products/ProductVariation'
export default {
data () {
return {
product: null,
form: {
variation: null
}
}
},
components: {
ProductVariation
},
async asyncData({ params, app }) {
let response = await app.$axios.$get(`products/${params.slug}`)
return {
product: response.data
}
}
}
</script>
ProductVariation Component
<template>
<div class="flex mb-4">
<div class="w-full">
<label class="block text-gray-700 w-full text-sm font-bold">{{ type }}</label>
<select class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight" :name="type">
<option value="0">Please select</option>
<option v-for="variation in variations" :key="variation.id" :value="variation.id">{{ variation.name }} <span>( +{{ variation.price }} )</span></option>
</select>
</div>
</div>
</template>
<script>
export default {
props: {
type: {
required: true,
type: String
},
variations: {
required: true,
type: Array
}
},
}
</script>

Calling the Twitch API with axios and Vue

so I'm attempting to use the Twitch API to enable users to sign in using the Twitch API, however, I'm running into some issues
Here is the code I have so far
<template>
<section>
<form class="pt-6 pb-8 animated fadeIn" style="outline:none" #submit.prevent="signIn">
<section class="mb-4">
<label class="block text-grey-darker text-sm font-bold mb-2" for="email">
Email
</label>
<input class="shadow hover:shadow-md bg-transparent appearance-none border-2 border-grey rounded w-full py-2 px-3 text-grey-darker"
style="outline:none" type="email" v-model="email" placeholder="demo#example.co.uk">
</section>
<section class="mb-6">
<label class="block text-grey-darker text-sm font-bold mb-2" for="password">
Password
</label>
<input class="shadow hover:shadow-md bg-transparent appearance-none border-2 border-grey rounded w-full py-2 px-3 text-grey-darker"
style="outline:none" type="password" v-model="password" placeholder="********">
</section>
<section class="flex items-center justify-between">
<button class="bg-grey-darker hover:bg-grey-darkest w-full text-white font-semibold py-3 px-4 border rounded-sm shadow" style="outline:none">
Sign In
</button>
</section>
<a class="flex justify-center pt-6 pb-px font-semibold text-sm text-grey hover:text-green-darker" href="#sign-up">
Create an account
</a>
<a class="flex justify-center font-semibold text-sm text-grey hover:text-green-darker" href="#forgot-password">
Forgot Password?
</a>
</form>
<button class="twitch flex justify-center absolute pin-l items-center p-8 uppercase text-white font-semibold tracking-wide w-full" #click="twitch">
<i class="fab fa-twitch pr-2 text-xl"></i> Sign in with Twitch
</button>
</section>
</template>
<script>
import firebase from '#/middleware/firebase'
import axios from 'axios'
export default {
data: function () {
return {
email: '',
password: ''
}
},
methods: {
signIn () {
firebase.auth().signInWithEmailAndPassword(this.email, this.password),
console.log('Signed in with ' + this.email)
},
twitch: function () {
return axios.get(
'https://id.twitch.tv/oauth2/authorize?response_type=code&client_id=<KEY>&redirect_uri=http://localhost:3000&scope=chat_login'
).then(res => {
console.log(res)
})
}
}
}
</script>
I'm not sure what I'm doing wrong here, at the moment I just want to console log the response then I'll go from there.
Any help is appreciated!
Your problem is about CORS (see https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS).
You are try to reach a resource from a domain to another domain, which is only possible if expicitly allowed.