JSX Extension
Alins uses JSX to describe the UI, but makes some extensions based on JSX to enable it to achieve more powerful capabilities. This chapter is about introducing some extensions to JSX in Alins.
1.JSX return value
Unlike JSX in React, which returns a React Component, in Alins, the JSX rendering function returns a native DOM element or DocumentFragment element, so we can use the following statement to add an element to the App element:
document.getElementById('App').appendChild(
<div>Hello World!</div>
)
It can be seen from the compiled product that the JSX object is converted into a _$ce
function for execution, and the return result is a DOM element. JSX allows us to write UI in JS just like writing HTML code.
Return DocumentFragment
By using an empty JSX tag, a DocumentFragment object can be returned
const frag = <>
<div>Div 1</div>
<div>Div 2</div>
</>;
console.log('Frag is a ', frag.constructor.name);
document.getElementById('App').appendChild(frag);
Frag Tags
You can also return a DocumentFragment through the Frag tag. The advantage is that you can use Frag to mount properties. Empty tags cannot
const frag = <Frag>
<div>Div 1</div>
<div>Div 2</div>
</Frag>;
console.log('Frag is a ', frag.constructor.name);
document.getElementById('App').appendChild(frag);
Note: When the Frag tag mounts attributes, all attributes introduced in subsequent chapters will only act on the first child element, and the life cycle will only act on the first child node.
2.$mount attribute
The $mount
attribute is used to mount the DOM element generated by the JSX object to the target node. It can be understood as syntactic sugar for the .appendChild method. For example, the example in the first section is equivalent to the following writing method using the $mount attribute.
<div $mount='#App'>Hello World!</div>
The value of the $mount attribute is an HTML selector used to select DOM elements. It has the same effect as appendChild, but the code will be much simpler and the writing burden will be reduced a lot.
Of course, the $mount
attribute value can also be another JSX object, as follows:
const parent = <div $mount='#App'>Parent</div>;
<div $mount={parent}>Child</div>
Note: Empty JSX tags do not support the $mount attribute
3.JSX expression
JSX expression is JS code wrapped in curly braces, which is used to embed JS logic into the UI, providing the UI with extremely high flexibility and scalability.
Here is an example of inserting html attributes and html content using JSX expressions
const msg = 'World';
<div title={`Hello ${msg}!`} $mount='#App'>{`Hello ${msg}!`}</div>;
4.$ref attribute
The $ref
attribute is used to reference the DOM element returned by the JSX object. Of course, you can also directly use the value of the JSX object as the DOM element, but in some UIs with deeper nesting levels, it will not look so elegant.
$ref is used as follows:
let ref;
<div $mount='#App'>
Parent
<button $ref={ref}
onclick={console.log(ref.textContent)}
>Click Me!</button>
</div>
Note:
- If you use it immediately after the ref declaration, you will get an undefined. The initialization time of the ref reference is after the created life cycle function. We will introduce the life cycle in subsequent chapters.
- The onclick attribute means adding an event, which can be a js expression or function. It will be introduced in detail in the next chapter.
5.$html attribute
Using the $html
attribute, you can set the html style of a DOM element. It is worth noting that after setting $html, all the child nodes of the DOM element will become invalid.
const html = 'This is <h1>h1 title</h1>';
<div $html={html} $mount='#App'>Internal elements will be invalid</div>;
6.$attributes
The $attributes
attribute is used to aggregate HTML attributes. You can use objects to set attributes in batches, as shown below
const data={
name: 'TestName',
value: 'TestValue',
}
function logAttributes(e){
const attrs = e.target.attributes;
for(let item of attrs){
console.log(`${item.name}=${item.value}`);
}
}
<button $mount='#App'
inner-attr="test"
$attributes={data}
onclick={logAttributes}
>Click Me!</button>
$attributes
also supports passing in string types, using the format of name=value&name=value to pass in strings
let attrStr = 'name=TestName&value=TestValue';
function logAttributes(e){
const attrs = e.target.attributes;
for(let item of attrs){
console.log(`${item.name}=${item.value}`);
}
}
<button $mount='#App'
inner-attr="test"
$attributes={attrStr}
onclick={logAttributes}
>Click Me!</button>
7. Dynamic node
Since the essence of Alins is to directly operate Dom, creating dynamic nodes is also very intuitive. You can just directly mount JSX elements. Here is an example.
let parent, _id = 1;
function addChild(e){
<div $mount={parent}>Dynamic Node {_id++}</div>;
// Or use $mount={e.target.parentElement}
}
<div $ref={parent} style='border: 1px solid #555' $mount='#App'>
<button onclick={addChild}>Add Child</button>
</div>
Note: The _id variable here uses an underscore prefix to identify a static data, otherwise id++ will be identified as calculated data and cause reactive changes