I want to create a simple Banner with vue-banner-better, I installed the module and configure scoped banner in a vue file. When i run it, i get the next warn and doesn't appear the desired banner. thanks in advance.
this is the warn:
[Vue warn]: Component is missing template or render function.
at <Banner autoplay="" indicator= {clickable: true, type: 'pill', showCounter: false}clickable: trueshowCounter: falsetype: "pill"[[Prototype]]: Objectconstructor: ƒ Object()hasOwnProperty: ƒ hasOwnProperty()isPrototypeOf: ƒ isPrototypeOf()propertyIsEnumerable: ƒ propertyIsEnumerable()toLocaleString: ƒ toLocaleString()toString: ƒ toString()valueOf: ƒ valueOf()__defineGetter__: ƒ __defineGetter__()__defineSetter__: ƒ __defineSetter__()__lookupGetter__: ƒ __lookupGetter__()__lookupSetter__: ƒ __lookupSetter__()__proto__: (...)get __proto__: ƒ __proto__()set __proto__: ƒ __proto__() show-navigation="" ... >
at <Hero>
at <Home onVnodeUnmounted=fn<onVnodeUnmounted> ref=Ref< undefined > >
at <RouterView>
at <App>
This is my Hero.vue file:
<template>
<div class="text-center hero">
<img class="mb-3 app-logo" src="/logo.png" alt="Vue.js logo" width="120" />
<div class="app">
<Banner
autoplay
:indicator="indicator"
show-navigation
disable-on-hover
mode="loop"
>
<Slide>
<img
src="https://images.pexels.com/photos/289323/pexels-photo-289323.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500"
/>
</Slide>
<Slide>
<img
src="https://images.pexels.com/photos/70741/cereals-field-ripe-poppy-70741.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500"
/>
</Slide>
<Slide>
<img
src="https://images.pexels.com/photos/54323/rose-composites-flowers-spring-54323.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500"
/>
</Slide>
</Banner>
</div>
</div>
</template>
<script>
import Banner from "vue-banner-better";
import Slide from "vue-banner-better";
export default {
name: "Hero",
data: () => {
return {
indicator: {
clickable: true,
type: "pill",
showCounter: false,
},
};
},
components: {
Banner,
Slide,
},
};
</script>
My main.ts has commented the reference because I tested it but doesn't work too.
import App from "./App.vue";
import { createApp } from "vue";
import { createRouter } from "./router";
import { createAuth0 } from "#auth0/auth0-vue";
import hljs from "vue3-highlightjs";
import "highlight.js/styles/github.css";
import { library } from "#fortawesome/fontawesome-svg-core";
import { faLink, faUser, faPowerOff } from "#fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "#fortawesome/vue-fontawesome";
import { domain, clientId as client_id } from "../auth_config.json";
//import { Banner } from "vue-banner-better";
const app = createApp(App);
library.add(faLink, faUser, faPowerOff);
app
//.use(Banner)
.use(hljs)
.use(createRouter(app))
.use(
createAuth0({
domain,
client_id,
redirect_uri: window.location.origin,
})
)
.component("font-awesome-icon", FontAwesomeIcon)
.mount("#app");
Related
I'm trying to import SVG icons for each item in a v-for loop, with the filename changing depending on the item's id. The icons are loading, but I get the following error for each icon imported.
Is there a better way to approach this?
Uncaught (in promise) TypeError: Failed to resolve module specifier '~/assets/img/flags/ar.svg'
<template>
<NavigationItem v-for="item in topCountries">
<template #icon>
<component :is="getIcon(item.id)" />
</template>
<NavigationItem />
</template>
<script setup>
const getIcon = (id) => defineAsyncComponent(() =>
import(`~/assets/img/flags/${id}.svg`));
</script>
You can have a look at https://nuxt.com/modules/nuxt-svgo module.
This module allows to import SVG.
npm i --save nuxt-svgo
Add it as a module dependency in your nuxt.config file
// nuxt.config.ts
import { defineNuxtConfig } from 'nuxt'
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
modules: ['nuxt-svgo']
})
Import SVG icons as follow:
<script setup lang="ts">
const getIcon = (id: string) => defineAsyncComponent(() => import(`#/assets/svg/${id}.svg`));
</script>
<template>
<div v-for="item in ['icon1', 'icon2']">
<component :is="getIcon(item)" />
</div>
</template>
Note that if you use Typescript, you will have to create a custom.d.ts file to fix import error
// custom.d.ts
declare module '*.svg' {
import type { DefineComponent } from 'vue'
const component: DefineComponent
export default component
}
calls each icon from the data. uses font awesome icons. you can also add svgs between the i tags
<template>
<ul>
<!-- list rendering -->
<li v-for="item in items">
<span class="icon">
<i :class="[faClass(item.icon)]"
aria-hidden="true"></i>
</span>
</li>
</ul>
</template>
<script>
export default {
name: "navbarMobile",
data() {
return {
//listItems
items: [
{
icon: 'home',
},
{
icon: 'wrench',
},
{
icon: 'project-diagram',
},
{
icon: 'cogs',
},
{
icon: 'phone',
}
]
}
},
methods: {
faClass(icon) {
return `fa fa-${icon}`;
}
}
}
</script>
Us the component name instead of the component path. Also, don't forget to import SVG components and add ?inline at the end of the name.
<template>
<NavigationItem v-for="item in topCountries">
<template #icon>
<component :is="item.icon" />
</template>
<NavigationItem />
</template>
<script setup>
import Eye from '~/assets/img/flags/Eye.svg?inline';
import Balls from '~/assets/img/flags/Balls.svg?inline';
const topCountries = [
{ icon: 'Eye' },
{ icon: 'Balls' }
]
</script>
I am currently working on a project using Vue 3, Quasar and Firebase. I have a Custom Dialog component that I'm using through Quasar's Dialog API:
<template>
<q-dialog ref="dialogRef" #hide="onDialogHide" v-on:keyup.enter="onOKClick">
<q-card class="q-dialog-plugin custom-dialog">
<q-card-section class="text-center">
<p class="text-white">{{ this.message }}</p>
</q-card-section>
<q-card-actions align="center">
<q-btn
class="q-mb-md"
color="secondary"
label="OK"
#click="onOKClick"
/>
<q-btn
class="q-mb-md"
color="negative"
label="Cancelar"
#click="onDialogCancel"
/>
</q-card-actions>
</q-card>
</q-dialog>
</template>
<script setup>
import { useDialogPluginComponent } from "quasar";
import { useRouter } from "vue-router";
const props = defineProps({
title: {
type: String,
default: "",
},
message: {
type: String,
default: "",
},
});
defineEmits([...useDialogPluginComponent.emits]);
const router = useRouter;
const { dialogRef, onDialogHide, onDialogOK, onDialogCancel } =
useDialogPluginComponent();
function onOKClick() {
onDialogOK();
router.push({
name: "home",
});
}
</script>
What I am trying to achieve is for the dialog to close and the user to be redirected to the Home page once he clicks OK. Console is throwing "Uncaught TypeError: router.push is not a function"
Anyone who knows their way around Quasar's Dialog API who could point me in the right direction would be much appreciated.
Try to execute useRouter function:
const router = useRouter();
Hi I have installed Vuejs 3 and I am trying to embed a vimeo video with this library: import vueVimeoPlayer from 'vue-vimeo-player'.
I imported this in the main.js like this:
import vueVimeoPlayer from 'vue-vimeo-player'
Vue.use(vueVimeoPlayer)
My view is this one:
<template>
<div id="app">
<vueVimeoPlayer
ref="player"
:video-url="url"
:player-height="500"
:player-width="500"
:autoplay="true"
/>
<div #click="updateUrl()">click me</div>
<div #click="errorUrl()">error pls</div>
</div>
</template>
<script>
import { vueVimeoPlayer } from 'vue-vimeo-player';
export default {
name: 'App',
components: {
vueVimeoPlayer,
},
data () {
return {
url: "https://vimeo.com/605358147/b5c4f01703",
};
},
methods: {
updateUrl() {
this.url = "https://vimeo.com/604413787/dd09a5711";
},
errorUrl() {
this.url = "https://vimeo.com/605266340/a7aa996ffc";
},
},
};
</script>
I receive this huge error:
TypeError: Object(...) is not a function
at Proxy.render (index.es.js?558f:174:1)
at VueComponent.Vue._render (vue.runtime.esm.js?2b0e:3569:1)
at VueComponent.updateComponent (vue.runtime.esm.js?2b0e:4081:1)
at Watcher.get (vue.runtime.esm.js?2b0e:4495:1)
at new Watcher (vue.runtime.esm.js?2b0e:4484:1)
etc
etc
So I wonder what am I doing wrong? Because I saw it working check this url:
https://codesandbox.io/s/m4z5v63jqy
Thanks
Vue.use is not directly available anymore in Vue3, you would have to use createApp().use
That's why you're seeing error. Try like this
Make sure you've install correct version of vue-vimeo-player to support Vue3
import { createApp } from 'vue'
import App from './App.vue'
import vueVimeoPlayer from 'vue-vimeo-player'
const app = createApp(App)
app.use(vueVimeoPlayer).mount("#app");
I have this code in file app.vue :
<template>
<div id="app">
<button v-on:click="component = 'login'">aa</button>
<component v-bind:is="component"></component>
</div>
</template>
<script>
import acceuil from './components/acceuil.vue'
import login from './components/login.vue'
export default {
name: 'app',
components: {
acceuil,
login
},
data(){
return {
component: 'acceuil'
}
}
}
</script>
How can I toggle between acceuil/login in component from a different vue file ?
You need to pass the imported dependency (the object or the name of the component as a string) to v-bind:is. You can do this by returning it in a computed function and pass it to a computed property, which you then can use in the template.
<template>
<div id="app">
<button v-on:click="isLogin = true">Show Login</button>
<component v-bind:is="currentComponent"></component>
</div>
</template>
<script>
import acceuil from './components/acceuil.vue';
import login from './components/login.vue';
export default {
name: 'app',
data () {
return {
isLogin: false
};
},
computed: {
currentComponent () {
return this.isLogin ? login : acceuil;
}
},
};
</script>
See also the documentation of dynamic components in the official docs.
Error: undefined is not a constructor (evaluating 'vm.$el.querySelector('h3')')
Follow my code and full code here
// main.js
import Vue from 'vue'
import App from './App'
import router from './router'
import store from './store'
import 'babel-polyfill'
require('es6-promise').polyfill()
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
store,
template: '<App/>',
components: { App }
})
// Home.vue
<template>
<div>
<h3 class="ui center aligned header">
An simple contact list
</h3>
<div class="ui fluid input">
<input type="text" placeholder="Search..." v-model="searchTerm" autofocus autocomplete="false">
</div>
<div class="ui inverted dimmer" :class="{ 'active': isFetchingContacts }">
<div class="ui text loader">Loading contacts</div>
</div>
<transition-group name="custom" mode="out-in"
enter-active-class="animated flipInX"
class="ui middle aligned selection celled relaxed list">
<component class="item"
v-for="contact in contacts" :key="contact.id"
:is="openedId === contact.id ? 'contact-card' : 'contact-item'" :contact=contact>
</component>
</transition-group>
<div class="ui warning message" v-if="contacts.length <= 0">
<div class="header">
No contacts found!
</div>
</div>
</div>
</template>
<script>
import { mapActions, mapGetters, mapState } from 'vuex'
import _ from 'lodash'
import contactItem from './ContactItem'
import contactCard from './ContactCard'
export default {
name: 'home',
data () {
return { searchTerm: '' }
},
created () { this.fetchContacts() },
watch: {
'$route': 'fetchContacts',
'searchTerm': 'search'
},
computed: {
...mapGetters([ 'contacts' ]),
...mapState({
isFetchingContacts: state => state.isFetchingContacts,
openedId: state => state.openedId
})
},
methods: {
...mapActions([ 'fetchContacts' ]),
search: _.debounce(function () {
this.fetchContacts(this.searchTerm)
}, 900)
},
components: { contactItem, contactCard }
}
</script>
// Home.spec.js
import Vue from 'vue'
import Home from '#/components/Home'
describe('Home.vue', () => {
it('should render title', () => {
const vm = new Vue(Home).$mount()
expect(vm.$el.querySelector('h3'))
.toBe('An simple contact list')
})
})
Console error
Home.vue
✗ should render title
undefined is not a constructor (evaluating 'vm.$el.querySelector('h3')')
webpack:///test/unit/specs/Home.spec.js:7:32 <- index.js:30622:32
ERROR LOG: '[Vue warn]: Error in created hook:
(found in <Root>)'
ERROR LOG: TypeError{stack: 'mappedAction#http://localhost:9876/base/index.js?fcbe9e188a70bce472b9278dcad3e9e00645b644:10798:25
boundFn#http://localhost:9876/base/index.js?fcbe9e188a70bce472b9278dcad3e9e00645b644:690:16
created#http://localhost:9876/base/index.js?fcbe9e188a70bce472b9278dcad3e9e00645b644:31008:23
callHook#http://localhost:9876/base/index.js?fcbe9e188a70bce472b9278dcad3e9e00645b644:2786:25
_init#http://localhost:9876/base/index.js?fcbe9e188a70bce472b9278dcad3e9e00645b644:4209:13
VueComponent#http://localhost:9876/base/index.js?fcbe9e188a70bce472b9278dcad3e9e00645b644:4373:17
http://localhost:9876/base/index.js?fcbe9e188a70bce472b9278dcad3e9e00645b644:30627:29
callFnAsync#http://localhost:9876/absolute/Users/ridermansb/Projects/frontend-recruitment-orion/node_modules/mocha/mocha.js?0491afff0b566ea45cd04c9164a355dba705689e:4470:25
run#http://localhost:9876/absolute/Users/ridermansb/Projects/frontend-recruitment-orion/node_modules/mocha/mocha.js?0491afff0b566ea45cd04c9164a355dba705689e:4420:18
runTest#http://localhost:9876/absolute/Users/ridermansb/Projects/frontend-recruitment-orion/node_modules/mocha/mocha.js?0491afff0b566ea45cd04c9164a355dba705689e:4936:13
http://localhost:9876/absolute/Users/ridermansb/Projects/frontend-recruitment-orion/node_modules/mocha/mocha.js?0491afff0b566ea45cd04c9164a355dba705689e:5042:19
next#http://localhost:9876/absolute/Users/ridermansb/Projects/frontend-recruitment-orion/node_modules/mocha/mocha.js?0491afff0b566ea45cd04c9164a355dba705689e:4853:16
http://localhost:9876/absolute/Users/ridermansb/Projects/frontend-recruitment-orion/node_modules/mocha/mocha.js?0491afff0b566ea45cd04c9164a355dba705689e:4863:11
next#http://localhost:9876/absolute/Users/ridermansb/Projects/frontend-recruitment-orion/node_modules/mocha/mocha.js?0491afff0b566ea45cd04c9164a355dba705689e:4787:16
http://localhost:9876/absolute/Users/ridermansb/Projects/frontend-recruitment-orion/node_modules/mocha/mocha.js?0491afff0b566ea45cd04c9164a355dba705689e:4831:9
timeslice#http://localhost:9876/absolute/Users/ridermansb/Projects/frontend-recruitment-orion/node_modules/mocha/mocha.js?0491afff0b566ea45cd04c9164a355dba705689e:82:27', line: 10798, sourceURL: 'http://localhost:9876/base/index.js?fcbe9e188a70bce472b9278dcad3e9e00645b644'}
ERROR LOG: '[Vue warn]: Error in render function:
you need to include a store, in order to get your HTML rendered.
import Vuex from 'vuex'
const store = new Vuex.Store()
const Component = Vue.extend(Home)
const vm = new Component({store}).$mount()