I keep getting error Uncaught (in promise) ReferenceError: can't access lexical declaration 'primaryColor' before initialization as Iam trying to migrate from vue2 to vue 3
This is my code
<template>
<div class="introduce-connect-block pt-0 pb-0">
<img v-if="parameters.WELCOME_IMAGE" class="introduce-hero-image" :src="parameters.WELCOME_IMAGE" alt="" />
<img v-else class="introduce-hero-image" src="/images/heros.png" alt="" />
<p class="pop-wd-heading pop-mb-80">Welcome to {{ brandName }}</p>
</div>
</template>
<script setup>
import { defineProps, computed } from "vue";
const props = defineProps({
parameters: Object
});
const store = useStore();
const primaryColor = computed(() => store.getters["auth/color"]);
const brandName = computed(() => store.getters["auth/brandName"]);
</script>
<style lang="scss">
#media screen and (max-device-width: 480px) and (orientation: portrait) {
.connect-button-bg {
border: 2px solid v-bind(primaryColor);
}
}
</style>
The error is happening in line
border: 2px solid v-bind(primaryColor);
The value of primaryColor is in store, how can I fix this?
Related
I'm trying to create Todo List App with Laravel and Vue.js.
I have problem with that title error.
I've watched this video (https://www.youtube.com/watch?v=UHSipe7pSac&t=2482s) for paractcing
And also, I've done until 47:50, but when I wrote a a code listItem.vue, It didn't work as shown in video.
Although I compared with mycode for many times, I couldn't where is wrong.
If you have solution, Please tell me how to fix.
And, What is best way how to debug apps with laravel and Vue.js?
Here is my version
php
7.3.11
vue
vue#3.2.31
listItem.vue
<template>
<div class="item">
<input type="checkbox" #change="updateCheck()" v-model="item.completed" />
<span>{{ item.name }}</span>
<button #click="removeItem()" class="trashcan">
<font-awesome-icon icon="trash" />
</button>
</div>
</template>
<script>
export default {
props: ["item"],
};
</script>
<style scoped>
.completed {
text-decoration: line-through;
color: #999999;
}
.itemTexgt {
width: 100%;
margin-left: 20px;
}
.item {
display: flex;
justify-content: center;
align-items: center;
}
.trashcan {
background: #e6e6e6;
border: none;
color: #ff0000;
outline: none;
}
</style>
app.vue
<template>
<div class="todoListContainer">
<div class="heading">
<h2 id="title">TodoList</h2>
<add-item-form />
</div>
<list-view :items="items" />
</div>
</template>
<script>
import addItemForm from "./addItemForm.vue";
import listView from "./listView.vue";
export default {
components: {
addItemForm,
listView,
},
data: function () {
return {
items: [],
};
},
methods: {
getList() {
axios
.get("api/items")
.then((response) => {
this.items = response.data;
})
.catch((error) => {
console.log(error);
});
},
},
created() {
this.getList();
},
};
</script>
<style scoped>
.todoListContainer {
width: 350px;
margin: auto;
}
.heading {
background: #e6e6e6;
padding: 10px;
}
#title {
text-align: center;
}
</style>
error.log
app.js:34649 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'completed')
at Proxy.render (app.js:34649:69)
at renderComponentRoot (app.js:22841:44)
at ReactiveEffect.componentUpdateFn [as fn] (app.js:26958:57)
at ReactiveEffect.run (app.js:20778:25)
at setupRenderEffect (app.js:27084:9)
at mountComponent (app.js:26867:9)
at processComponent (app.js:26825:17)
at patch (app.js:26426:21)
at mountChildren (app.js:26613:13)
at mountElement (app.js:26522:17)
postscript
listView.vue
<template>
<div>
<div v-for="(item, index) in items" :key="index"></div>
<list-item :item="item" class="item" />
</div>
</template>
<script>
import listItem from "./listItem.vue";
export default {
props: ["items"],
components: {
listItem,
},
};
</script>
<style scoped>
.item {
background: #e6e6e6;
padding: 5px;
margin-top: 5px;
}
</style>
I learned and understood listItem.vue's parent is listView.vue.
What a silly mistake I had made!
<template>
<div>
<div v-for="(item, index) in items" :key="index"></div>
<list-item :item="item" class="item" />
</div>
</template>
↓
<div v-for="(item, index) in items" :key="index">
<list-item
:item="item"
class="item"
v-on:itemchanged="$emit('reloadlist')"
/>
</div>
sorry to take up your time.
i am following this tutorial.
https://www.youtube.com/watch?v=4deVCNJq3qc
below is my code for QuestionBox.vue
<template>
<div>
{{ currentQuestion.question}}
</div>
</template>
<script>
export default {
props: {
currentQuestion: Object
}
}
</script>
Below is code for App.vue
<template>
<div>
<Header />
<QuestionBox
:currentQuestion="questions[index]"
/>
</div>
</template>
<script>
import Header from './components/Header.vue'
import QuestionBox from './components/QuestionBox.vue'
export default {
name: 'app',
components: {
Header,
QuestionBox
},
data(){
return {
questions:[],
index:0
}
},
mounted: function(){
fetch('https://opentdb.com/api.php?amount=4&type=multiple',{
method: 'get'
})
.then((response) => {
return response.json()
})
.then((jsonData) => {
this.questions = jsonData.results
})
}
}
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
when i compile the code it succeeded but i am not getting the expected result which is question from index 0, instead when i do inspect i am getting error Uncaught TypeError: $props.currentQuestion is undefined .
I am stuck there for 2 days, What i am doing wrong? Please help. Thanks in advance.
Add v-if="questions[index]" on your <QuestionBox>.
You're fetching data for this.questions in your mounted hook so there is a period where the questions array is empty. So you're passing questions[index] or questions[0] to the <QuestionBox> as a prop. At that time, questions[0] evaluates to undefined. So in your QuestionBox you're trying to access the property question of undefined. {{ currentQuestion.question}} Which gives you an error.
<template>
<div>
<Header />
<QuestionBox
v-if="questions[index]"
:currentQuestion="questions[index]"
/>
</div>
</template>
Add a v-if to the <div> tag in Questionbox.vue:
<template>
<div v-if="currentQuestion">
{{ currentQuestion.question }}
</div>
</template>
This will prevent Vue from attempting to render until there is data present in currentQuestion. Then when currentQuestion becomes truthy it will be rendered.
See also: https://stackoverflow.com/a/41052023/2073738
You can also change the initial value of questions to questions:[{}] in App.vue
I've created a component in Nuxt to get data from a Firestore database and would like to show that data in a page I created.
When I embed the component in a page I keep getting the error:
Property or method "provinces" 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.
Now, when I copy the code from the component in the page it works just fine, so I assume the problem is with passing the data between the component and the page.
Full code of the component in components/index.vue :
<template>
<section class="container">
<div class="index">
<div v-for="province in provinces" :key="province.id">
<div class="div_title">
<h2>{{ province.name_nl }}</h2>
</div>
</div>
</div>
</section>
</template>
<script>
// import { VueperSlides, VueperSlide } from 'vueperslides'
// import 'vueperslides/dist/vueperslides.css'
import firebase from 'firebase'
// import fireDb from '#/plugins/firebase.js'
export default {
name: 'Index',
components: {
// VueperSlides,
// VueperSlide
},
data: function() {
return {}
},
async asyncData() {
const moment = require('moment')
const date = moment(new Date()).format('YYYY-MM-DD')
const housesArray = []
const provincesArray = []
await firebase
.firestore()
.collection('provinces')
.orderBy('name_nl')
.get()
.then(querySnapshot => {
querySnapshot.forEach(doc => {
provincesArray.push(doc.data())
})
})
await firebase
.firestore()
.collection('houses')
.where('valid_until', '>', date)
.get()
.then(querySnapshot => {
querySnapshot.forEach(doc => {
housesArray.push(doc.data())
})
})
return {
provinces: provincesArray,
houses: housesArray
}
}
}
</script>
<style scoped>
div {
text-align: center;
}
h2 {
margin-top: 5vh;
margin-left: auto;
margin-right: auto;
width: 95vh;
}
h3 {
margin: 40px 0 0;
}
ul {
list-style-type: none;
padding: 0;
}
p {
text-align: left;
}
li {
min-width: 100% !important;
margin-left: 0px;
text-align: left;
}
</style>
Page where I insert the component in pages/index.vue:
<template>
<v-layout column justify-center align-center>
<v-flex xs12 sm8 md6>
<div class="text-xs-center">
<logo />
<tabs />
<index />
</div>
</v-flex>
</v-layout>
</template>
<script>
import Logo from '~/components/Logo.vue'
import Tabs from '~/components/Tabs.vue'
import firebase from 'firebase'
import Index from '~/components/Index.vue'
export default {
components: {
Logo,
Tabs,
Index
},
data: function() {
return {}
}
}
</script>
I would expect the page to display the data that I retrieved when I import the component into the page but I keep getting the same error.
Should I be using the Nuxt store to transfer data between a component and a page or am I doing something else wrong?
The lifecycle hook asyncData is not know within Vue components. It's only known in Nuxt pages.
It's better to do the data request within your pages component and pass it as a property to your component:
pages/index.vue
<template>
<index :houses="houses" />
</template>
<script>
const delay = time => new Promise(resolve => setTimeout(resolve, time));
export default {
async asyncData() {
// fake data
await delay(500);
return {
houses: [...]
}
}
}
</script>
components/index.vue
<template>
<pre>{{ houses }}</pre>
</template>
<script>
export default {
props: {
houses: {
required: true,
type: Array
}
}
}
</script>
I am using mdb theme when the project is uploaded on aws instance footer gets break on right side. I checked the css the width of footer is 100% by default for mdb theme.
Below is the code-
App.vue
<template>
<div id="app">
<div class="flexible-content">
<navbar :page="activePage" />
<main class="mt-5 p-5">
<div class="pt-5">
<router-view></router-view>
</div>
</main>
<div class="white-skin">
<copyrights />
</div>
</div>
</div>
</template>
<script>
import SideNav from './components/SideNav'
import Navbar from './components/Navbar'
import Copyrights from './components/Footer'
import * as vm from "vue";
export default {
name: 'App',
mode:'history',
components: {
SideNav,
Navbar,
Copyrights
},
data () {
return {
activePage: 'dashboard',
toggle: false,
loader:true,
}
},
mounted () {
this.activePage = this.$route.name;
this.$on('toggle', function (value) {
this.toggle = value
});
},
updated () {
this.activePage = this.$route.name
}
}
</script>
<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
Footer.vue
<template>
<mdb-footer>
<p class="footer-copyright mb-0 py-3 text-center">
© {{new Date().getFullYear()}} Copyright: xyz
</p>
</mdb-footer>
</template>
<script>
import { mdbFooter } from 'mdbvue'
export default {
name: 'Footer',
components: {
mdbFooter
},
data () {
return {
}
}
}
</script>
<style scoped>
</style>
This is the code of App.vue and Footer.vue .It is perfectly working on localhost but not on instance. After upload on instance footer gets break from right side
I have a button that is set to be disabled if a computed property's valid property is false. If true, the button should be enabled and allow a user to move to the next step in the current flow.
My currentStep computed property is updating perfectly on changes to the current step's inputs, but the button :disabled="currentStep.valid" isn't recognizing the changes that ARE HAPPENING to currentStep.valid.
If I click on the current component (addnewprogram) in vue-devtools to see it's data, the button displays correctly!
Seen here: http://recordit.co/XH6HX7JLhV
However, without clicking on addnewprogram in the devtools, it doesn't function correctly.
Is there an obvservation caveat I'm missing?
The code for this functionality can be found here:
<template>
<section class="newprogram">
<div class="newprogram--content">
<div class="newprogram--stepone" v-if="progression.current === 1">
<div class="content--left">
<a class="link uppercase">use existing program information<i class="fa fa-picture-o"></i></a>
<base-input v-for="input in currentStep.inputs"
:key="input.id"
:data="input"
v-model="input.value"></base-input>
</div>
<div class="content--right">
<!-- images -->
</div>
</div>
<div class="newprogram--steptwo" v-if="progression.current === 2">
<choice-progression :step="1"></choice-progression>
</div>
</div>
</div>
<!-- Consistent among all steps -->
<div class="container--bottomnav">
<div class="bottomnav--left">
<base-btn class="button-fluid"
:data="currentStep.btns[0]"></base-btn>
</div>
<div class="bottomnav--right">
<base-btn :data="currentStep.btns[1]"
:disabled="currentStepValid"></base-btn>
</div>
</div>
<!-- -->
</section>
</template>
<script>
import bottomNav from '../main/bottom-nav.vue';
import baseProgressionBarbell from '../base/base-progression-barbell.vue';
import baseInstruction from '../base/base-instruction.vue';
import baseInput from '../base/base-input.vue';
import baseBtn from '../base/base-btn.vue';
import choiceProgression from '../secondary-flows/choice-progression.vue';
export default {
name: 'addNewProgram',
components: {
bottomNav,
baseProgressionBarbell,
baseInstruction,
baseInput,
baseBtn,
choiceProgression
},
computed: {
progression () {
return this.$store.getters.getProgression('addnewprogram');
},
steps () {
return this.$store.getters.getSteps('addnewprogram');
},
currentStep () {
return this.steps[this.progression.current - 1];
},
currentStepValid () {
return this.currentStep.valid == false ? true : false;
},
stepOneValidation () {
this.steps[0].inputs.forEach(input => {
if (!input.value) {
return this.$set(this.steps[0], 'valid', false);
}
this.$set(this.steps[0], 'valid', true);
});
},
stepTwoChoices() {
return this.$store.getters.getChoices('addnewprogram', 1);
}
}
}
</script>
<style lang="sass" scoped>
#import '../../sass/_variables.sass'
.newprogram
display: flex
flex-direction: column
.container--newprogram
display: flex
flex-direction: column
height: 100%
padding: $s1
.newprogram--header
display: flex
justify-content: space-between
align-items: center
h1
padding: 0
.newprogram--content
display: flex
// justify-content: center
// align-items: center
height: 100%
padding-top: $s2
</style>
You are updating members of a computed item. Computed items aren't editable. You need a data item, or you need to write your changes to the $store and have them refresh from there.