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()
Related
When I want to practice a navigation bar with Vue, encountering a mistake about the invalid route component. In this div cannot display anything. As to the hint of the console, I can find no way out.
the App.vue, hereI only show the Home navigation
<template>
<div id="app">
<tab-bar>
<tab-bar-item class="tab-bar-item" path='/home' activeColor="red">
<img slot="item-icon" src="./assets/img/tabbar/home.svg" alt="">
<img slot="item-icon-active" src="./assets/img/tabbar/Home1.svg" alt="">
<div slot="item-text">Home</div>
</tab-bar>
<router-view></router-view>
</div>
</template>
<script>
import TabBar from './components/tabbar/TabBar'
import TabBarItem from './components/tabbar/TabBarItem'
export default {
name: 'App',
components: {
TabBar,
TabBarItem
}
}
</script>
the two vue components:
TabBarItem.vue
<template>
<div class="tab-bar-item" #click="itemClick">
<div v-if="!isActive"><slot name="item-icon"></slot></div>
<div v-else><slot name="item-icon-active"></slot></div>
<div :style="activeStyle" :class="{active: isActive}"><slot name="item-text"></slot></div>
</div>
</template>
<script>
export default {
name: 'TabBarItem',
props: {
path: String,
activeColor: {
type: String,
default: 'red'
}
},
data() {
return {
isActive: true
}
},
methods: {
itemCilck() {
this.$router.replace();
console.log('itemclick')
}
}
}
</script>
TarBar.vue
<template>
<div id="tab-bar">
<slot></slot>
</div>
</template>
<script>
export default {
name: 'TabBar'
}
</script>
index.js
import { createRouter, createWebHistory } from 'vue-router'
const Home = () => import('../views/home/Home')
const Categroy = () => import('../views/category/Category')
const Cart = () => import('../views/cart/Cart')
const Profile = () => import('../views/profile/Profile')
// import Home from '../views/Home.vue'
const routes = [
{
path: '/home',
component: Home
},
]
const router = createRouter({
history: createWebHistory(),
routes
})
export default router
the error
vue-router.esm-bundler.js:3266 Error: Invalid route component
at extractComponentsGuards (vue-router.esm-bundler.js:1994)
at eval (vue-router.esm-bundler.js:3107)
the console picture
According to docs they do not omit file types in dynamic imports, try Home.vue instead of just Home:
const Home = () => import('../views/home/Home.vue')
I am trying to make a simple project which has 2 Vue pages add.vue and read.vue. If we add a message in add.vue(using commit to mutate teh state), results should be displayed in read.vue , using Vuex store. (I am using Nuxt)
store/index.js file=>
export const state = () => ({
messages:[]
})
export const mutations={
addMessage:(state, comment)=> {
state.messages.push(comment)
}
}
add.vue file
<template>
<div class="addContainer">
<b-form #submit.prevent="handleSubmit">
<b-form-group id="input-group-2" label="Comment:" label-for="input-2">
<b-form-input
id="input-2"
v-model="comment"
required
placeholder="Enter Your Comment"
></b-form-input>
</b-form-group>
<b-button type="submit" variant="primary">Submit</b-button>
</b-form>
</div>
</template>
<script>
import Header from '~/components/Header'
import {mapActions} from 'vuex'
import {mapState} from 'vuex'
export default {
data() {
return {
comment:''
}
},
computed:{
...mapState([
'messages'
])
},
methods:{
handleSubmit(){
this.$store.commit('addMessage', this.comment)
console.log('Messages is '+this.messages )
this.comment = ''
}
},
components:{
Header
}
}
</script>
read.vue
<template>
<div>
<p>Read Messages</p>
<ul>
<li v-for="(msg, index) in messages" :key="index">
<b>{{ msg}}</b>
<br>
{{ messages}}
</li>
</ul>
</div>
</template>
<script>
import {mapState} from 'vuex'
export default {
data() {
return {}
},
computed:{
...mapState({
messages:state=>state.messages
})
}
}
</script>
In Vue component , I can see messages array inside state changes after adding a message , but same changes are not reflected in read page.
Add getters to your store:
export const getters= {
getMessages: state => state.messages
}
and then use the getters in your component instead of accessing the state directly:
// read.vue
<script>
import {mapGetters} from 'vuex'
export default {
data() {
return {}
},
computed:{
...mapGetters({
messages: 'getMessages',
})
}
}
</script>
I was given this problematic codebase, where the Vue components aren't loading in.
Vue is mounting, but without any components.
This is a Laravel 5.7 app, using blade templates with some Vue added in.
This is the initial code:
import 'babel-polyfill'
import loadClientScripts from './load-client-scripts'
import 'bootstrap-material-design/js/'
// Vue & axios
import Vue from 'vue'
import { axios } from '../axios-config'
import BootstrapVue from 'bootstrap-vue/dist/bootstrap-vue.esm'
import { createLocales } from '../vue-i18n-config'
import Noty from 'noty'
//Components
import signInForm from './components/SignInForm'
import signUpForm from './components/SignUpForm'
import forgotPassForm from './components/ForgotPassForm'
// import RegisterToAgency from './components/RegisterToAgency'
import SendEmailForm from './components/SendEmailForm'
import AgencyServiceCategories from './components/AgencyServiceCategories'
import DropdownWithCheckboxes from './components/DropdownWithCheckboxes'
import LasiCoalitionAgencies from './components/LasiCoalitionAgencies'
import ServiceProviders from "./components/ServiceProviders";
import ServiceProvider from "./components/ServiceProvider";
import vSelect from "vue-select";
window.axios = axios
Vue.component('v-select', vSelect)
// Bootstrap Vue
Vue.use(BootstrapVue)
export function createApp() {
const i18n = createLocales(window.locale)
// Components
Vue.component('sign-in-form', signInForm)
Vue.component('sign-up-form', signUpForm)
Vue.component('forgot-pass-form', forgotPassForm)
// Vue.component('register-to-agency', RegisterToAgency)
Vue.component('send-email-form', SendEmailForm)
Vue.component('agency-service-categories', AgencyServiceCategories)
Vue.component('dropdown-with-checkboxes', DropdownWithCheckboxes)
Vue.component('lasi-coalition-agencies', LasiCoalitionAgencies)
Vue.component('service-providers', ServiceProviders)
Vue.component('service-provider', ServiceProvider)
new Vue({
i18n
}).$mount('#app')
}
sign in form component for example:
<template>
<div>
<b-form
id="sign-in-form"
#submit="onSubmit"
>
<div class="form-group">
<b-form-input
id="sgi-email"
v-model="model.email"
required
name="email"
:state="state('email')"
type="email"
:placeholder="$t('validation.attributes.email_address')"
/>
<b-form-feedback>{{ feedback('email') }}</b-form-feedback>
</div>
<div class="form-group mb-3">
<b-form-input
id="sgi-password"
v-model="model.password"
required="required"
name="password"
:state="state('password')"
type="password"
:placeholder="$t('validation.attributes.password')"
/>
<b-form-feedback>{{ feedback('password') }}</b-form-feedback>
</div>
<div class="form-group my-0">
<a
class="text-opacity forgot-pass-link"
href="#"
>
{{ $t('labels.user.password_forgot') }}
</a>
</div>
</b-form>
</div>
</template>
<script>
console.log('IM HIT')
export default {
name: 'SignInForm',
data() {
return {
model: {
email: '',
password: ''
},
validation: {}
}
},
mounted() {
this.test()
},
methods: {
test() {
console.log("test")
},
feedback(name) {
if (this.state(name)) {
return this.validation.errors[name][0]
}
},
state(name) {
return this.validation.errors !== undefined &&
this.validation.errors.hasOwnProperty(name)
? 'invalid'
: null
},
onSubmit(evt) {
evt.preventDefault()
window.axios
.post('/login', this.model)
.then(response => {
location.href = '/app'
})
.catch(e => {
if (e.response.status === 422) {
this.validation = e.response.data
return
}
})
}
}
}
</script>
Any ideas help!
in the example sign in form, the console does output the "Im hit" that I had placed to ensure that things were loaded.
Thanks
Are you at any point rendering anything with that Vue instance?
Try passing a component to its render function like so:
// lets pretend you've imported a component from some file App.vue up here and called the component simply 'App'
// e.g.: const App = require('./App.vue') or import App from './App.vue';
Vue.use(BootstrapVue)
export function createApp() {
const i18n = createLocales(window.locale)
// Components
Vue.component('sign-in-form', signInForm)
Vue.component('sign-up-form', signUpForm)
Vue.component('forgot-pass-form', forgotPassForm)
// Vue.component('register-to-agency', RegisterToAgency)
Vue.component('send-email-form', SendEmailForm)
Vue.component('agency-service-categories', AgencyServiceCategories)
Vue.component('dropdown-with-checkboxes', DropdownWithCheckboxes)
Vue.component('lasi-coalition-agencies', LasiCoalitionAgencies)
Vue.component('service-providers', ServiceProviders)
Vue.component('service-provider', ServiceProvider)
new Vue({
i18n,
render: createElement => createElement(App) // needs a render function
}).$mount('#app')
}
I am unsure what I am doing wrong. I get the below error:
error message in console:
[Vue warn]: Failed to mount component: template or render function not defined.
found in
---> <VueChartjs>
<Chatjsvue> at src\components\vueChartjs\Chatjsvue.vue
<App> at src\App.vue
<Root>
index.js
import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '#/components/HelloWorld'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
name: 'HelloWorld',
// component: HelloWorld
component: require('../components/HelloWorld.vue').default
}
]
})
App.vue
<template>
<div id="app" class="container">
<img src="./assets/logo.png" class="logo">
<!-- chartjs -->
<div class="chartjsvue">
<Chatjsvue></Chatjsvue>
</div>
<div class="clear"></div>
<!-- chartjs -->
</div>
</template>
<script>
import Chatjsvue from '#/components/vueChartjs/Chatjsvue'
export default {
name: 'App',
components: {
Chatjsvue
}
}
</script>
Chatjsvue.vue
<template src="../../views/chartjshtml/chartsjs.html"></template>
<script>
import Chartjsvue from '#/assets/javascripts/chartjs'
export default {
components: {
'vue-chartjs': Chartjsvue
}
};
</script>
chartsjs.html
<div class="wrapper">
<vue-chartjs></vue-chartjs>
</div>
chartjs.js
file is rmpty- no code in the file
What is the error referring to and what needs to be done to resolve it?
I think the problem is your chartjs.js is empty. You need to do:
import template from './chartjs.html' // in your questions it's chartsjs.html, please help to correct it
export default {
template: template
}
Your chartjs.js file shouldn't be empty. It should be a Vue component with a template that can be rendered. Any javascript can be written within the script tags themselves.
The components object should only contain the list of vue components you need to use in the current component. And each component must have a template.
Thank you to everyone who contributed in answering. The js file should not be empty. This is the complete code to display all the charts for chartjs
main.js [src/main.js]
import Vue from 'vue'
import App from './App'
import router from './router'
import ChartJsPluginDataLabels from 'chartjs-plugin-datalabels'
Vue.config.productionTip = false
require('./assets/stylesheets/application.css')
require('./assets/javascripts/application.js')
require('./assets/javascripts/chartjs.js')
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
components: {
App,
ChartJsPluginDataLabels
},
template: '<App/>'
})
App.vue [src/App.vue]
<template>
<div id="app" class="container">
<!-- chartjs -->
<div class="chartjsvue tab-content active" id="tab2">
<Chatjsvue></Chatjsvue>
</div>
<div class="clear"></div>
<!-- chartjs -->
</div>
</template>
<script>
import Chatjsvue from '#/components/vueChartjs/Chatjsvue'
export default {
name: 'App',
components: {
Chatjsvue
}
}
</script>
Chatjsvue.vue [src/components/Chatjsvue.vue]
<template src="../../views/chartjshtml/chartsjs.html"></template>
<script>
import Chartjsbarvue from '#/assets/javascripts/chartjsbar'
export default {
components: {
'vue-chartbarjs': Chartjsbarvue
},
mounted(){
console.log('Data is chartjs',this)
},
methods: {},
}
</script>
chartsjs.html [src/views/chartjshtml/chartsjs.html]
<div class="wrapper">
<div class="chart_header">chartjs bar chart</div>
<vue-chartbarjs></vue-chartbarjs>
</div>
chartjsbar.js [src/assets/javascripts/chartjsbar.js]
/*===================================================
File: Chartsjsvue.vue
===================================================*/
import { Bar } from 'vue-chartjs'
export default {
extends: Bar,
data () {
return {
datacollection: {
labels: ['VueJs', 'EmberJs', 'ReactJs', 'AngularJs'],
datasets: [
{
label: '1st Dataset hello',
backgroundColor: 'rgba(52,65,84, 0.3)',
bordercolor: '#344154"',
hoverBackgroundColor: "#344154",
data: [40, 20, 12, 39]
},
{
label: '2nd Dataset',
backgroundColor: 'rgba(130,191,163, 0.5)',
bordercolor: '#82BFA3"',
hoverBackgroundColor: "#82BFA3",
data: [50, 70, 22, 55]
}
]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
datalabels: {
display: false
}
}
}
}
},
mounted () {
this.renderChart(this.datacollection, this.options)
}
}
Why changing mutation do not update page in new language?
main.js : here I implemented vue-i18n with vue:
import Vue from 'vue'
import VueRouter from 'vue-router'
import VueResource from 'vue-resource'
import VueI18n from 'vue-i18n'
import locales from './locales'
import router from './router'
import store from './store'
import App from './App'
Vue.use(VueRouter)
Vue.use(VueResource)
Vue.use(VueI18n, store)
Vue.http.interceptors.push((request, next) => {
console.log('sending request: ', request)
next(response => {
console.log('response: ', response)
})
})
Vue.config.debug = true
Vue.config.lang = 'fa'
Object.keys(locales).forEach(lang => {
Vue.locale(lang, locales[lang])
})
const app = new Vue({
el: '#app',
router,
VueI18n,
store,
render: h => h(App)
})
app.$mount('#app')
App.vue: Then used two buttons to change language:
<template>
<div id="app">
<h2>{{ $t('example', '#store.state.culture') }}</h2>
<p>{{ count }}</p>
<p>
<button #click="increment()">+</button>
<button #click="decrement()">-</button>
</p>
<p>culture: {{ culture }}</p>
<p>
<button #click=' changeCulture("en") '>English</button>
<button #click=' changeCulture("fa") '>پارسی</button>
</p>
<input type="text" v-model="newUserName">
<button #click="handleAddUserButton()">add</button>
<div>
<router-link to="/page1">Go to page1</router-link>
<router-link to="/page2">Go to page2</router-link>
</div>
<transition name="fade" mode="out-in">
<keep-alive>
<router-view></router-view>
</keep-alive>
</transition>
<img src="./assets/logo.png">
<hello></hello>
</div>
</template>
<script>
import { mapGetters, mapActions } from 'vuex'
// import App from './main.js'
import Hello from 'components/Hello'
export default {
name: 'app',
components: {
Hello
},
data () {
return {
newUserName: ''
}
},
computed: {
...mapGetters([
'count',
'culture'
])
},
methods: {
...mapActions([
'increment',
'decrement',
'exampleGetFirebaseData',
'examplePostFirebaseData',
'changeCulture'
]),
handleAddUserButton () {
const user = {
name: this.newUserName
}
this.examplePostFirebaseData(user)
.then(resp => {
// console.log('resp: ', resp)
})
.catch(error => {
console.log('catch error: ', error)
})
},
handleError () {
}
},
beforeMount () {
this.exampleGetFirebaseData()
.then(resp => {
// console.log('resp: ', resp)
})
.catch(error => {
this.handleError(error)
// console.log('catch error: ', error)
})
}
}
</script>
sotre > culture.js: Then using store, getters, actions and mutation to change langauge,
const state = {
locales: ['en', 'fa'],
culture: 'en'
}
const getters = {
culture: state => state.culture
}
const actions = {
async changeCulture ({ commit }, playload) {
commit('CHANGE', playload)
}
}
import App from '../../main.js'
const mutations = {
CHANGE (state, payload) {
if (state.locales.indexOf(payload) !== -1) {
state.culture = payload
} else state.culture = 'en'
console.log(App.i18n)
}
}
export default {
state,
getters,
actions,
mutations
}
I checked using vue development tools in chrome and culture is changed but the problem is that title of {{ $t("example")}} do not change as mutation change.
I know doubt something basic is wrong in my code, may you please help.
Many Thanks in advance.
Becasue this is not a valid expression for i18n
<h2>{{ $t('example', '#store.state.culture') }}</h2>
If you want to translate the text en and fa do this
<h2>{{ $t(culture) }}</h2>
OR
<h2>{{ $t(`namespace:${culture}`) }}</h2>
If you want to use namespace