Vue Slots Jsx

2021年10月29日
Register here: http://gg.gg/wcqta
Basics
Vue recommends using templates to build your HTML in the vast majority of cases. There are situations however, where you really need the full programmatic power of JavaScript. That’s where you can use the render function, a closer-to-the-compiler alternative to templates.
Let’s dive into a simple example where a render function would be practical. Say you want to generate anchored headings:
For the HTML above, you decide you want this component interface:
When you get started with a component that only generates a heading based on the level prop, you quickly arrive at this:
If you use Vue version above 2.6.0, Vue introduces new unified slot api, which is v-slot. It replaces the slot and slot-scope attributes, which are deprecated, but have not been removed and are still documented here. You can refer to deprecated API here. # Slots (Default). This page assumes you’ve already read the Components Basics.Read that first if you are new to components. Vue implements a content distribution API that’s modeled after the current Web Components spec draft, using the slot element to serve as distribution outlets for content. Vue.js - The Progressive JavaScript Framework. Each Vue instance goes through a series of initialization steps when it’s created - for example, it needs to set up data observation, compile the template, mount the instance to the DOM, and update the DOM when data changes. 渲染函数 & JSX — Vue.jsrender函数特点render函数和模板一样,模板可以做的事情它都可以做render函数是最接近编译器的函数render函数返回vnode模板和jsx会先编译成render函数然后在返回vnode组件树中的所有 V.
That template doesn’t feel great. It’s not only verbose, but we’re duplicating <slot></slot> for every heading level and will have to do the same when we add the anchor element.
While templates work great for most components, it’s clear that this isn’t one of them. So let’s try rewriting it with a render function:
Much simpler! Sort of. The code is shorter, but also requires greater familiarity with Vue instance properties. In this case, you have to know that when you pass children without a slot attribute into a component, like the Hello world! inside of anchored-heading, those children are stored on the component instance at $slots.default. If you haven’t already, it’s recommended to read through the instance properties API before diving into render functions.Nodes, Trees, and the Virtual DOM
Before we dive into render functions, it’s important to know a little about how browsers work. Take this HTML for example:
When a browser reads this code, it builds a tree of “DOM nodes” to help it keep track of everything, just as you might build a family tree to keep track of your extended family.
The tree of DOM nodes for the HTML above looks like this:
Every element is a node. Every piece of text is a node. Even comments are nodes! A node is just a piece of the page. And as in a family tree, each node can have children (i.e. each piece can contain other pieces).
Updating all these nodes efficiently can be difficult, but thankfully, you never have to do it manually. Instead, you tell Vue what HTML you want on the page, in a template:
Or a render function:
And in both cases, Vue automatically keeps the page updated, even when blogTitle changes.The Virtual DOM
Vue accomplishes this by building a virtual DOM to keep track of the changes it needs to make to the real DOM. Taking a closer look at this line:
What is createElement actually returning? It’s not exactly a real DOM element. It could perhaps more accurately be named createNodeDescription, as it contains information describing to Vue what kind of node it should render on the page, including descriptions of any child nodes. We call this node description a “virtual node”, usually abbreviated to VNode. “Virtual DOM” is what we call the entire tree of VNodes, built by a tree of Vue components.createElement Arguments
The next thing you’ll have to become familiar with is how to use template features in the createElement function. Here are the arguments that createElement accepts:The Data Object In-Depth
One thing to note: similar to how v-bind:class and v-bind:style have special treatment in templates, they have their own top-level fields in VNode data objects. This object also allows you to bind normal HTML attributes as well as DOM properties such as innerHTML (this would replace the v-html directive):Complete Example
With this knowledge, we can now finish the component we started:ConstraintsVNodes Must Be Unique
All VNodes in the component tree must be unique. That means the following render function is invalid:
If you really want to duplicate the same element/component many times, you can do so with a factory function. For example, the following render function is a perfectly valid way of rendering 20 identical paragraphs:Replacing Template Features with Plain JavaScriptv-if and v-for
Wherever something can be easily accomplished in plain JavaScript, Vue render functions do not provide a proprietary alternative. For example, in a template using v-if and v-for:
This could be rewritten with JavaScript’s if/else and map in a render function:v-model
There is no direct v-model counterpart in render functions - you will have to implement the logic yourself:
This is the cost of going lower-level, but it also gives you much more control over the interaction details compared to v-model.Event & Key Modifiers
For the .passive, .capture and .once event modifiers, Vue offers prefixes that can be used with on:Modifier(s)Prefix.passive&.capture!.once~.capture.once or
.once.capture~!
For example:
For all other event and key modifiers, no proprietary prefix is necessary, because you can use event methods in the handler:Modifier(s)Equivalent in Handler.stopevent.stopPropagation().preventevent.preventDefault().selfif (event.target ! event.currentTarget) returnKeys:
.enter, .13if (event.keyCode ! 13) return (change 13 to another key code for other key modifiers)Modifiers Keys:
.ctrl, .alt, .shift, .metaif (!event.ctrlKey) return (change ctrlKey to altKey, shiftKey, or metaKey, respectively)
Here’s an example with all of these modifiers used together:Slots
You can access static slot contents as Arrays of VNodes from this.$slots: Does garmin nuvi 40 have sd slot.
And access scoped slots as functions that return VNodes from this.$scopedSlots:
To pass scoped slots to a child component using render functions, use the scopedSlots field in VNode data:Vue Jsx Slot PropsJSX
If you’re writing a lot of render functions, it might feel painful to write something like this:
Especially when the template version is so simple in comparison:
That’s why there’s a Babel plugin to use JSX with Vue, getting us back to a syntax that’s closer to templates:
Aliasing createElement to h is a common convention you’ll see in the Vue ecosystem and is actually required for JSX. If h is not available in the scope, your app will throw an error.
For more on how JSX maps to JavaScript, see the usage docs.Functional Components
The anchored heading component we created earlier is relatively simple. It doesn’t manage any state, watch any state passed to it, and it has no lifecycle methods. Really, it’s only a function with some props.
In cases like this, we can mark components as functional, which means that they’re stateless (no data) and instanceless (no this context). A functional component looks like this:
Note: in versions before 2.3.0, the props option is required if you wish to accept props in a functional component. In 2.3.0+ you can omit the props option and all attributes found on the component node will be implicitly extracted as props.
In 2.5.0+, if you are using single-file components, template-based functional components can be declared with:
Everything the component needs is passed through context, which is an object containing:
*props: An object of the provided props
*children: An array of the VNode children
*slots: A function returning a slots object
*data: The entire data object passed to the component
*parent: A reference to the parent component
*listeners: (2.3.0+) An object containing parent-registered event listeners. This is an alias to data.on
*injections: (2.3.0+) if using the inject option, this will contain resolved injections.
After adding functional: true, updating the render function of our anchored heading component would require adding the context argument, updating this.$slots.default to context.children, then updating this.level to context.props.level.
Since functional components are just functions, they’re much cheaper to render. However, the lack of a persistent instance means they won’t show up in the Vue devtools component tree.
They’re also very useful as wrapper components. For example, when you need to:
*Programmatically choose one of several other components to delegate to
*Manipulate children, props, or data before passing them on to a child component
Here’s an example of a smart-list component that delegates to more specific components, depending on the props passed to it:slots() vs children
You may wonder why we need both slots() and children. Wouldn’t slots().default be the same as children? In some cases, yes - but what if you have a functional component with the following children?
For this component, children will give you both paragraphs, slots().default will give you only the second, and slots().foo will give you only the first. Having both children and slots() therefore allows you to choose whether this component knows about a slot system or perhaps delegates that responsibility to another component by passing along children.Template Compilation
You may be interested to know that Vue’s templates actually compile to render functions. This is an implementation detail you usually don’t need to know about, but if you’d like to see how specific template features are compiled, you may find it interesting. Below is a little demo using Vue.compile to live-compile a template string:Compilation Error: Hai visto degli errori o vorresti contriuire alla repository? Modifica questa pagina in Github!
This page assumes you’ve already read the Components Basics. Read that first if you are new to components.Slot Content
Vue implements a content distribution API that’s modeled after the current Web Components spec draft, using the <slot> element to serve as distribution outlets for content.
This allows you to compose components like this:
Then in the template for <navigation-link>, you might have:
When the component renders, the <slot> element will be replaced by “Your Profile”. Slots can contain any template code, including HTML:
Or even other components:
If <navigation-link> did not contain a <slot> element, any content passed to it would simply be discarded.Named Slots
There are times when it’s useful to have multiple slots. For example, in a hypothetical base-layout component with the following template:
For these cases, the <slot> element has a special attribute, name, which can be used to define additional slots:
To provide content to named slots, we can use the slot attribute on a <template> element in the parent:
Or, the slot attribute can also be used directly on a normal element:Vue V-slot Jsx
There can still be one unnamed slot, which is the default slot that serves as a catch-all outlet for any unmatched content. In both examples above, the rendered HTML would be:Default Slot Content
There are cases when it’s useful to provide a slot with default content. For example, a <submit-button> component might want the content of the button to be “Submit” by default, but also allow users to override with “Save”, “Upload”, or anything else.
To achieve this, specify the default content in between the <slot> tags.
If the slot is provided content by the parent, it will replace the default content.Compilation Scope
When you want to use data inside a slot, such as in:Vue Jsx Slot Name
That slot has access to the same instance properties (i.e. the same “scope”) as the rest of the template. The slot does not have access to <navigation-link>‘s scope. For example, trying to access url would not work. As a rule, remember that:Jsx Vue Slots
Everything in the parent template is compiled in parent scope; everything in the child template is compiled in the child scope.Scoped SlotsVue Slot Jsx
New in 2.1.0+
Sometimes you’ll want to provide a component with a reusable slot that can access data from the child component. For example, a simple <todo-list> component may contain the following in its template:
But in some parts of our app, we want the individual todo items to render something different than just the todo.text. This is where scoped slots come in.
To make the feature possible, all we have to do is wrap the todo item content in a <slot> element, then pass the slot any data relevant to its context: in this case, the todo object:
Now when we use the <todo-list> component, we can optionally define an alternative <template> for todo items, but with access to data from the child via the slot-scope attribute:
In 2.5.0+, slot-scope is no longer limited to the <template> element, but can instead be used on any element or component in the slot.Destructuring slot-scopeVue Scoped Slots Jsx
The value of slot-scope can actually accept any valid JavaScript expression that can appear in the argument position of a function definition. This means in supported environments (single-file components or modern browsers) you can also use ES2015 destructuring in the expression, like so:
This is a great way to make scoped slots a little cleaner.← Custom EventsDynamic & Async Components → Phát hiện lỗi hoặc muốn đóng góp vào nội dung? Chỉnh sửa trang này trên GitHub!
Register here: http://gg.gg/wcqta

https://diarynote.indered.space

コメント

お気に入り日記の更新

テーマ別日記一覧

まだテーマがありません

この日記について

日記内を検索