Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

Example Analysis of incomplete Application of jsx in Vue

2025-04-12 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

This article mainly introduces the example analysis of the incomplete application of jsx in Vue, which is very detailed and has a certain reference value. Interested friends must read it!

When using Vue development projects, in most cases, templates are used to write HTML, but sometimes the page is complex and there are various conditions to show / hide and piece together the page content, or when many parts of the page have the same DOM structure, they are slightly stretched, a lot of repetitive code will be written, and a single .vue file will be too long, so we need more code control. You can use the rendering function at this time.

Presumably, few people write rendering functions, because it is very painful to write (I haven't written it either). JSX syntax is more often used in Vue. The way it is written is similar to that in React, but it is still not as perfect as in React.

The problem of a style should not be considered in the process of writing JSX, although you can write only part and part directly in the .vue file, without worrying about the style scope. But more often, it is recommended to use .js to write components directly, which involves the issue of style scope.

In the ecology of React, there are many CSS-IN-JS solutions, such as styled-jsx, emotion, styled-components and so on. At present, styled-components is the most active and has the largest number of users, which has a good ecological circle. If you need to do some color calculation in the style like that in Sass/Less, you can use polished to achieve, of course, more than that simple function. But there are too few solutions available in Vue, because Vue uses templates to write HTML itself is out of the box style scoped, when using JSX to write components are faced with style problems, one solution is to take a special name in the component package, and then the styles are nested under this class, but it is inevitable to encounter naming conflicts, and each time you have to change the pattern to take the name. In addition, the corresponding implementation of CSS-IN-JS in Vue is introduced, but at present, Styled-components officially provides a Vue version of vue-emotion called vue-styled-components and emotion, but there are too few people to use it. For example, styled-components has made major updates and changes, but the Vue version is still the original version, and sometimes the style does not take effect.

Let's get to the point, from simple grammar to experience sharing (Daniel, please make a detour)

Basic usage

First of all, you need to agree that using JSX components to name the hump in uppercase, the style can be written directly in the same file based on vue-styled-components, complex suggestions can be put in a separate _ Styles.js_ file, of course, you can not use CSS-IN-JS, use Less/Sass to write, and then import in the file.

Here is a general skeleton:

Import styled from 'vue-styled-components'const Container = styled.div` heigth: 100%; `const Dashboard = {name:' Dashboard', render () {return (content)}} export default Dashboard

Interpolation.

Use a single parenthesis to bind text interpolation in JSX

Message: {this.messsage}

In jsx, there is no need to separate v-model into event binding and assignment, because there is a corresponding babel plug-in to deal with it.

Style

In JSX, you can directly use class= "xx" to specify style classes, and inline styles can be written directly as

Button

Ergodic

There are no instructions such as v-for and v-if in JSX, all of which need to be implemented by Js.

{/ * similar to v-if * /} {this.withTitle & &} {/ * similar to v-if plus v-else * /} {this.isSubTitle?:} {/ * similar to v-for * /} {this.options.map (option = > {{option.title}})}

Event binding

Event binding needs to be prefixed with on in front of the event name, and nativeOn is added to the native event.

Click meNative click this.handleClick (this.id)} > Click and pass data

Note: if you need to pass parameters to the event handler, you need to use the arrow function to do so. If you do not use the arrow function, you will receive the event property of the object of the event.

Advanced part

In Vue, components can also be split into small functional components based on jsx, but there is a limitation that there must be an outer wrap element, which cannot be written directly like:

Const Demo = () = > (One Two)

Must be written as follows:

Const Demo = () = > (One Two)

In React, you can use empty tags and to implement package elements, where the empty tag is really just a syntactic sugar of react.Fragment. At the same time, the form of returned array is directly supported in React 16:

Const Demo = () = > [One Two]

Then similar functions can only be achieved through traversal in Vue. The general idea is to define the data first and then generate a map directly. Of course, if the tags of elements are of different types, you need to add additional identifiers to judge.

{data () {return {options: ['one',' two']}}, render () {const LiItem = () = > this.options.map (option = > {option}) return ()}}

Event modifier

In the basic part, we briefly introduce the binding use of events, which is mainly to supplement the writing of event modifiers.

In the template syntax, Vue provides many event modifiers to quickly deal with event bubbling, capture, event trigger frequency, keystroke identification, and so on. You can directly view the event-button modifier section of the official document, where the relevant content is shipped as is:

The modifier prefix .passive & .capture! .once ~ .capture.once or .once.capture ~!

The mode of use is as follows:

Click Me!

The event modifiers given below are equivalent operations that need to be written in the event handler.

The modifier handles the equivalent operation in the function .stopevent.stopPropagation (). Selfif (event.target! = = event.currentTarget) return key: .enter, .13if (event.keyCode! = = 13) return (for other key modifiers, 13 can be changed to another key code) modifier key: .ctrl, .alt, .shift, .metaif (! event.ctrlKey) return (modify ctrlKey to altKey, shiftKey or metaKey, respectively)

The following is an example of using modifiers in event handlers:

Methods: {keyup (e) {/ correspond to `.self` if (e.target! = = e.currentTarget) return / / correspond to `.enter`, `.13` if (! e.shiftKey | | e.keyCode! = = 13) return / / correspond to `.stop` e.stopPropagation () / correspond to `.stop` e.preventDefault () / /...}}

Ref and refInFor

In Vue, ref is used to register reference information with elements or subcomponents. The reference information will be registered on the $refs object of the parent component. If used on a normal DOM element, the reference points to the DOM element; if used on a subcomponent, the reference points to the component.

Note:

Because ref itself is created as a rendering result, you cannot access them during the initial rendering-they do not yet exist

$refs is not responsive, so you should not try to use it for data binding in templates.

When v-for is used for an element or component, the reference information will be an array of DOM nodes or component instances.

If you want to reference traversal elements or components in jsx, for example:

Const LiArray = () = > this.options.map (option = > ({option}))

You will find that the array value obtained from this.$refs.li is not the desired value. At this point, you need to use the refInFor attribute and set it to true to achieve the effect of using ref in the template v-for:

Const LiArray = () = > this.options.map (option = > ({option}))

Slot (v-slot)

You can use this.$slots in jsx to access the contents of static slots.

Note: slot and slot-scope are discarded after version 2.6.x of Vue, and the new uniform syntax v-slot directive is used in the template. V-slot can only be used with Vue components and template tags.

{this.$slots.title? This.$slots.title: this.title}

Equivalent to a template

{{title}}

It is mentioned in the Vue official documentation that all content in the parent template is compiled in the parent scope; everything in the child template is compiled in the child scope. So an example like this doesn't work properly.

{{user.firstName}}

The user property is accessible in the component, but the content provided is rendered in the parent component. If you want to achieve the desired results, you need to use a scope slot at this time. The following is the rewritten code, more knowledge points can directly view the scope slot of the official document.

{{user.lastName}} {{slotProps.user.firstName}}

The above example is actually an official example. What needs to be explained here is that the so-called scope slot function in Vue is similar to the concept of Render Props in React, except that more often we provide not only attributes but also operation methods in React. But in Vue, more data is provided for parent scope rendering. Of course, we can also provide methods, such as:

{{user.lastName}} export default {data () {return {user: {firstName: 'snow', lastName:' wolf'}}}, computed: {slotProps () {return {user: this.user, logFullName: this.logFullName}}}, methods: {logFullName () {console.log (`${this.firstName} ${this.lastName}`)}

Use in the parent component:

{{injectedProps.user.firstName}} Log Full Name

In the above code, we actually use deconstruction to get the injectedProps. Based on the deconstructed feature, we can also rename the property name and specify the initial value when prop is undefined.

{{user.firstName}}

If the component has only one default slot, you can also use the abbreviation syntax. Write "slotProps" as "slotProps", and the named slot as "slotProps". If you want to dynamically insert the slot, you can also write the name as v-slot: [dynamicSlotName]. In addition, named slots also have abbreviation syntax, such as v-slot:header can be rewritten as # slot.

Many slot-related knowledge points have been introduced above to illustrate their importance in the development process. Much has been said about how to define and use scope slots in templates, but now let's get to the point of how to use them in jsx as well.

/ / current-user components {data () {return {user: {firstName: 'snow', lastName:' wolf'}, computed: {slotProps () {return {user: this.user, logFullName: this.logFullName}, methods: {logFullName () {console.log (`${this.firstName} ${this.lastName}`)}} Render () {return ({this.$scopedSlots.subTitle ({injectedProps: this.slotProps})})}

Then use jsx in the parent component:

(injectedProps.user Log Full Name)}} >

Instruction

It should be noted that all Vue built-in instructions in jsx are not supported except v-show, and need to be implemented in some equivalent ways, such as v-if using trinomial operation expressions, v-for using array.map (), and so on.

Custom instructions can be written using the syntax of vmuramee = {value}. It is important to note that the parameters and modifiers of the instructions are not supported. Taking the example of using v-focus given in the official document instruction section as an example, two solutions are introduced:

1 pass all instruction attributes directly using the object

2 use the original vnode instruction data format

{directives: {focus: {inserted: function (el) {el.focus ()}, render () {const directives = [{name: 'focus', value: true}] return ()}}

Filter

Filters are not often used in the development process, because more often, the data can be transformed and filtered by calculating properties. Here is just a brief mention that there is no knowledge to delve into.

The usage in the template is as follows:

{{message | capitalize}}

The method to use in jsx is:

{this.$options.filters ('formatDate') (' 2019-07-01')}

Note: since Vue global filters are only used in templates, if you need to use them in a component method, you can extract the filter method from a public Js file separately, then introduce it into the component, and then use it in the method.

Share some simple experiences

This is not to say that we have to use jsx to write when we develop Vue projects, but it is worth trying to master one more way to be flexible, improve work efficiency and expand our ideas. And, in some scenarios, unleashing the full programming power of js will make you more comfortable. In fact, when using the template way, we do not fully adopt the component way of thinking to do, or is not done thoroughly, not pure, the granularity of the split is not enough. More often do not take into account how components are divided and abstracted, how to deal with dependencies and define their own functional points when many people work together.

About DOM properties, HTML properties, and component properties

In React, all data is mounted under props, while Vue is not. There are only three properties: component attribute props, normal html attribute attrs and DOM attribute domProps. The interpolation binding section of the Angular document focuses on the difference between the DOM attribute and the HTML attribute. In most cases, both have corresponding properties of the same name, that is, 1:1 mapping, but there are exceptions, such as textContent in colspan,DOM in HTML. The value of the HTML property specifies the initial value and cannot be changed, while the value of the DOM property represents the current value and can be changed.

Then there is no distinction between the DOM attribute and the HTML attribute in the template syntax of Vue, for example:

Input value: {{title}} export default {data () {return {title:''}}, methods: {logTitle (e) {/ / output DOM attribute console.log (e.target.value) / / output HTML attribute console.log (e.target.getAttribue ('value'))}

Running the example shows that the initial value of input is set to "I am the DOM attribute value". When we add or delete text in the input box, the HTML property remains unchanged, while the bound DOM value is changing. Then take a look at the implementation in jsx:

Enter value: {this.title}

After the same operation, you will find that the HTML attribute is not directly initialized to the DOM attribute value in the jsx writing, that is, the current value in the input box is an empty string, which is in line with the expected behavior.

In addition, it is impossible to distinguish between HTML attribute and DOM attribute naming scenarios in template syntax, but it can be well distinguished in jsx:

The result is that the title= "I am the DOM property" is displayed in the HMTL, and the "I am the component property" is passed to the component.

The syntax of the style meaning of CSS in React is in the form of className= "xx" in jsx, while it can be written directly as class= "xx" in Vue jsx. In fact, because class is a reserved word for Js, its property name is className in DOM and class in HTML attribute. We can write this in Vue and get the correct style class name after Babel translation:

Note: if class= "xx" domPropsClassName= "yy" is written at the same time, then the latter has a higher priority, regardless of location. So try to use class as the writing method.

Anyone who has experience with Bootstrap may notice that it contains a lot of ARIA attributes, which do not belong to DOM, and can be added in jsx through attrsXX or direct aria-xx:

But replacing the above with domPropsAria-label has no effect.

Note: in jsx, all DOM attributes (Property) syntax is domPropsXx, and HTML attribute (Attribute) syntax is attrsXx. More often, it is recommended to use less, or use reasonably.

You can also use mixed writing in jsx, for example, in a component, you can define a property object, and then write it together in the way of {... props}. At this time, the problem of attribute merging will occur, and the same event will be triggered when event handlers are declared in multiple places.

Finally, it is important to mention that when there are a lot of props passed to a component in Vue, some are not declared by the component, or there may be some general HTML or DOM attributes, but these props will be directly displayed in the final compiled HTML. If you do not want these attributes to be displayed in the final HTML, you can set inheritAttrs: false in the component. Although it is not shown, we can still get all the bound properties (except class and style) through vm.$attrs, including those not defined in props.

About events

We have already introduced all the event-related knowledge points, and here we mainly talk about how to deal with jsx event binding syntax onXx and component properties (mainly function prop) that begin with on.

Although you can avoid starting with on when writing components, what if you encounter it when using the third library? For example, the Element component Upload has many hooks that start with on. Here are two solutions:

1. Use deployment

Use propsXx

The second way is recommended, which is easier to write.

Complex logic condition judgment

V-if, v-else-if and v-else can be used to determine conditions in template syntax. In jsx, you can use the?: ternary operator (Ternary operator) operator to make if-else judgment:

Const Demo = () = > isTrue?

True!

: null

You can then take advantage of the characteristics of the & & operator to abbreviate:

Const Demo = () = > isTrue & &

True!

For complex condition judgments, such as:

Const Demo = () = > ({flag & & flag2 & &! flag3? Flag4?

Blash

: flag5?

Meh

:

HErp

:

Derp

})

There are two ways to reduce the complexity of judgment and recognition.

The best way: transfer the judgment logic to the subcomponents

Optional hacky method: use IIFE (execute the expression immediately)

Use a third-party library to solve: jsx-control-statements

Here is the use of IIFE to optimize the above problem by internally using the if-else return value:

Const Demo = () = > ({() = > {if (flag & & flag2 & &! flag3) {if (flag4) {return)

Blah

} else if (flag5) {return

Meh

} else {return

Herp

}} else {return

Derp

}) ()})

You can also use do expressions, but you need a translation of the plug-in @ babel/plugin-proposal-do-expressions to support it.

Const Demo = () = > ({do {if (flag1 & & flag2 & &! flag3) {if (flag4) {

Blah

} else if (flag5) {

Meh

} else {

Herp

}} else {

Derp

})

Then there is a relatively simple alternative, as follows:

Const Demo = () = > {const basicCondition = flag & & flag1 &! flag3; if (! basicCondition) return

Derp

If (flag4) return

Blah

If (flag5) return

Meh

Return

Herp

}

The last one that uses the jsx plug-in does not elaborate and give examples. If you are interested, you can check the documentation directly.

Passed value of component

Many functional components can be written in a single jsx file to split into smaller granularities. For example, in the previous article, Vue backend management system development daily summary _ _ component PageHeader, there are two forms of components, one is a common title, the other is a title with a tab, so you can write it like this when writing:

Render () {/ / partial html const TabHeader = () / / function partial const Header = () = > () {this.withTab? TabHeader:}}

Note that when splitting, if you don't need to make any judgment, you can simply assign a value to a variable by a HTML fragment, and write it as a functional component if you need conditional judgment. It should be noted that because the render function will be called many times, pay attention to the impact on performance when writing, the current capacity is limited in this area will not be expanded.

Now that you are using functional components, you can also pass parameters in the function, which is an object that contains the following properties

Children # VNode array, similar to React's childrendata # bound attribute attrs # Attribute domProps # DOM property on # event injections # injected object listeners: # bound event type click # Click event... parent # parent component props # attribute scopedSlots # object, scope slot, scope slot is also found in the following slots # function, slot

Although it is possible to pass parameters, events, and slot in functional components, I personally feel that this is not recommended, but it is complicated.

Render () {const Demo = props = > {return (internal component in Jsx {props.data.title} {props.children} {props.scopedSlots.bar ()})} return (I am Children

I am Slot content.

)}

The above example will eventually generate a HTML that converts the content to # document-fragment.

The above is all the contents of the article "sample Analysis of incomplete Application of jsx in Vue". Thank you for reading! Hope to share the content to help you, more related knowledge, welcome to follow the industry information channel!

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: 211

*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.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report