Compilez Svelte dans votre tête. Partie 1/3

introduction

Rappelons-nous comment nous écrivons des applications Web sans framework:





Créer un élément





//   h1
const h1 = document.createElement('h1');
h1.textContent = 'Hello World';
// ...    body
document.body.appendChild(h1);
      
      



Mettre à jour l'élément





//    h1
h1.textContent = 'Bye World';
      
      



Retirer l'élément





// ,    h1
document.body.removeChild(h1);
      
      



Ajouter des styles à l'élément





const h1 = document.createElement('h1');
h1.textContent = 'Hello World';

//     h1
h1.setAttribute('class', 'abc');

// ...   <style>  head
const style = document.createElement('style');
style.textContent = '.abc { color: blue; }';
document.head.appendChild(style);
document.body.appendChild(h1);
      
      



Écoute des événements de clic sur un élément





const button = document.createElement('button');
button.textContent = 'Click Me!';

//   click
button.addEventListener('click', () => {
  console.log('Hi!');
});

document.body.appendChild(button);
      
      



En JavaScript pur, nous devons écrire quelque chose comme ça.





Le but principal de cet article est de montrer comment le compilateur Svelte convertit la syntaxe Svelte dans les blocs de code que j'ai montrés ci-dessus.





Syntaxe Svelte

Ensuite, je vais vous montrer quelques exemples de syntaxe de base Svelte.





, Svelte .





, Svelte:





<h1>Hello World</h1>
      
      



Svelte REPL





, <style>



:





<style>
  h1 {
    color: rebeccapurple;
  }
</style>

<h1>Hello World</h1>
      
      



Svelte REPL





Svelte HTML, Svelte HTML .





, :





<script>
  let name = 'World';
</script>

<h1>Hello {name}</h1>
      
      



Svelte REPL





JavaScript .





, on:







<script>
  let count = 0;
  function onClickButton(event) {
    console.log(count);
  }
</script>

<button on:click={onClickButton}>Clicked {count}</button>
      
      



Svelte REPL





:





<script>
  let count = 0;
  function onClickButton(event) {
    count += 1;
  }
</script>

<button on:click={onClickButton}>Clicked {count}</button>
      
      



Svelte REPL





Svelte JavaScript, .





Svelte

Svelte , JavaScript.





, Svelte , . , Svelte .





:





<h1>Hello World</h1>
      
      



Svelte REPL





:





function create_fragment(ctx) {
  let h1;

  return {
    c() {
      h1 = element('h1');
      h1.textContent = 'Hello world';
    },
    m(target, anchor) {
      insert(target, h1, anchor);
    },
    d(detaching) {
      if (detaching) detach(h1);
    },
  };
}

export default class App extends SvelteComponent {
  constructor(options) {
    super();
    init(this, options, null, create_fragment, safe_not_equal, {});
  }
}
      
      



2 :





  • create_fragment







  • class App extends SvelteComponent







create_fragment

Svelte - Svelte. Svelte DOM .





create_fragment



Svelte DOM .





create_fragment



. , :





  • c()







create. .





h1



:





h1 = element('h1');
h1.textContent = 'Hello World';
      
      



  • m(target, anchor)







mount. .





h1



target



:





insert(target, h1, anchor);

// http://github.com/sveltejs/svelte/tree/master/src/runtime/internal/dom.ts
export function insert(target, node, anchor) {
  target.insertBefore(node, anchor || null);
}
      
      



  • d(detaching)







destroy. .





h1



DOM :





detach(h1);

// http://github.com/sveltejs/svelte/tree/master/src/runtime/internal/dom.ts
function detach(node) {
  node.parentNode.removeChild(node);
}
      
      



. , .





export default class App extends SvelteComponent

- , API.





, create_fragment. Svelte , .





<h1>



, :





<!-- empty -->
      
      



Svelte REPL





class App extends SvelteComponent {
  constructor(options) {
    super();
    init(this, options, null, null, safe_not_equal, {});
  }
}
      
      



Svelte null



create_fragment



!





init - , Svelte , :





  • , ctx















Svelte create_fragment



DOM.





, this.$$



.





, $$



, . !





Svelte , :





<script>
	let name = 'World';
</script>

<h1>Hello {name}</h1>
      
      



Svelte REPL





:





function create_fragment(ctx) {
  // ...
  return {
    c() {
      h1 = element('h1');
      h1.textContent = `Hello ${name}`;},
    // ...
  };
}
let name = 'World';

class App extends SvelteComponent {
  // ...
}
      
      



:





  • , <script>



    ,





  • h1







, , .





:





<script>
	let name = 'World';
	function update() {
		name = 'Svelte';
	}
</script>

<h1>Hello {name}</h1>
      
      



Svelte REPL





… :





function create_fragment(ctx) {
  return {
    c() {
      h1 = element('h1');
      t0 = text('Hello ');
      t1 = text(/*name*/ ctx[0]);
    },
    m(target, anchor) {
      insert(target, h1, anchor);
      append(h1, t0);
      append(h1, t1);
    },
    p(ctx, [dirty]) {
      if (dirty & /*name*/ 1) set_data(t1, /*name*/ ctx[0]);
    },
    d(detaching) {
      if (detaching) detach(h1);
    },
  };
}

function instance($$self, $$props, $$invalidate) {
  let name = 'World';

  function update() {
    $$invalidate(0, (name = 'Svelte'));
  }

  return [name];
}

export default class App extends SvelteComponent {
  constructor(options) {
    super();
    init(this, options, instance, create_fragment, safe_not_equal, {});
  }
}
      
      



:





  • <h1>



    2 , text (...)







  • create_fragment



    p(ctx, dirty)







  • instance







  • script



    instance







  • , create_fragment



    , ctx[0]







?





Svelte , <script>



.





:





  • ? : count++







  • ? : name = 'Svelte'







  • ? <h1>Hello {name}</h1>







  • ? const i = 1;



    let i = 1;







  • ...





Svelte , (- name = 'Svelte';



), h1



, .





, , p



.





  • p(ctx, dirty)







u_p_date







p(ctx, dirty)



, (dirty



) (ctx



) .





instance

, App



.





instance



.





, , App



, :





<App />
<App />
<App />

<!--  -->
<h1>Hello world</h1>
<h1>Hello world</h1>
<h1>Hello world</h1>
      
      



name



1 , instance



:





<App />
<App />
<App />

<!--   -->
<h1>Hello world</h1>
<h1>Hello Svelte</h1>
<h1>Hello world</h1>
<!--       -->
      
      



instance($$self, $$props, $$invalidate)

instance :













Svelte ctx



.





init



Svelte instance



ctx



:





// ,
const ctx = instance(/*...*/);
const fragment = create_fragment(ctx);

//  
fragment.c();

//    DOM 
fragment.m(target);
      
      



name



name



, ctx



:





t1 = text(/* name */ ctx[0]);
      
      



, ctx



, Map



, . .





$$invalidate

Svelte - $$invalidate



.





,













$$invalidate



:





name = 'Svelte';
count++;
foo.a = 1;

//     
name = 'Svelte';
$$invalidate(/* name */, name);
count++;
$$invalidate(/* count */, count);
foo.a = 1;
$$invalidate(/* foo */, foo);
      
      



$$invalidate



:





// ...
const ctx = instance(/*...*/);
const fragment = create_fragment(ctx);

//  ,   
const dirty = new Set();
const $$invalidate = (variable, newValue) => {
  //  ctx
  ctx[variable] = newValue;

  //    
  dirty.add(variable);

  //    
  scheduleUpdate(component);
};

// ,   
function flushUpdate() {
  //  
  fragment.p(ctx, dirty);

  //    
  dirty.clear();
}
      
      







<script>
	let name = 'world';
	function update() {
		name = 'Svelte';
	}
</script>

<h1 on:click={update}>Hello {name}</h1>
      
      



Svelte REPL





:





function create_fragment(ctx) {
  // ...
  return {
    c() {
      h1 = element('h1');
      t0 = text('Hello ');
      t1 = text(/*name*/ ctx[0]);
    },
    m(target, anchor) {
      insert(target, h1, anchor);
      append(h1, t0);
      append(h1, t1);
      dispose = listen(h1, 'click', /*update*/ ctx[1]);},
    p(ctx, [dirty]) {
      if (dirty & /*name*/ 1) set_data(t1, /*name*/ ctx[0]);
    },
    d(detaching) {
      if (detaching) detach(h1);
      dispose();},
  };
}

function instance($$self, $$props, $$invalidate) {
  let name = 'world';

  function update() {
    $$invalidate(0, (name = 'Svelte'));
  }
  return [name, update];}
// ...
      
      



:





  • instance



    2





  • listen



    mount



    dispose



    destroy







, instance



, .





update



, instance



ctx



.





Svelte JavaScript, , .





listen dispose

, , Svelte , DOM.





,





<h1
	on:click={update}
	on:mousedown={update}
	on:touchstart={update}>
  Hello {name}!
</h1>
      
      



Svelte REPL





:





// ...
dispose = [
  listen(h1, 'click', /*update*/ ctx[1]),
  listen(h1, 'mousedown', /*update*/ ctx[1]),
  listen(h1, 'touchstart', /*update*/ ctx[1], { passive: true }),
];
// ...
run_all(dispose);
      
      



, Svelte :





//   
dispose1 = listen(h1, 'click', /*update*/ ctx[1]);
dispose2 = listen(h1, 'mousedown', /*update*/ ctx[1]);
dispose2 = listen(h1, 'touchstart', /*update*/ ctx[1], { passive: true });
// ...
dispose1();
dispose2();
dispose3();
      
      



, .





, , Svelte JavaScript. Svelte dispose



, .





Svelte - HTML.





Svelte, JavaScript .





3 :





1. create_fragment





  • , DOM .





2. instance





  • , <script>



    , .





  • , .





  • $$invalidate







3. class App extends SvelteComponent





  • create_fragment



    instance











  • API





Svelte JavaScript, :





  • h1



    ,





  • create_fragment



    instance



    ,





  • dispose



    , .





  • ...





, Svelte .






:





Rejoignez la communauté russophone Svelte sur Telegram - @sveltejs . Vous pouvez y trouver de l'aide ou des conseils sur presque tous les problèmes, ainsi que discuter des sujets les plus urgents. Si vous n'avez pas le temps de discuter, abonnez-vous à la chaîne @sveltejs_public pour des nouvelles et des documents utiles sur Svelte.





J'espère que ce matériel vous a été utile!








All Articles