动态组件在开发的过程中大多数情况下都会用到,当我们需要在不同的组件之间进行状态切换时,动态组件可以很好的满足我们的需求,其中的核心是component标签和is属性的使用。【相关推荐:《vue.js教程》】
<div id="app"> <button @click="changetabs('child1')">child1</button> <button @click="changetabs('child2')">child2</button> <button @click="changetabs('child3')">child3</button> <component :is="choosetabs"> </component></div>
// jsvar child1 = { template: '<div>content1</div>',}var child2 = { template: '<div>content2</div>'}var child3 = { template: '<div>content3</div>'}var vm = new vue({ el: '#app', components: { child1, child2, child3 }, methods: { changetabs(tab) { this.choosetabs = tab; } }})
例子是一个动态组件的基本使用场景,当点击按钮时,视图根据this.choosetabs值在组件child1,child2,child3间切换。
ast解析<component>的解读和前面几篇内容一致,会从ast解析阶段说起,过程也不会专注每一个细节,而是把和以往处理方式不同的地方特别说明。针对动态组件解析的差异,集中在processcomponent上,由于标签上is属性的存在,它会在最终的ast树上打上component属性的标志。
// 针对动态组件的解析function processcomponent (el) { var binding; // 拿到is属性所对应的值 if ((binding = getbindingattr(el, 'is'))) { // ast树上多了component的属性 el.component = binding; } if (getandremoveattr(el, 'inline-template') != null) { el.inlinetemplate = true; }}
render函数有了ast树,接下来是根据ast树生成可执行的render函数,由于有component属性,render函数的产生过程会走gencomponent分支。
// render函数生成函数var code = generate(ast, options);// generate函数的实现function generate (ast,options) { var state = new codegenstate(options); var code = ast ? genelement(ast, state) : '_c("div")'; return { render: ("with(this){return " + code + "}"), staticrenderfns: state.staticrenderfns }}function genelement(el, state) { ··· var code; // 动态组件分支 if (el.component) { code = gencomponent(el.component, el, state); }}
针对动态组件的处理逻辑其实很简单,当没有内联模板标志时(后面会讲),拿到后续的子节点进行拼接,和普通组件唯一的区别在于,_c的第一个参数不再是一个指定的字符串,而是一个代表组件的变量
// 针对动态组件的处理 function gencomponent ( componentname, el, state ) { // 拥有inlinetemplate属性时,children为null var children = el.inlinetemplate ? null : genchildren(el, state, true); return ("_c(" + componentname + "," + (gendata$2(el, state)) + (children ? ("," + children) : '') + ")") }
普通组件和动态组件的对比"with(this){return _c('div',{attrs:{"id":"app"}},[_c('child1',[_v(_s(test))])],1)}"
动态组件的render函数with(this){return _c('div',{attrs:{"id":"app"}},[_c(choosetabs,{tag:"component"})],1)}
简单的总结,动态组件和普通组件的区别在于:
ast阶段新增了component属性,这是动态组件的标志
产生render函数阶段由于component属性的存在,会执行gencomponent分支,gencomponent会针对动态组件的执行函数进行特殊的处理,和普通组件不同的是,_c的第一个参数不再是不变的字符串,而是指定的组件名变量。
render到vnode阶段和普通组件的流程相同,只是字符串换成了变量,并有{ tag: 'component' }的data属性。例子中choosetabs此时取的是child1。
有了render函数,接下来从vnode到真实节点的过程和普通组件在流程和思路上基本一致,这一阶段可以回顾之前介绍组件流程的分析
更多编程相关知识,请访问:编程入门!!
以上就是浅谈vue中动态组件怎么使用?的详细内容。
