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
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>
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>
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
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>
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.