Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Failed to mount component: template or render function not defined. (found in root instance) #713

Closed
lzxb opened this issue Oct 2, 2016 · 39 comments

Comments

@lzxb
Copy link

lzxb commented Oct 2, 2016

I write it in this case, but it is wrong.
http://router.vuejs.org/en/essentials/getting-started.html

"vue": "^2.0.1",
"vue-router": "^2.0.0",
"vuex": "^2.0.0"
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<div id="app">
  <h1>Hello App!</h1>
  <p>
    <!-- use router-link component for navigation. -->
    <!-- specify the link by passing the `to` prop. -->
    <!-- <router-link> will be rendered as an `<a>` tag by default -->
    <router-link to="/foo">Go to Foo</router-link>
    <router-link to="/bar">Go to Bar</router-link>
  </p>
  <!-- route outlet -->
  <!-- component matched by the route will render here -->
  <router-view></router-view>
</div>
</body>
</html>
import Vue from 'vue'
import VueRouter from 'vue-router'

Vue.use(VueRouter)
// 0. If using a module system, call Vue.use(VueRouter)

// 1. Define route components.
// These can be imported from other files
const Foo = { template: '<div>foo</div>' }
const Bar = { template: '<div>bar</div>' }

// 2. Define some routes
// Each route should map to a component. The "component" can
// either be an actual component constructor created via
// Vue.extend(), or just a component options object.
// We'll talk about nested routes later.
const routes = [
  { path: '/foo', component: Foo },
  { path: '/bar', component: Bar }
]

// 3. Create the router instance and pass the `routes` option
// You can pass in additional options here, but let's
// keep it simple for now.
const router = new VueRouter({
  routes // short for routes: routes
})

// 4. Create and mount the root instance.
// Make sure to inject the router with the router option to make the
// whole app router-aware.
const app = new Vue({
  router
}).$mount('#app')

// Now the app has started!
open url http://localhost:3000/admin/#/bar
@fnlctrl
Copy link
Member

fnlctrl commented Oct 2, 2016

Hi, thanks for filling this issue.
If you import Vue from 'vue'; you get the runtime only build that cannot compile templates (either in-dom templates or template option).
In this case you need the standalone build, here is a helpful section explaining this:
https://vuejs.org/guide/installation.html#Standalone-vs-Runtime-only-Build

@fnlctrl fnlctrl closed this as completed Oct 2, 2016
@lzxb
Copy link
Author

lzxb commented Oct 2, 2016

thank you

@vanpipy
Copy link

vanpipy commented Nov 9, 2016

Hello :D @fnlctrl @lzxb.

I follow @fnlctrl advice to fix the vue template compiler.

But another problem come out.

All the get start vue code copy from get-start-page

The different is webpack config.
Here is below:

const rucksack = require('rucksack-css');
const Webpack = require('webpack');
const path = require('path');

function makeWebpackConfig() {
    return {
        context: path.join(__dirname, './client'),
        entry: {
            js: './index.js',
            html: './index.html',
            vendor: [
                'vue',
                'vue-router',
            ]
        },
        output: {
            path: path.resolve(__dirname, 'dist'),
            publicPath: '/',
            filename: 'bundle.js'
        },
        module: {
            loaders: [
                {
                    test: /\.html$/,
                    loader: 'file?name=[name].[ext]'
                },
                {
                    test: /\.(js|jsx)$/,
                    exclude: /node_modules/,
                    loader: 'babel-loader',
                    query: {
                        presets: ['es2015']
                    }
                },
                {
                    test: /\.css$/,
                    include: /client/,
                    loaders: [
                        'style-loader',
                        'css-loader',
                        'postcss-loader'
                    ]
                }
            ]
        },
        resolve: {
            extensions: ['', '.js', '.jsx'],
            alias: {
                'vue$': 'vue/dist/vue.js'
            }
        },
        postcss: [
            rucksack({
                autoprefixer: true
            })
        ],
        plugins: [
            new Webpack.optimize.CommonsChunkPlugin('vendor', 'vendor.bundle.js'),
            new Webpack.DefinePlugin({
                'process.env': {
                    NODE_ENV: JSON.stringify(process.env.NODE_ENV || 'development')
                }
            })
        ],
        devServer: {
            contentBase: './client',
            hot: true
        }
    };
}

And after the new Vue({ router }).$mount the div#app inner router-view display nothing, I try to compare the get start live example with mine but nothing found.

Can anyone give me some advice for this?

That's mine fault, it's need more { routes } in it. It's fixed already :D. Thanks.

@ModleIory
Copy link

It works!!! good!

@oleynikd
Copy link

oleynikd commented Dec 2, 2016

Should I also use standalone build if I'm using Single File Components?

@fnlctrl
Copy link
Member

fnlctrl commented Dec 3, 2016

@oleynikd No, single file components will have their templates compiled at build time. As long as you don't use the template: ... option or in-dom templates, you can use the lighter runtime-only build.

@xqyww123
Copy link

xqyww123 commented Dec 4, 2016

@fnlctrl so here is the problem. In main.js, which isn't a single file component so that can not be compiled, how can I declare the top component app under the body tag, without template: ... option in main.js or in-dom template in index.html

@fnlctrl
Copy link
Member

fnlctrl commented Dec 4, 2016

@xqyww123 If you're using the runtime-only build, anything put inside html cannot be compiled. Therefore, you'll need the mount method

A simple example:

// your entry js
import App from './App.vue';
new Vue(App).mount('#app');
<body>
  <div id="app"></div>
</body>

If you need to add a router/store instance to the root instance, it'll have to be slightly modified:

// your entry js
import App from './App.vue';
import store from './store';
import router from './router';

new Vue({
   ...App // ES7 Object rest spread operator (or Object.assign)
   router,
   store
}).mount('#app');

The above is the javascript approach.
However, if you want to avoid the rest spread operator / Object.assign, another approach would be using vue's render functions:

// your entry js
import App from './App.vue';
import store from './store';
import router from './router';

new Vue({
   router,
   store,
   render: h => h(App)
}).mount('#app');

@AnsonHwang86
Copy link

@fnlctrl Therefore, you'll need the mount method. You mean instance method $mount can compiled anything inside html? I make a demo and find this wrong. Runtime-only build with method $mount cann't compiled anything inside html.
My code:

// index.html

<div id="app">
  {{ message }}
</div>

// main.js

import App from './App.vue'
new Vue({
  data: {
    message: 'hello, kitty!'
  }
}).$mount('#app') // Noted, it's "$mount" instead "mount", $mount is vue instance method

// result vue.runtime.common.js:519 [Vue warn]: Failed to mount component: template or render function not defined.
Your demo is very nice, thanks.

@fnlctrl
Copy link
Member

fnlctrl commented Dec 14, 2016

You mean instance method $mount can compiled anything inside html?

No. That's not what I said. Let me rephrase that: since the runtime-only build cannot compile anything (in-dom, template string), you can't put templates inside html, so you either use $mount or the el option to mount the component to the target.

@ubershmekel
Copy link

ubershmekel commented Dec 17, 2016

For anyone still finding this thread, this is how I ended up getting past this error for my browserify and typescript setup:

import * as Vue from 'vue/dist/vue.common.js';

var app = new Vue({
    el: '#app',
    data: {
        message: 'Hello Vue!'
    }
});

@seanfisher
Copy link

@ubershmekel Not to take us too off-topic, but how do you get typings with that setup?

@zcdziura
Copy link

zcdziura commented Feb 7, 2017

If you're using Webpack 2 to build your application, here is what I did to resolve the problem:

From webpack.config.js:

module.exports = {
    ...
    resolve: {
        extensions: ['.js'],
        alias: {
            'vue': 'vue/dist/vue.common.js'
        }
    },
    ...
}

From there, you are able to install Vue as you would expect using ES6 syntax:

import Vue from 'vue';

@aiqin-bao
Copy link

有中文的解答吗? 看得不是很明白 ??

@wspl
Copy link

wspl commented Nov 1, 2017

import Vue from 'vue'
import Router from 'vue-router'

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/',
      component: require('../pages/Main.vue').default
    }
  ]
})

if you use require in router, you need add a .default after require expression.

@jacky-jiang
Copy link

as @wspl commented, it would work well.

another option is 'import' as following:

import Vue from 'vue'
import Router from 'vue-router'

import Main from '../pages/Main.vue'

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/',
      component: Main
    }
  ]
})

@0x1af2aec8f957
Copy link

0x1af2aec8f957 commented Nov 7, 2017

删除你的module文件夹,重新更新安装所有依赖(使用npm进行安装)。请不要通过cnpm进行安装依赖,这会导致有些包找不到地址(无法正常找到)。推荐使用npm,更换镜像地址即可!

@sxei
Copy link

sxei commented Dec 6, 2017

一群中国人在这里用英语交流,也是醉了哈

@toshcn
Copy link

toshcn commented Dec 19, 2017

@wspl thanks
正解
the right answers
add the require .default
routes: [
{
path: '/',
component: require('../pages/Main.vue').default
}
]

@SageSanyue
Copy link

SageSanyue commented Jul 11, 2018

Smilar problem, when I write:

let routes = [{
path: '/',
component: require('./components/member.vue')
}]
it failed:[Vue warn]: Failed to mount component: template or render function not defined.
add ".default", it works!

let routes = [{
path: '/',
component: require('./components/member.vue').default
}]
PS:"vue": "^2.5.2","vue-router": "^3.0.1""vue-loader": "^13.3.0",

@0x1af2aec8f957
Copy link

0x1af2aec8f957 commented Jul 11, 2018

@SageSanyue 你可以尝试使用webpack的动态导入语法:

component: () => import ('./HelloWorld')

const routes = [{
path: '/',
component: () => import('./components/member.vue')
}]

上述代码在webpack^3.0中正常工作。

@Deg5112
Copy link

Deg5112 commented Jul 30, 2018

thank you @notescript

@molerat619
Copy link

I still have this issue. This is my app.js:

image

components/index.js:

image

I get this issue only when I enable esModul in webpack like so:
mix.config.vue.esModule = true;

How can I fix this? The routes should be fine, I use import.

@0x1af2aec8f957
Copy link

@molerat619 你可以换一种提问题的方式?

期望 -> 现状 -> 结果

---代码---

---问题描述---

你应该尽可能详细的描述你遇到的问题。

@PayteR
Copy link

PayteR commented Sep 18, 2018

i ran into same issue, but my solution was this:

https://stackoverflow.com/questions/49138501/vue-warn-failed-to-mount-component-template-or-render-function-not-defined-i

i think it's same as in @molerat619 example

@askanhan
Copy link

In my case, I imported my component (in router) as:

import bsw from 'common-mod/src/components/webcommon/webcommon'

It is simply solved if I changed it to

import bsw from 'common-mod/src/components/webcommon/webcommon.vue'

@javierojeda94
Copy link

@askanhan solution worked perfect for me! Still I don't know why that caused the problem, the software I'm working on has been online for about 3 years and we are using Vue since 1 year ago but it worked fine :(

@isofttechn
Copy link

I solve mine by adding default after closing curly bracket. '.default'. e.g.
const routes = [
{ path: '/foo', component: Foo }.default,
{ path: '/bar', component: Bar }.default
]

@askanhan
Copy link

askanhan commented Jan 3, 2019

@askanhan solution worked perfect for me! Still I don't know why that caused the problem, the software I'm working on has been online for about 3 years and we are using Vue since 1 year ago but it worked fine :(

Couldn't find any reason but I believe it has something to do with the updates of webpack or so

@benmo1602
Copy link

benmo1602 commented Feb 26, 2019

我遇到这个问题了, 打开router .js 然后 ctrl + s 就好了 , 真是诡异
image

@skinnn
Copy link

skinnn commented Jul 1, 2019

@wspl Thanks, thanks really all I needed to fix the error:

[Vue warn]: Failed to mount component: template or render function not defined.

@egulhan
Copy link

egulhan commented Oct 24, 2019

@skinnn, maybe you must be missing default keyword when you use like that: require('./components/Example.vue').default

@codegeek1001
Copy link

I was getting the same error but adding .default helped as well. Here is my app.js in case it helps anyone else:

import Vue from "vue";
Vue.component("my-component", require("./components/my-component.vue").default);

new Vue({
  el: "#app"
});

@Kasre96
Copy link

Kasre96 commented Jan 28, 2020

Adding .default works for me too.

In case yours doesn't change after adding .default try recompiling your code (.eg. npm run dev). Worked for me.

@salahfarzin
Copy link

salahfarzin commented Mar 3, 2020

Adding .default at the end of component line and worked
import VueRouter from "vue-router";
let routes = [
{
path: '/',
component: require('./components/Home').default
},
{
path: '/coupon',
component: require('./components/Coupon').default
}
];
export default new VueRouter({
routes
});

@chinela
Copy link

chinela commented Apr 25, 2020

You can do
import Home from './components/Home;

let routes = [ { path: '/', component: Home }, ]

@NickCashFlow
Copy link

I got this error because I had empty style section. Fill the style section or remove it and the problem will solved.

@bhojkamal
Copy link

I got blank on my web page. On console, I got this error ->

Vue warn]: Failed to mount app: mount target selector "#app" returned null.

I have used vue 3 with laravel 8 and used laravel-mix.

I've added the bootstrap 5 but it is working on my laravel blade template but other vue component is not working.

On blade

<body class="text-center">
  <div>
    <h2>Hello laravel 8</h2> <!-- this is showing on output in webpage with text center that come from app.js -->
  </div>
  <div id="#app"></div>
  <script src="{{ mix('js/app.js') }}"></script>
</body>

On app.js

import { createApp } from 'vue'
import router from './router'
import App from './App.vue'
import 'bootstrap/dist/css/bootstrap.min.css';
import 'bootstrap/dist/js/bootstrap.min';
const app = createApp(App)
app.use(router)
app.mount('#app')

on App.vue

<template>
  <div class="text-center">
    <h1 class="text-bold"> Namaste from vue component </h1> <!-- this is not showing on output in webpage -->
    </div>
  <router-view></router-view>
</template>
<script>
export default {
  name: 'App'
}
</script>

@javierojeda94
Copy link

@bhojkamal so by reading the error you should be able to tell what's wrong.

Replace <div id="#app"></div> with <div id="app"></div> and that should be it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests