vuejs / vueify

Browserify transform for single-file Vue components
MIT License
1.17k stars 153 forks source link

I can't use .vue anymore in vuejs 2 when using runtime only build #113

Open dluague opened 8 years ago

dluague commented 8 years ago

When using .vue file for my custom components it throws an vue warning. [Vue warn]: Failed to mount component: template or render function not defined. (found in root instance)

But if I use the standalone build it works fine.

LinusBorg commented 8 years ago

Please provide the relevant code,m including the main.js and package.json

dluague commented 8 years ago
package.json

{
  "private": true,
  "scripts": {
    "prod": "gulp --production",
    "dev": "gulp watch"
  },
  "devDependencies": {
    "babel-plugin-syntax-object-rest-spread": "^6.8.0",
    "babel-plugin-transform-object-rest-spread": "^6.8.0",
    "font-awesome": "^4.6.3",
    "gulp": "^3.9.1",
    "js-cookie": "^2.1.2",
    "laravel-elixir": "^6.0.0-9",
    "laravel-elixir-browserify-official": "^0.1.3",
    "laravel-elixir-vueify-next": "^1.0.2",
    "laravel-elixir-webpack-official": "^1.0.2",
    "lodash": "^4.14.0",
    "particles.js": "^2.0.0",
    "sweetalert": "^1.1.3",
    "vue": "^2.0.0-beta.6",
    "vue-resource": "^0.9.3",
    "vue-router": "^2.0.0-beta.4",
    "vuex": "^2.0.0-rc.3"
  }
}
app.js

import Vue from 'vue'

//import Particles from './components/particles.vue';
import AjaxForm from './components/form.vue';
import Dropdown from './components/dropdown.vue';
import Modal from './components/modal.vue';

// Vuex
import { mapGetters, mapActions } from 'vuex';
import store from './vuex/store.js';

import Vuex from 'vuex';

Vue.use(Vuex);

var app = new Vue({
    el: '#app',
    components: {
        //Particles,
        AjaxForm,
        Dropdown,
        Modal
    },
    store,
    mounted() {

    },     
    data() {
        return {
            birthday: {month: '00', year: '0000', day: '00', date: '0000-00-00'},
        }               
    },
    watch: {
        'birthday': {
            handler(val, oldVal) {
                this.birthday.date = `${this.birthday.year}-${this.birthday.month}-${this.birthday.day}`;
            },
            deep: true
        }
    },
    methods: {        
        showModal(name) {
            this.$refs['login-modal'].open = true;
        },
        ...mapActions(['bodyWasClicked'])
    }
});
modal.vue

<template>
    <transition>
        <div class="modal fade" :class="classes">
            <div 
                class="modal-dialog" 
                role="document" 
                @mouseover="mouseover"
                @mouseleave="mouseleave"
            >
                <div class="modal-content">
                    <div class="modal-header" v-if="title">
                        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                            <span aria-hidden="true">&times;</span>
                        </button>
                        <h4 class="modal-title" v-text="title"></h4>
                    </div>
                    <div class="modal-body">
                        <slot name="body"></slot>
                    </div>
                    <div class="modal-footer" v-if="footer">
                        <slot name="footer"></slot>
                    </div>
                </div>
            </div>
        </div>
    </transition>
</template>

<script>
    import { mapGetters } from 'vuex';

    export default {
        props: {
            title: {
                type: String,
                default: null
            },
            footer: {
                type: Boolean,
                default: false
            },
            static: {
                type: Boolean,
                default: false
            }
        },
        data() {
            return {
                open: false
            }
        },
        computed: {
            classes() {
                return {in: this.open};
            },
            isBodyWasClicked () { 
                return this.$store.getters.isBodyWasClicked;
            }
        },
        mounted() {

        },
        watch: {
            open() {
                if (this.open) {
                    this.show();
                }
            }            
        },
        methods: {
            show() {
                document.body.classList.add('modal-open');
            },
            close() {
                document.body.classList.remove('modal-open');
                this.open = false;
            },            
            mouseover() {
                this.open = true;
            },
            mouseleave() {
                if (this.isBodyWasClicked && ! this.static) { 
                    this.close();
                }
            }
        }
    }
</script>
LinusBorg commented 8 years ago

import Vue from 'vue' loads the runtime-only build by default. This means you can't define any templates in the index.html file.

You have to either

The best way is susually to put all the functionality and template code that you might currently have in the main instance and template in App.vue and have the main instance only do this:

new Vue({
  el: '#app',
  template: `<app></app>`
})
LinusBorg commented 8 years ago

This should be closed now, as it is not a bug. For support questions, we have the forum and gitter.

dluague commented 8 years ago

even if I'm using browserify?

annothernother commented 8 years ago

What I'm getting from this issue is that vueify is not yet compatible with Vue 2.0 short of a workaround with aliasify; the 1/3 size reduction of Vue is not available to browserify-based builds?

This means you can't define any templates in the index.html file.

I'm not doing this and I am still getting the error.

Browserify is not handling the necessary transformations of the template contents of .vue files to work around the runtime-only absence of template compilation. If this isn't a bug then it seems to me that it is an incompatibility.

From the 2.0 RC wiki:

When you use vue-loader or vueify to import .vue files, their