关于this.$options._component的值。
来源:17-1 组件通信provide和inject
 
			慕工程3718384
2019-12-03
Test 中的 _component的值 为什么首字母被小些了?而Test3组件中没有?
 Vue.component('Test',{
                template:"<div>{{message}}<Test2 /></div>",
                provide(){
                    return {
                        elTest:this
                    }
                },
                data(){
                    return {
                        message:'message from ' + this.$options._componentTag
                        //_componentTag = test
                    }
                },
                methods:{
                    change:function(component) {
                        this.message = 'message from ' + component
                    }
                }
            });
             Vue.component('Test2',{
                template:"<Test3 />"
            });
            
            Vue.component('Test3',{
               template:"<button type='button' @click='changeMessage'> change </button>",
               inject:['elTest'],
               methods:{
                   changeMessage:function () {
                       this.elTest.change(this.$options._componentTag);
                       //_componentTag = Test3
                   }
               }
            });
            
3回答
- 
				  Sam 2019-12-04 你好,这是一个非常好的问题,要搞清楚这个问题需要对 Vue 的源码比较熟悉,问题出在 template 获取的部分,大致原理如下: 在 $mount 方法中,会使用如下代码获取 template 的 html 字符串: template = getOuterHTML(el); 对于本案例中返回的结果为: "<div id="root"> <test></test> </div>" 注意,这里的 Test 已经被转为了 test,此后在 baseCompile 的 parse 会将 template 解析为 AST,在解析 AST 过程中会将 id 为 root 的 div 的 children 解析出来,children 中包含了 test 标签,最后会生成 render 函数如下: (function anonymous( ) { with(this){return _c('div',{attrs:{"id":"root"}},[_c('test')],1)} })可以看到 _c('test') 中已经将 test 变成小写,而 Test 组件中的 template 为: <div>{{message}}<Test2 /></div>Test 组件的渲染方法如下: child.$mount(hydrating ? vnode.elm : undefined, hydrating); 该方法中会获取组件的 template,这里的获取方法与 Vue 实例中不同: if (!options.render) { var template = options.template; if (template) { if (typeof template === 'string') { if (template.charAt(0) === '#') { template = idToTemplate(template); /* istanbul ignore if */ if (!template) { warn( ("Template element not found or is empty: " + (options.template)), this ); } } } else if (template.nodeType) { template = template.innerHTML; } else { { warn('invalid template option:' + template, this); } return this } } else if (el) { template = getOuterHTML(el); }最终会执行 Test 组件的 render 方法: (function anonymous( ) { with(this){return _c('div',[_v(_s(message)),_c('Test2')],1)} })212019-12-10
- 
				  Sam 2019-12-04 你看源码非常细心,不过想搞清楚这个问题较为复杂,最后一句话概况,造成这种差异的原因是:template 获取方式不同。 写在 root 下的 Test 通过: template = getOuterHTML(el); 获取 template,getOuterHTML 通过 el.outerHTML 来实现,而组件的 template 是直接返回的,没有做任何处理,所以造成了这种差异 10
- 
				  Hemingway_AT 2019-12-10 现象是:除了第一层级的组件,_componentTag 小写,其子组件和孙子组件...都是大写 00
相似问题
 
						