Calling the Twitch API with axios and Vue - vue.js

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.

Related

I'm trying to use Dialog headless ui as a way to open a modal out of my dropdown, but everything I've tried so far hasn't worked

Apologies as I'm new to headless ui and vue in general. I have a dropdown in my parent component that works. What I'm trying to do is use dialog to open a modal upon clicking the button in the dropdown. The issue is everyway I have thought to try either causes the dropdown to flash open and close, or the dropdown to open, allow me to click the modal button, but nothing happens, no modal appears. Below is my code for the dialog modal:
<template>
<div class="flex items-center justify-center">
<button type="button" #click="openModal" class="rounded-md bg-black bg-opacity-20 px-4 py-2 text-sm font-medium text-white hover:bg-opacity-30 focus:outline-none focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-opacity-75">
Open dialog
</button>
</div>
<TransitionRoot appear :show="isOpen" as="template">
<Dialog as="div" #close="closeModal" class="relative">
<TransitionChild as="template" enter="duration-300 ease-out" enter-from="opacity-0" enter-to="opacity-100" leave="duration-200 ease-in" leave-from="opacity-100" leave to="opacity-0">
<div class="fixed inset-0 bg-black bg-opacity-25" />
</TransitionChild>
<div class="fixed inset-0 overflow-y-auto">
<div
class="flex min-h-full items-center justify-center p-4 text-center"
>
<TransitionChild as="template" enter="duration-300 ease-out" enter-from="opacity-0 scale-95" enter-to="opacity-100 scale-100" leave="duration-200 ease-in" leave-from="opacity-100 scale-100" leave-to="opacity-0 scale-95">
<DialogPanel
class="w-full max-w-md transform overflow-hidden rounded-2xl bg-white p-6 text-left align-middle shadow-xl transition-all"
>
<DialogTitle
as="h3"
class="text-lg font-medium leading-6 text-gray-900"
>
Payment successful
</DialogTitle>
<div class="mt-2">
<p class="text-sm text-gray-500">
Your payment has been successfully submitted. We’ve sent you
an email with all of the details of your order.
</p>
</div>
<div class="mt-4">
<button
type="button"
class="inline-flex justify-center rounded-md border border-transparent bg-blue-100 px-4 py-2 text-sm font-medium text-blue-900 hover:bg-blue-200 focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2"
#click="closeModal"
>
Got it, thanks!
</button>
</div>
</DialogPanel>
</TransitionChild>
</div>
</div>
</Dialog>
</TransitionRoot>
</template>
<script setup>
import { ref } from 'vue'
import {
TransitionRoot,
TransitionChild,
Dialog,
DialogPanel,
DialogTitle,
} from '#headlessui/vue'
const isOpen = ref(true)
function closeModal() {
isOpen.value = false
}
function openModal() {
isOpen.value = true
}
</script>

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>

VueJS 3 - How to use draggable nested element but prevent duplicate item

I am trying to create a simple survey builder with Vue3 and Vue Draggable. All is going well until I try to create a multiple choice question. This type of questions has its own sortable list of possible answers. When I add another multiple choice question it then pulls from the same list which makes sense but I have tried to use a v-if to check the parents ID to match the choice ID..
Basically if I add a new choice it adds to the all multiple choice questions, which makes sense, but how to I keep it to the current item I am in?
Any ideas? I know the code is mess, it will be refactored once it works.
<template>
<div class="p-4">
<div class="container mx-auto rounded-md grid grid-cols-12 gap-4 h-full">
<div class="col-span-4 p-3 flex flex-col min-h-screen bg-gray-200 shadow-md rounded-md">
<div class="text-lg font-bold w-full bg-blue-600 text-white rounded-md p-2 mb-4">Builder your survey</div>
<div class="sticky top-4">
<div class="text-lg font-bold">Components</div>
<draggable
class="p-2 rounded-md"
:list="componentsList"
:group="{ name: 'questions', pull: 'clone', put: false, sort: false }"
:clone="cloneItem"
sort: false
#change="log"
item-key="id"
>
<template #item="{ element }">
<div
class="bg-gray-300 p-4 rounded-md mt-2 shadow-sm hover:shadow-md cursor-pointer border border-blue-800 border-dashed"
>
{{ element.name }}
</div>
</template>
</draggable>
</div>
</div>
<div class="col-span-8 flex p-3 flex-col bg-white shadow-md rounded-md">
<div class="text-lg font-bold pt-4">Survey</div>
<draggable
class="w-full h-full border border-blue-400 rounded-md p-2 flex flex-col flex-1"
:list="questionsList"
group="questions"
#change="log"
handle=".handle"
itemKey="name + index"
>
<template #item="{ element, index }">
<div>
<div v-if="element.name == 'Single Line of Text'" class="bg-gray-300 p-2 rounded-md mt-2 mb-2 shadow-lg hover:shadow-md">
<div class="w-full text-sm text-left">{{ element.name }} {{element.id}}</div>
<div class="flex justify-between items-center p-2 bg-gray-200 rounded-md mb-4">
<div class="w-10 font-bold hidden">Q{{ index + 1 }}</div>
<div class="w-full pr-4">
<input
type="text"
class="w-full p-2 bg-transparent flex-grow"
placeholder="Question title here..."
v-model="element.text"
/>
</div>
<div class="flex ">
<div class="cursor-pointer">
<i class="handle las la-arrows-alt la-2x mr-2"></i>
</div>
<div #click="remove(index)">
<i class="las la-trash-alt text-red-800 la-2x cursor-pointer"></i>
</div>
</div>
</div>
<div>
<input
type="text"
class="w-full p-2 rounded-md border border-gray-400"
placeholder="User response will go here"
/>
</div>
<div class="text-left flex justify-between items-center p-2 bg-gray-200 rounded-md mt-2">
<div class="flex items-center">
<div><input type="checkbox" class="mr-2" /></div>
<div>Required?</div>
</div>
</div>
</div>
<!-- START problem area -->
<div v-else-if="element.name == 'Multiple Choice'" class="bg-gray-300 p-2 rounded-md mt-2 mb-2 shadow-lg hover:shadow-md">
<div class="w-full text-sm text-left">{{ element.name }} {{element.id}}</div>
<div class="flex justify-between items-center p-2 bg-gray-200 rounded-md mb-4">
<div class="w-10 font-bold hidden">Q{{ index + 1 }}</div>
<div class="w-full pr-4">
<input
type="text"
class="w-full p-2 bg-transparent flex-grow"
placeholder="Question title here..."
v-model="element.text"
/>
</div>
<div class="flex ">
<div class="cursor-pointer">
<i class="handle las la-arrows-alt la-2x mr-2"></i>
</div>
<div #click="remove(index)">
<i class="las la-trash-alt text-red-800 la-2x cursor-pointer"></i>
</div>
</div>
</div>
<div class="flex items-center ">
<draggable
class="p-2 rounded-md w-full"
:list="multipleChoiceList"
:group="{ name: 'choice', pull: false, put: false, sort: true }"
sort: true
handle=".handle"
#change="log"
item-key="question"
>
<template #item="{ element }">
<div
class="bg-blue-100 p-4 flex items-center justify-start rounded-md mt-2 shadow-sm hover:shadow-md cursor-pointer w-full"
>
<div class="flex items-center flex-grow"
>
<input type="checkbox" class="w-6 h-6">
<input
type="text"
class="p-2 bg-transparent flex-grow"
placeholder="Add choice here"
v-model="element.text"
/>
</div>
<div class="flex ">
<div class="cursor-pointer">
<i class="handle las la-arrows-alt la-1x mr-2"></i>
</div>
<div #click="remove(index)">
<i class="las la-trash-alt text-red-800 la-1x cursor-pointer"></i>
</div>
</div>
</div>
</template>
<template #footer>
<div>
<button class="p-2 bg-blue-300 mt-2 rounded-md" #click="addChoice(element.id)">Add</button>
</div>
</template>
</draggable>
</div>
<div class="text-left flex justify-between items-center p-2 bg-gray-200 rounded-md mt-2">
<div class="flex items-center">
<div><input type="checkbox" class="mr-2" /></div>
<div>Required?</div>
</div>
</div>
</div>
<!-- END problem area -->
<div v-else-if="element.name == 'Open Ended'" class="bg-gray-300 p-2 rounded-md mt-2 mb-2 shadow-lg hover:shadow-md">
<div class="w-full text-sm text-left">{{ element.name }} {{element.id}}</div>
<div class="flex justify-between items-center p-2 bg-gray-200 rounded-md mb-4">
<div class="w-10 font-bold hidden">Q{{ index + 1 }}</div>
<div class="w-full pr-4">
<input
type="text"
class="w-full p-2 bg-transparent flex-grow"
placeholder="Question title here..."
v-model="element.text"
/>
</div>
<div class="flex ">
<div class="cursor-pointer">
<i class="handle las la-arrows-alt la-2x mr-2"></i>
</div>
<div #click="remove(index)">
<i class="las la-trash-alt text-red-800 la-2x cursor-pointer"></i>
</div>
</div>
</div>
<div>
<textarea
class="h-32 w-full w-full p-2 rounded-md border border-gray-400"
></textarea>
</div>
<div class="flex items-center">
<div>Max Length</div>
<div>
<input
type="number"
class="mr-2 w-20 border border-gray-400 p-2 rounded-md ml-2"
/>
</div>
</div>
<div class="text-left flex justify-between items-center p-2 bg-gray-200 rounded-md mt-2">
<div class="flex items-center">
<div><input type="checkbox" class="mr-2" /></div>
<div>Required?</div>
</div>
</div>
</div>
<div v-else-if="element.name == 'Divider'">
<div class="flex items-center">
<div class="flex-grow border-t border-black mx-4"> </div>
<div class="flex ">
<div class="cursor-pointer">
<i class="handle las la-arrows-alt la-2x mr-2"></i>
</div>
<div #click="remove(index)">
<i class="las la-trash-alt text-red-800 la-2x cursor-pointer"></i>
</div>
</div>
</div>
</div>
</div>
</template>
</draggable>
</div>
</div>
</div>
</template>
See Clone method which assigns a random number as the id
<script>
import draggable from "vuedraggable";
export default {
name: "Survey",
components: {
draggable,
},
data() {
return {
drag: false,
componentsList: [
{ name: "Single Line of Text", type: "question", text: "", id: 1 },
{ name: "Multiple Choice", type: "question", text: "", id: 2 },
{ name: "Matrix", type: "question", text: "", id: 3 },
{ name: "Open Ended", type: "question", text: "", id: 4 },
{ name: "Divider", type: "component", id: 9 },
],
questionsList: [],
multipleChoiceList: [
{text: "text A", type:"choice", question:"32"},
{text: "text B", type:"choice", question:"1"},
{text: "text A", type:"choice", question:"2"} ]
};
},
methods: {
onEnd: function(evt) {
console.log(evt);
},
log: function(evt) {
console.log(evt);
},
addChoice(id) {
this.multipleChoiceList.push({ text: "Choice " + id, type: "choice", question:id });
console.log(this.multipleChoiceList);
},
remove(index) {
this.questionsList.splice(index, 1);
},
cloneItem({ id, name, type }) {
return {
name: name,
id: Math.ceil(Math.random()*100),
text: "",
type: type,
};
}
},
mounted() {
// console.log("mounted");
},
};
</script>
https://github.com/SortableJS/Vue.Draggable/issues/687#issuecomment-1153083717
I just answered to a similar question on github.
Not sure would this help as Vue.Draggable and vue.draggable.next is slightly different.

TailwindCSS - Change Label When Radio Button Checked

I see that the TailwindCSS checked: variant can be enabled to change the input element when checked, but how can I change the input's label when checked?
Here is the relevant Tailwind CSS docs.
Sample code below.
After enabling the variant in tailwind.config.js, putting checked:bg-green-300 in the div or the label doesn't work. It only works in the input.
<div>
<label>
<input checked type="radio" name="option1" id="option1" className="hidden" />
<div>option1</div>
</label>
<label>
<input checked type="radio" name="option2" id="option1" className="hidden" />
<div>option2</div>
</label>
</div>
EDIT: as version 2.2+ was released it has built-in support for sibling selector variants called peer (watch updates release)
This feature is only available in Just-in-Time mode.
<label>
<input checked type="radio" name="option" id="option1" class="hidden peer" />
<div class="peer-checked:bg-red-600">option1</div>
</label>
For versions bellow 2.2:
You need to write your own plugin for adding new variant. Mor info here
For example, let name it label-checked
tailwind.config.js
const plugin = require('tailwindcss/plugin');
module.exports = {
purge: [],
darkMode: false, // or 'media' or 'class'
theme: {},
variants: {
extend: {
backgroundColor: ['label-checked'], // you need add new variant to a property you want to extend
},
},
plugins: [
plugin(({ addVariant, e }) => {
addVariant('label-checked', ({ modifySelectors, separator }) => {
modifySelectors(
({ className }) => {
const eClassName = e(`label-checked${separator}${className}`); // escape class
const yourSelector = 'input[type="radio"]'; // your input selector. Could be any
return `${yourSelector}:checked ~ .${eClassName}`; // ~ - CSS selector for siblings
}
)
})
}),
],
};
This configuration should work for next cases (We extended backgroundColor, so it should work with bg-color classes):
1 - label is the wrapper, it's text should wrapped in any selector (in this case div)
<label>
<input checked type="radio" name="option1" id="option1" class="hidden" />
<div class="label-checked:bg-red-600">option1</div>
</label>
2 - label after input
<input checked type="radio" name="option1" id="option1" class="hidden" />
<label for="option-1" class="label-checked:bg-red-600"></label>
DEMO - https://play.tailwindcss.com/SEQ4NRpPV3
Use the peer class as per the tailwind 2.2.0
<input type="checkbox" name="themeToggler" id="themeToggler" class="peer" />
<label for="themeToggler" class="w-10 h-10 bg-gray-400 peer-checked:bg-red-400"></label>
DEMO
Tailwind's peer class is the modern way to solve this.
You can add peer behavior by adding two classes to the HTML.
Add the peer class to the HTML tag you want to observe the state for.
Add the peer-checked class, followed by the desired behavior change, to a sibling element.
See a detailed example here
In Tailwind CSS 3.0 you can create custom radio button like this
<div class="p-3 h-screen w-full flex justify-center items-center bg-black">
<div class="w-full">
<div class="flex">
<p class="text-[20px] text-white">Which of the following is an asian country?</p>
</div>
<div class="md:grid grid-cols-12 gap-3 pb-4 w-full">
<div className="col-span-6">
<div class="w-full">
<input id="default-radio-1" type="radio" value="" name="default-radio" class="peer opacity-0 w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600">
<label for="default-radio-1" class="flex cursor-pointer bg-gray-200 justify-center items-center h-10 w-full peer-checked:bg-rose-500 peer-checked:text-white text-[17px] text-sm font-medium text-gray-900 dark:text-gray-300">India</label>
</div>
</div>
<div className="col-span-6">
<div class="w-full">
<input id="default-radio-2" type="radio" value="" name="default-radio" class="peer opacity-0 w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600">
<label for="default-radio-2" class="flex cursor-pointer bg-gray-200 justify-center items-center h-10 w-full peer-checked:bg-rose-500 peer-checked:text-white text-[17px] text-sm font-medium text-gray-900 dark:text-gray-300">Australia</label>
</div>
</div>
<div className="col-span-6">
<div class="w-full">
<input id="default-radio-3" type="radio" value="" name="default-radio" class="peer opacity-0 w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600">
<label for="default-radio-3" class="flex cursor-pointer bg-gray-200 justify-center items-center h-10 w-full peer-checked:bg-rose-500 peer-checked:text-white text-[17px] text-sm font-medium text-gray-900 dark:text-gray-300">USA</label>
</div>
</div>
<div className="col-span-6">
<div class="w-full">
<input id="default-radio-4" type="radio" value="" name="default-radio" class="peer opacity-0 w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600">
<label for="default-radio-4" class="flex cursor-pointer bg-gray-200 justify-center items-center h-10 w-full peer-checked:bg-rose-500 peer-checked:text-white text-[17px] text-sm font-medium text-gray-900 dark:text-gray-300">Germany</label>
</div>
</div>
</div>
</div>
Checkout this running example - https://bbbootstrap.com/snippets/custom-radio-button-91048657

Vue syntax error: Unexpected Token

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.