Actions, which are essentially life cycle functions on elements. It can be used in such ways as the following

  • Interconnect with third-party libraries (integrate third-party library functions on components)
  • Lazy loading of images
  • Tooltips
  • Add custom event handlers

Action is essentially just a normal function that takes one argument, which is the DOM node object of the current element

Action is a feature that enhances the capability of components. It has strong encapsulation and reusability, and can split logical code into JS files for repeated application

// The name of the function defining an action is arbitrary
export function movable(node) {
  / /... Code for third-party libraries or custom event handlers

  return {
    destroy() {
      / /... The destroy function is called when the element is cleared,
      // You can do some cleaning here}}}Copy the code
<script>
  import movable from './movable'
</script>

<! -- Using the use directive to apply custom utility functions or third-party libraries to divs -->
<div use:movable>Box</div>
Copy the code
<! -- Can listen for custom events in utility functions -->
<div
  use:movable
  on:movestart={e= >console.log('move start... ', e.detail)} on:moving={e => console.log('moving', e.detail)} on:moveend={() => console.log('move end... ')} >Box</div>
Copy the code
export default function movable(node) {
  let moving = false
  let x, y, left, top
	
  function handleMove(e) {
    if (moving) {
      node.style.left = (e.clientX - x + left) + 'px'
      node.style.top = (e.clientY - y + top) + 'px'
			
      // Send the moving event
      // Use Node.dispatchEvent to send the corresponding event
      // New CustomEvent(type, option) is a native way to create custom events
			node.dispatchEvent(new CustomEvent('moving', {
        detail: { x: e.clientX - x + left, y: e.clientY - y + top }
      }))
    }
  }

  function startMove(e) {
    moving = true
		
    x = e.clientX
    y = e.clientY
		
    left = parseInt(node.style.left) || 0
    top = parseInt(node.style.top) || 0
		
    // Send the MovestArt event
    node.dispatchEvent(new CustomEvent('movestart', { detail: {x:left, y:top}}))
  }
	
  function endMove() {
    moving = false
		
    // Send the moveEnd event
    node.dispatchEvent(new CustomEvent('moveend'))}window.addEventListener('mousemove', handleMove)
  window.addEventListener('mouseup', endMove)
  node.addEventListener('mousedown', startMove)
	
  return {
    destroy() {
      window.removeEventListener('mousemove', handleMove)
      window.removeEventListener('mouseup', endMove)
      node.removeEventListener('mousedown', startMove)
    }
  }
}
Copy the code

Additional parameters

Just like transition and animate, Action supports arguments. The Action function is called with its element.

longpress.js

// The action function takes two arguments
// Parameter 1: the node object bound to the Action
// Parameter 2: the parameter passed when the element bound to the Action is used
export function longpress(node, duration) {
  let timer;
	
  const handleMousedown = () = > {
    timer = setTimeout(() = > {
      node.dispatchEvent(
        new CustomEvent('longpress')); }, duration *1000);
  };
	
  const handleMouseup = () = > clearTimeout(timer);

  node.addEventListener('mousedown', handleMousedown);
  node.addEventListener('mouseup', handleMouseup);

  return {
    destroy() {
      node.removeEventListener('mousedown', handleMousedown);
      node.removeEventListener('mouseup', handleMouseup); }}; }Copy the code
<button
  use:longpress={duration}
  .
>Hold me down</button>
Copy the code
<! In the action function, if you need to pass multiple arguments, you can only pass them into a single object -->
<button
  use:longpress={{duration, spiciness}}
  .
>Hold me down</button>
Copy the code
return {
  destroy() {
    node.removeEventListener('mousedown', handleMousedown);
    node.removeEventListener('mouseup', handleMouseup);
  },
  // The action function is executed when the component is initialized
  // This means that the action function will not be aware of any subsequent changes in the value of the passed parameter
  // You can add the update method to the return object of the action
  // The update method is called whenever an argument changes, passing in the latest value of the argument as an argument
  update(newDuration){ duration = newDuration; }};Copy the code