introduce

Riot. Mount is the entry function that Riot uses to load the contents of the template, render the DOM with incoming data, and update it to the page.

usage

The most common usage:

  • selector(string) style selector, id, class name, label selector
  • tagName(string) The name of the template file that needs to be loaded. Note that this is not the name of the file, but the name of the top-level tag in the template content.

  • opts(object) Data passed in, like react props, [] for optional

demo

Start with the simplest demo(note that necoo-Loader analysis is used here):

Todo. The content of the tag:

<todo h="1">
    <div class="{cls}">{name}: {desc}{console.log('hello world')} {myFunc()}</div>
    // logic comes here
    let self = this;
    self.desc = 'nice';
    self.name = 'HongRunhui'
    self.myFunc = function () {
        console.log('hello');
    };
    self.cls = 'content';
    function beforeBeforeMount() {
        window.necooPush(arguments);
    }
    beforeBeforeMount();
    self.on('before-mount'.function myBeforeMount() {
        window.necooPush(arguments);
    });
    self.on('mount'.function myMount() {
        window.necooPush(arguments);
    });
    self.on('update'.function myUpdate() {
        window.necooPush(arguments);
    });
    self.on('updated'.function myUpdated() {
        window.necooPush(arguments);
    });
</todo>
Copy the code

Execution trajectory diagram:

Phenomenon analysis:

The yellow arrows are the hook function buried in todo.tag above. You can see that beforeBeforeMount is earlier than myBeforeMount, and myMount is later than myBeforeMount. So the lifecycle function in Riot looks like this:

  • before-before-mount(There’s no such thing, I’m using it to refer to functions written directly inside script tags.)
  • before-mount
  • mount

And found that self.on(‘update’) and self.on(‘updated’) were not triggered during mount;

Code analysis:

To make things easier for you, LET me give you a simple explanation of some of the more important functions outlined above:

  • mountThe entry function
    • ?Select the parent element to be loaded into
    • pushTagsToA function that contains recursion will? Is used to load the tag in a loop
    • mount$1Start to actually load a specific template tag
      • createTagCreate a new tag instance based on the __IMPL_ cached template information
        • componentMountOnce the tag instance is created, start updating the tag instance into the DOM
          • parseAttributesparsing?Attributes on the selected parent element and saved to the Tag instance
          • walAttributesParse attrs attributes already parsed in the __IMPL_ template (such as those on todo tags) and save them to the Tag instance
          • parseAttributesParses the properties obtained in the previous step and, if there are expressions, throws them into an array of expressions and saves them, if not, synchronizes them?On the selected parent element.
          • updateOptsUpdate the incoming OPTS
          • mixinwindow.__global_mixinIs bound to the Tag instance.
          • beforeBeforeMountExecute the js in script, which is the data we write in todo.taglet self = this; This. MyLists = [1, 2, 3]MyLists are bound to the tag instance.
          • myBeforeMountIf this is being listened for, the corresponding function will be fired
          • parseExpressionsContains in the template by iterating through the template’s HTML nodes{title}Such expressions are parsed and stored in an expression array variableexpressionsIn the
            • componentUpdateParse the expressions array above, usingnew FunctionTo get the variable values on the tag instance, generate a string template that eventually contains the data, insert it into the DOM, and finally insert the DOM into?The parent element that was selected.

The above is the general process.

{xxx}

= >

Hello

How did this template syntax end up being replaced with data?

Here’s an example:

<div class="{cls}">{name}: {desc}{console.log('hello world')} {myFunc()}</div>
Copy the code

The contents of the div are processed into this function and executed to read variables on the tag instance.

(function anonymous(E) {
    return [
        function _anonymous_15(v) {
            window.necooPush(arguments);
            v = (("name"in this ? this : window).name);
            return v || v === 0 ? v : ""
        }.call(this),":".function _anonymous_15(v) {
            window.necooPush(arguments);
            v = (("desc"in this ? this : window).desc);
            return v || v === 0 ? v : ""
        }.call(this),
        function _anonymous_15(v) {
            window.necooPush(arguments);
            try {
                v = ("console"in this ? this : window).console.log('hello world')}catch (e) {
                E(e, this)};return v || v === 0 ? v : ""
        }.call(this),
        "".function _anonymous_15(v) {
            window.necooPush(arguments);
            try {
                v = ("myFunc"in this ? this : window).myFunc()
            } catch (e) {
                E(e, this)};return v || v === 0 ? v : ""
        }.call(this)
    ].join("");
})

Copy the code