import App from './App' 导进来的到底是什么

App.vue中有template,script,style,那么在main.js中import App from './App'导入的到底是什么内容,

console.log(APP)出来是下面的内容,是个对象
Object { name: "app", render: render(), staticRenderFns: Array[0], _compiled: true, beforeCreate: Array[2], __file: "src\App.vue", beforeDestroy: Array[1] }

为什么既可以template: '<App/>', 也可以components: { App }

是不是通过</>和{}来判断是template还是components,这些由VUE引擎来做?

阅读 6.5k
1 个回答

你看到的东西,是vue帮你处理过的,渲染的时候会调用render(这句存疑,我再看看调用的啥)。

  1. 你把单文件组件当成让你写起来更舒服一点的形式就可以了。vue-cli脚手架的其他插件会帮你抽取每个部分,export default导出的是上面的<template>和<script>里的东西(应该是经过了_init处理的)。
  2. template属性是定义当前组件的html应该是什么,而components是定义当前组件内的自定义标签是哪些组件。

如:

import Custon from './Custom'
export default {
  template: `
  <div></div>
  <Custom />
  `,
  components: {Custom}
}

意思就是当前组件的html(template)有一个div和一个自定义标签Custom,当前组件内的自定义标签是这些组件(components):中的Custom

可以看看文档的这部分


  1. template里的<App />标签通过去components里按名字找对应的component后生成实例,然后会在实例的mounted阶段被替换掉。然后template里的<App />的使命就结束了。然后生成App组件的实例,再去index.html中把id为app的元素,再把它替换掉,这是整个过程。
    你可以把App.vue中的<div id="app">改成<div id="test">看看最后渲染出来的id是啥。
  2. 刚才又去看了vue的源代码,通过在Vue.prototype._render = function () {里打断点,确定组件在注册而不挂载的时候是不会调用render的。

然后我大概说下直接引入vue时,vue是怎么运行的。

  1. vue.js开始接管页面dom(如果你先给元素绑定事件,在引入js会发现原有事件全部失效,因为你再看到的页面上的new Vue()范围内的元素全都是vue重新生成的)。
  2. 这个解析页面dom的过程中,遇到未识别的标签如<App />,会去全局的Vue的components集合里去找(在单文件组件中会逐级的往上找,也可能是别的机制),比如components里{APP},其实就是{App: App},你可以理解为key就是自定义标签的名字,value就是注册的组件,vue对这个调用一些如render方法之后,生成实例然后替换掉页面上的<App />标签。
    使用引入的方式写下方代码
<div id="example">
  <my-component></my-component>
</div>
new Vue({
  el: '#example'
})
Vue.component('my-component', {
  template: '<div>A custom component!</div>'
})

提示未注册,意思就是碰到自定义标签后,没有找到对应的component。
然后调整组件注册顺序,打断点并注释掉new Vue部分,可以观察到并没有进入断点。
你也可以去vue.js多打一些断点,看是怎么运行的。

说的有些乱,也有些不清楚和错误的地方欢迎纠正。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题