I'm doing a FE based on [THIS VUE TEMPLATE][https://www.creative-tim.com/product/vue-material-dashboard-pro]
I am trying to register a component locally, but I keep getting the error:
"103:5 error The "BFCookieCard" component has been registered but
not used"
I did not have any success with the answers shared in:
I'm getting an error of 13:5 error The “Home” component has been registered but not used vue/no-unused-components
component has been registered but not used vue/no-unused-components
Vue component defined but not used error message. How do I use it properly?
Remove 'component has been registered but not used' in eslint for Vue.js
My Files are as follows:
BFConsentCookie.vue
<template>
<h1> HELLO </h1>
</template>
<script>
export default {
name: "bf-cookie-card",
data() {
return {};
},
beforeMount() {
},
}
Login.vue
<template>
<div>
<bf-cookie-card>
</bf-cookie-card>
</div>
</div>
</template>
<script>
import { BFCookieCard} from "#/components";
export default {
components: {
BFCookieCard,
},
data() {
return {};
},
}
index.js
import BFCookieCard from "./Cards/BFCookieCard.vue";
export {
BFCookieCard
}
The problem is the capital F in BFCookieCard, replace it with BfCookieCard.
In your login.vue you can also import your component like that:
components: {
BfCookieCard: () => import('path to component file.vue'),
},
Related
Instead of mounting my component directly to #app, I'm trying to push my component one level down so I can pass props to it from the HTML file it lives in. However, nothing shows up and there aren't any console errors. I'm sure it's just me misunderstanding how Vue 3 and createApp works.
My HTML file:
<div id="app">
<my-component />
</div>
My main JS file:
import { createApp } from 'vue'
import MyComponent from './pages/MyComponent.vue'
import { IonicVue } from '#ionic/vue'
const app = createApp({
components: {
MyComponent: {
props: {
},
}
},
})
.use(IonicVue)
.mount("#app");
Thank you in advance!
When using props validation in Vue, it only shows errors during the runtime in the browser console.
But I want to get props validation to work during the static code analysis phase (linting).
For example, I have used the default Vue 2 project template:
HelloWorld.vue is the component that has msg prop and it's required:
<template>
<h1>Message: {{ msg }}</h1>
</template>
<script>
export default {
name: 'HelloWorld',
props: {
msg: {
type: String,
required: true,
},
},
};
</script>
App.vue is using HelloWorld component, but doesn't specify msg prop. Instead, it uses non-existent prop something:
<template>
<HelloWorld :something="somewhat" />
</template>
<script>
import HelloWorld from './components/HelloWorld.vue';
export default {
name: 'App',
components: {
HelloWorld,
},
};
</script>
I expect at least some of these requirements to be met when I run npm run lint:
it should say Error: required "msg" prop not found
it should say Warning: unknown "something" prop has been used
also, if I assign something other than String to msg prop, it should say Error: prop "msg" should be String, but received *NotString*
In other words, I want Vue templates to be lintable, like JSX templates in React.
Is there any way I can achieve this in Vue 2 or Vue 3? Perhaps, some eslint plugins?
If this can be solved using TypeScript - that would be super awesome.
A solution to this problem, which works in both Vue 2 and Vue 3 is to use JSX (TSX).
Here's a Vue 3 example:
HelloWorld.tsx:
import { defineComponent } from "vue";
export default defineComponent({
name: "HelloWorld",
props: {
msg: {
type: String,
required: true,
},
},
setup: (props) => () => <h1>{props.msg}</h1>,
});
App.tsx:
import { defineComponent } from "vue";
import HelloWorld from "./components/HelloWorld";
export default defineComponent({
name: "App",
render: () => <HelloWorld msg={"123"} />,
});
Here's Vue 2 example repo: https://github.com/Maxim-Mazurok/vue-2-tsx-example
And Vue 3: https://github.com/Maxim-Mazurok/vue-3-tsx-example
I have two components:
App.vue
Sidekick.vue
In my App.vue component, I have a property that I would like to access from Sidekick.vue
App.vue
<template>
<div id="app">
<p>{{ myData }}</p>
<div class="sidebar">
<router-view/> // our sidekick component is shown here
</div>
</div>
</template>
<script>
export default {
name: 'App',
data () {
return {
myData: 'is just this string'
}
}
}
</script>
Sidekick.vue
<template>
<div class="sidekick">
{{ myData }}
</div>
</template>
<script>
export default {
name: 'Sidekick'
}
</script>
I would like access to myData (which is declared in App.vue) from Sidekick.vue
I have tried importing App.vue from within Sidekick.vue by doing something like:
Sidekick.vue (incorrect attempt)
<script>
import App from '#/App'
export default {
name: 'Sidekick',
data () {
return {
myData: App.myData
}
}
}
</script>
I have read about props - but have only seen references to child / parent components. In my case, Sidekick.vue is shown in a div inside App.vue (not sure if this makes it a "child"). Do I need to give access of myData to <router-view/> somehow?
UPDATE: (to show relationship between App.vue and Sidekick.vue
index.js (router file)
import Vue from 'vue'
import Router from 'vue-router'
import Sidekick from '#/components/Sidekick',
import FakeComponent from '#/components/FakeComponent'
Vue.use(Router)
const router = new Router({
routes: [
{
path: '/',
redirect: '/fakecomponent'
},
{
path: '/sidekick',
name: 'Sidekick',
component: Sidekick
},
{
path: '/fakecomponent',
name: 'FakeComponent',
component: FakeComponent
}
]
})
export default router
Sidekick.vue gets rendered when we hit /sidekick
Just keep in mind, the rule of thumb is using props to pass data in a one-way flow
props down, events up.
https://v2.vuejs.org/v2/guide/components.html#Composing-Components
Quick solution:
Global event bus to post messages between your <App/> and <Sidekick/> components.
https://v2.vuejs.org/v2/guide/components.html#Non-Parent-Child-Communication
Long term solution:
Use a state management library like vuex to better encapsulates data in one place (a global store) and subscribe it from your components tree using import { mapState, mapMutations } from 'vuex'
When you have parent-child communication, the best and recommended
option is to use props and events. Read more in Vue docs
When want to have shared state between many components the best and
recommended way is to use Vuex.
If you want to use simple data sharing you can use Vue observable.
Simple example: Say that you have a game and you want the errors to be accessible by many components. (components can access it and manipulate it).
errors.js
import Vue from "vue";
export const errors = Vue.observable({ count: 0 });
Component1.vue
import { errors } from 'path-of-errors.js'
export default {
computed: {
errors () {
get () { return errors.count },
set (val) { errors.count = val }
}
}
}
In Component1 the errors.count is reactive. So if as a template you have:
<template>
<div>
Errors: {{ errors }}
<button #click="errors++">Increase</button>
</div>
</template>
While you click the Increase button, you will see the errors increasing.
As you might expect, when you import the errors.js in another component, then both components can participate on manipulating the errors.count.
Note: Even though you might use the Vue.observable API for simple data sharing you should be aware that this is a very powerful API. For example read Using Vue Observables as a State Store
App.vue:
<router-view pass_data='myData'/>
Sidekick.vue:
export default {
name: "Sidekick",
props: ["pass_data"],
created() {
alert("pass_data: "+this.pass_data)
}
}
If App.js(Parent) and Sidekick(Child)
App.js
in Template
In script
import Sidekick from './Sidekick.vue:
Sidekick.vue
props: ['myData']
now you can access myData anywhere in sidekick.
In template myData and
in scripts this.myData
I have two components:
App.vue
Sidekick.vue
In my App.vue component, I have a property that I would like to access from Sidekick.vue
App.vue
<template>
<div id="app">
<p>{{ myData }}</p>
<div class="sidebar">
<router-view/> // our sidekick component is shown here
</div>
</div>
</template>
<script>
export default {
name: 'App',
data () {
return {
myData: 'is just this string'
}
}
}
</script>
Sidekick.vue
<template>
<div class="sidekick">
{{ myData }}
</div>
</template>
<script>
export default {
name: 'Sidekick'
}
</script>
I would like access to myData (which is declared in App.vue) from Sidekick.vue
I have tried importing App.vue from within Sidekick.vue by doing something like:
Sidekick.vue (incorrect attempt)
<script>
import App from '#/App'
export default {
name: 'Sidekick',
data () {
return {
myData: App.myData
}
}
}
</script>
I have read about props - but have only seen references to child / parent components. In my case, Sidekick.vue is shown in a div inside App.vue (not sure if this makes it a "child"). Do I need to give access of myData to <router-view/> somehow?
UPDATE: (to show relationship between App.vue and Sidekick.vue
index.js (router file)
import Vue from 'vue'
import Router from 'vue-router'
import Sidekick from '#/components/Sidekick',
import FakeComponent from '#/components/FakeComponent'
Vue.use(Router)
const router = new Router({
routes: [
{
path: '/',
redirect: '/fakecomponent'
},
{
path: '/sidekick',
name: 'Sidekick',
component: Sidekick
},
{
path: '/fakecomponent',
name: 'FakeComponent',
component: FakeComponent
}
]
})
export default router
Sidekick.vue gets rendered when we hit /sidekick
Just keep in mind, the rule of thumb is using props to pass data in a one-way flow
props down, events up.
https://v2.vuejs.org/v2/guide/components.html#Composing-Components
Quick solution:
Global event bus to post messages between your <App/> and <Sidekick/> components.
https://v2.vuejs.org/v2/guide/components.html#Non-Parent-Child-Communication
Long term solution:
Use a state management library like vuex to better encapsulates data in one place (a global store) and subscribe it from your components tree using import { mapState, mapMutations } from 'vuex'
When you have parent-child communication, the best and recommended
option is to use props and events. Read more in Vue docs
When want to have shared state between many components the best and
recommended way is to use Vuex.
If you want to use simple data sharing you can use Vue observable.
Simple example: Say that you have a game and you want the errors to be accessible by many components. (components can access it and manipulate it).
errors.js
import Vue from "vue";
export const errors = Vue.observable({ count: 0 });
Component1.vue
import { errors } from 'path-of-errors.js'
export default {
computed: {
errors () {
get () { return errors.count },
set (val) { errors.count = val }
}
}
}
In Component1 the errors.count is reactive. So if as a template you have:
<template>
<div>
Errors: {{ errors }}
<button #click="errors++">Increase</button>
</div>
</template>
While you click the Increase button, you will see the errors increasing.
As you might expect, when you import the errors.js in another component, then both components can participate on manipulating the errors.count.
Note: Even though you might use the Vue.observable API for simple data sharing you should be aware that this is a very powerful API. For example read Using Vue Observables as a State Store
App.vue:
<router-view pass_data='myData'/>
Sidekick.vue:
export default {
name: "Sidekick",
props: ["pass_data"],
created() {
alert("pass_data: "+this.pass_data)
}
}
If App.js(Parent) and Sidekick(Child)
App.js
in Template
In script
import Sidekick from './Sidekick.vue:
Sidekick.vue
props: ['myData']
now you can access myData anywhere in sidekick.
In template myData and
in scripts this.myData
Getting an error that project is undefined when trying to render out some text using {{project.projectSummary}} in my ProjectContainer component. I'm guessing when the component is initialized project is undefined because it shows up in VueTools fine on my component.
So next, I try to set v-if="resource.project" on the parent component
<template v-if="resource.project">
<div class="resourceContainer">
<resource-card :resource="resource" :showResourceBtn="showResourceBtn"></resource-card>
<project-container :project="resource.project"></project-container>
</div>
</template>
<script>
import { firebaseAuth, database } from '../../database/database'
import Vue from 'vue'
import VueFire from 'vuefire'
import ResourceCard from '../ResourceCard/ResourceCard'
import ProjectContainer from './Project'
Vue.use(VueFire);
export default {
name: 'Resource',
components: {
ResourceCard,
ProjectContainer
},
data () {
return {
showResourceBtn: true
}
},
computed: {
fbUser () {
return firebaseAuth.currentUser
}
},
created () {
// Load resource
this.$bindAsObject('resource', database.ref('/resources/' + this.$route.params.resourceKey));
}
}
</script>
But this isn't working either. Gives me a warning in the console that Invalid prop: type check failed for prop "project". Expected Object, got Undefined.
Any thoughts? Thanks