In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-03-31 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >
Share
Shulou(Shulou.com)05/31 Report--
This article introduces the relevant knowledge of "case Analysis of the principle of Vue slot implementation". In the operation of actual cases, many people will encounter such a dilemma, so let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!
First, sample code this is the default slot, this is the named slot, this is the scope slot (old version) {{scope.test}}, this is the scope slot (new version) {{scopeProps.test}} two, look at the essence through the phenomenon
The role of slot is to achieve content distribution, which requires two conditions:
Placeholder
Distribution content
The slot tag defined inside the component can be understood as a placeholder, and the slot content in the parent component is the content to be distributed. The essence of slot processing is to put the specified content in a specified location. Needless to say, from this article, you will know:
The realization principle of slot
How to use slots in render method
Third, the realization principle
The order of vue component instantiation is as follows: parent component state initialization (data, computed, watch...)-> template compilation-- > generate render method-- > instantiate rendering watcher-- > call render method, generate VNode-- > patch VNode, convert to real DOM-- > instantiate child components-- >. Repeat the same process-- > mount the real DOM generated by the child component to the real DOM generated by the parent component, mount it to the page-- > remove the old node
From the above process, it can be inferred that:
1. The parent component template is resolved before the child component, so the parent component first gets the slot template content
two。 The sub-component template is parsed later, so when the sub-component calls the render method to generate VNode, you can get the VNode node of the slot by some means.
3. Scope slots can obtain variables within subcomponents, so the VNode generation of scope slots is dynamic, that is, the scope scope of subcomponents needs to be transmitted in real time.
The processing phase of the entire slot is roughly divided into three steps:
Compile
Generate rendering templat
Generate VNode
Take the following code as an example to briefly outline the process of slot operation.
123 new Vue ({el:'# app', components: {test: {template:'+'+'}) IV. Parent component compilation phase
Compilation parses the template file into an AST syntax tree, which parses the slot template into the following data structure:
{tag: 'test', scopedSlots: {/ / scope slot / / slotName: ASTNode, / /} children: [{tag:' template', / /. Parent: parentASTNode, children: [childASTNode], / / slot content child node, that is, text node 123slotScope: undefined, / / scope slot binding value slotTarget: "\" hello\ ", / / named slot name slotTargetDynamic: false / / whether it is a dynamic binding slot / /.}] V, parent component generation rendering method
Parse and generate the rendering method string according to the AST syntax tree, and the final result generated by the parent component is as follows. This structure is the same as our direct render method. The essence is to generate VNode, except that _ c or h is the abbreviation of this.$createElement.
With (this) {return _ c ('div', {attrs: {"id": "app"}}, [_ c (' test', [_ c ('template', {slot: "hello"}, [_ v ("\ n123\ n")])], 1)} VI. The parent component generates VNode
Call the render method to generate VNode,VNode in the following format:
{tag: 'div', parent: undefined, data: {/ / Storage VNode configuration item attrs: {id:' # app'}}, context: componentContext, / / component scope elm: undefined, / / Real DOM element children: [{tag: 'vue-component-1-test', children: undefined, / / component is the smallest component of the page Put the contents of the slot into the subcomponent to parse parent: undefined, componentOptions: {/ / component configuration item Ctor: VueComponentCtor, / / component construction method data: {hook: {init: fn, / / instantiate the component call method insert: fn, prepatch: fn, destroy: fn} ScopedSlots: {/ / scope slot configuration item Used to generate scope slot VNode slotName: slotFn}}, children: [/ / component slot node tag: 'template', propsData: undefined, / / props parameter listeners: undefined, data: {slot:' hello'}, children: [VNode] Parent: undefined, context: componentContext / / parent component scope / /...]}], / /.}
In vue, the component is the basic unit of the page structure. From the above VNode, we can also see that the VNode page hierarchy ends with the test component, and the test component children will be handled during the initialization process of the sub-component. The subcomponent constructor assembly and properties are merged in the vue-dev\ src\ core\ vdom\ create-component.js createComponent method, and the component instantiation invocation entry is in the vue-dev\ src\ core\ vdom\ patch.js createComponent method.
VII. State initialization of sub-components
When instantiating a subcomponent, the subcomponent slot node is mounted to the component scope vm in the initRender-> resolveSlots method in the form of vm.$slots = {slotName: [VNode]}.
VIII. Sub-component compilation phase
During the compilation phase, the subcomponent compiles the slot node into the following AST structure:
{tag:'H2, parent: undefined, children: [{tag: 'slot', slotName: "\" hello\ ", / /...}], / /...} IX. Sub-components generate rendering methods
The generated rendering method is as follows, where _ t is the abbreviation of the renderSlot method. From the renderSlot method, we can intuitively associate the slot content with the slot point.
/ / rendering method with (this) {return _ c ('H2, [_ t ("hello")], 2)} / / Source path: vue-dev\ src\ core\ instance\ render-helpers\ render-slot.jsexport function renderSlot (name: string, fallback:? Array, props:? Object BindObject:? Object):? Array {const scopedSlotFn = this.$scopedSlots [name] let nodes if (scopedSlotFn) {/ / scoped slot props = props | {} if (bindObject) {if (process.env.NODE_ENV! = = 'production' & &! isObject (bindObject)) {warn (' slot v-bind without argument expects an Object', this)} props = extend (extend ({}) BindObject), props)} / / scope slot Get slot VNode nodes = scopedSlotFn (props) | | fallback} else {/ / get slot normal slot VNode nodes = this.$slots [name] | | fallback} const target = props & & props.slot if (target) {return this.$createElement ('template', {slot: target}, nodes)} else {return nodes}}
The difference between scope slots and named slots
{{scope.hello}} var vm = new Vue ({el:'# app', components: {test: {data () {return {hello: '123'}}) Template:'+'+'}})
The main difference between scope slots and ordinary slots is that the contents of slots can obtain subcomponent scope variables. Due to the need to inject subcomponent variables, scope slots differ from named slots in the following ways:
When a rendering method is assembled, the scope slot generates a method that contains injection scope. Compared to the VNode generated by createElement, there is an additional layer of injection scope method package, which determines that the slot VNode scope slot is generated when the child component generates the VNode, while the named slot is generated when the parent component creates the VNode. _ u is resolveScopedSlots, which converts the node configuration item into {scopedSlots: {slotName: fn}} form.
With (this) {return _ c ('div', {attrs: {"id": "app"}}, [_ c (' test', {scopedSlots: _ u) ([{key: "hello") Fn: function (scope) {return [_ v ("\ n" + _ s (scope.hello) + "\ n")}])})), 1)}
During initialization, the subcomponent processes the named slot node and mounts it to the component $slots, while the scope slot is called directly in renderSlot.
In addition, the other processes are roughly the same. Slot mechanism is not difficult to understand, the key is template parsing and generating render function these two steps are more content, the process is longer, more difficult to understand.
10. Use skills
Through the above analysis, we can roughly understand the slot processing flow. Most of the work uses templates to write vue code, but sometimes templates have some limitations, so it is necessary to enlarge the component abstraction ability of vue with the help of render method. In the render method, our slot is used as follows:
10.1, named slot
Slot processing is generally divided into two pieces:
Parent component: the parent component only needs to be written into the rendering method compiled by the template, that is, specify the slot slot name
Child component: since the child component directly takes the VNode generated during the initialization phase of the parent component, the child component only needs to replace the slot tag with the VNode generated by the parent component, and the child component will mount the named slot to the component $slots attribute when initializing the state.
New Vue ({/ / el:'# app', render (createElement) {return createElement ('test', [createElement (' h4pm, {slot: 'hello', domProps: {innerText:' 123}})])} Components: {test: {render (createElement) {return createElement ('H2, [this.$slots.hello]) } / / template:''+ /'+ / /'}}). $mount ('# app') 10.2, scope slot
Scope slots are flexible to use and can be injected into the state of subcomponents. The scope slot + render method plays a very important role in the encapsulation of secondary components. For example, scope slots are very useful when encapsulating ElementUI table components based on JSON data.
New Vue ({/ / el:'# app', render (createElement) {return createElement ('test', {scopedSlots: {hello: scope = > {/ / parent component generation rendering method The scope slot method of the final conversion is consistent with this writing return createElement ('span', {domProps: {innerText: scope.hello}})})} Components: {test: {data () {return {hello: '123'}}, render (createElement) {/ / the parent component of the scope slot passes function Need to manually call to generate VNode let slotVnode = this.$scopedSlots.hello ({hello: this.hello}) return createElement ('H2, [slotVnode])} / / template:'+ / /'+ / /'}}). This is the end of $mount ('# app') "Vue slot implementation example Analysis" Thank you for your reading. If you want to know more about the industry, you can follow the website, the editor will output more high-quality practical articles for you!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.