vuejs / vue

This is the repo for Vue 2. For Vue 3, go to https://github.com/vuejs/core
http://v2.vuejs.org
MIT License
207.83k stars 33.68k forks source link

Vue 2.0 Problem with Slot #3965

Closed eugenio4 closed 7 years ago

eugenio4 commented 8 years ago

Hello, I'm using Vue 2.0 standalone and i have a problem with components with Slot. Always render default value inside slot. Never render content inside custom component

package.json

{
  "name": "web-components",
  "description": "A Vue.js project",
  "author": "",
  "private": true,
  "scripts": {
    "watchify": "watchify -vd -p browserify-hmr -e src/main.js -o dist/build.js",
    "serve": "http-server -o -c 1 -a localhost",
    "dev": "npm-run-all --parallel watchify serve",
    "lint": "eslint --ext .js,.vue src test/unit",
    "test": "karma start karma.conf.js",
    "build": "cross-env NODE_ENV=production browserify -g envify -p [ vueify/plugins/extract-css -o dist/build.css ] -e src/main.js | uglifyjs -c warnings=false -m > dist/build.js"
  },
  "browserify": {
    "transform": [
      "vueify",
      "babelify"
    ]
  },
  "aliasify": {
    "aliases": {
      "vue": "vue/dist/vue"
    }
  },
  "dependencies": {
    "vue": "^2.0.1"
  },
  "devDependencies": {
    "aliasify": "^2.0.0",
    "babel-core": "^6.0.0",
    "babel-plugin-transform-runtime": "^6.0.0",
    "babel-preset-es2015": "^6.0.0",
    "babel-preset-stage-2": "^6.0.0",
    "babel-runtime": "^6.0.0",
    "babelify": "^7.2.0",
    "browserify": "^13.1.0",
    "browserify-hmr": "^0.3.1",
    "cross-env": "^2.0.0",
    "envify": "^3.4.1",
    "eslint": "^3.3.0",
    "eslint-config-standard": "^5.3.5",
    "eslint-plugin-html": "^1.5.2",
    "eslint-plugin-promise": "^2.0.1",
    "eslint-plugin-standard": "^2.0.0",
    "http-server": "^0.9.0",
    "jasmine-core": "^2.4.1",
    "karma": "^1.2.0",
    "karma-browserify": "^5.1.0",
    "karma-jasmine": "^1.0.2",
    "karma-phantomjs-launcher": "^1.0.0",
    "karma-spec-reporter": "0.0.26",
    "npm-run-all": "^2.3.0",
    "phantomjs-prebuilt": "^2.1.3",
    "proxyquireify": "^3.0.1",
    "uglify-js": "^2.5.0",
    "vueify": "^9.0.0",
    "watchify": "^3.4.0"
  }
}

main.js

//this show Failed to mount component: template or render function not defined. 
//import Vue from 'vue/dist/vue'
import Vue from 'vue'

import Hello from './components/Hello.vue'

Vue.component('Hello',Hello)

new Vue({ // eslint-disable-line no-new
  el: '#app'
});

Hello.vue

<template>
  <div id="hello">
    <h1>{{ msg }}</h1>
    <slot>defect</slot>
  </div>
</template>

<script>
export default {
  name: 'hello',
  data () {
    return {
      msg: 'Welcome to Your Vue.js App'
    }
  }
}
</script>

index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>web-components</title>
    <link rel="stylesheet" href="dist/build.css">
  </head>
  <body>
    <div id="app">
        <hello><label>change value</label></hello>

    </div>
    <script src="dist/build.js"></script>
  </body>
</html>
LinusBorg commented 8 years ago

There's a bug in the browserify template that I just today submitted a PR for, and I assume it's the reason for your problem.

It will likely be fixed tomorrow.

Meanwhile, the fix for you is easy - your package.json should look like this:

// ...
"browserify": {
    "transform": [
      "babelify",
      "aliasify",
      "vueify"
    ]
  },
  "aliasify": {
    "aliases": {
      "vue$": "vue/dist/vue"
    }
  },
 //...

Then you can use the original import line that you have commented out.

eugenio4 commented 8 years ago

Hello , I tried to change the package.json but when i use import Vue from 'vue' i have a error

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

When use import Vue from 'vue/dist/vue' no render content inside slot

LinusBorg commented 8 years ago

please provide a live reproduction (repository) or ask on the forums for help.

forum , Stack Overflow or on gitter

eugenio4 commented 8 years ago

here repository with the problem

https://github.com/eugenio4/vue-slot

eugenio4 commented 8 years ago

If i use npm run build instead of nrpm run dev. This work fine.

defcc commented 7 years ago

Got it, @eugenio4。 I'll take a look at this issue, @LinusBorg

HerringtonDarkholme commented 7 years ago

Please just don't mix runtime only build with standalone build. They are incompatible. My suggestion after digging to the build.js

From the comment here

FYI: You should use standalone build to use html template. To adapt runtime build, use render option instead of writing html.

new Vue({
  el: '#app',
  render: h => h('hello'),
})

For more info, please see https://github.com/vuejs/vue/wiki/Vue-2.0-RC-Starter-Resources#standalone-vs-runtime-builds

If you need more complex entry point template, just write an entry component. And render it in render function.

More Info:

The problem is vue-hot-load api in vueify uses runtime build, and user code uses standalone build. These two builds both mount the same component and are agnostic about each other. The slots children are lost between two conflicting builds.

defcc commented 7 years ago

As @HerringtonDarkholme metioned, there are two vue versions in your app indeed, standalone and runtime version when you run npm run dev

Standalone required from your app.js is used to compile the template in the html, it is resolved to "vue/dist/vue.js" . And in internal there is a runtime version used by vueify to compile your .vue files and hot-reload, it is resolved to "vue/dist/vue.common.js" and bundled to the compiled js files too.

It fails when doing some prototype checks in runtime (one from vue.js and the other from vue.common.js), so you just get the default slot node.

As for npm run build , NODE_ENV is set to production when you run it, so the hot-reload logic is eliminated and it works.

As for your issue, you could just select "Runtime-only" version when init your app with vue-cli, and move all your codes into .vue files.

I'll make a PR to update the related docs to specifiy this problem.

Maybe the best way is that we could ensure the only one vue version in the browserify template. I am looking into it.

LinusBorg commented 7 years ago

This problem is explained on the "installation" page of the guide. But maybe it can be improved / also mentioned in the migration guide?

defcc commented 7 years ago

@LinusBorg I think so. We should also upgrade the browserify template. I'll try to do it.

LinusBorg commented 7 years ago

Browserify template is also updated, it uses aliasify if standalone was selected.

defcc commented 7 years ago

@LinusBorg it seems not working as expected, because .vue files are not processed duiring the aliasify transformation. I open a PR here https://github.com/benbria/browserify-transform-tools/pull/26 to add .vue file to its JS_EXTENSIONS. Once it's merged, I will update the template as well.

defcc commented 7 years ago

@eugenio4 ,this is an issue of browserify template, and I have submited a PR to fix it.

I forked your repo and updated it here https://github.com/defcc/vue-slot/blob/master/package.json

You could adjust your package.json like this.

"browserify": {
  "transform": [  
    "babelify",   
    "vueify"   
  ]  
},
"browser": {
   "vue": "vue/dist/vue" 
}
defcc commented 7 years ago

PR merged, I'll close this issue. If your problem still exists, you could report an issue here https://github.com/vuejs-templates/browserify/issues