/ Gists

Gists

On gists

Editor config (VSCode)

Config files

.editorconfig.js #

root = true

[*.php]
indent_size = 4
indent_style = tab

[*.js]
indent_size = 2
indent_style = space

[*.vue]
indent_size = 2
indent_style = space

On gists

Ignore scanning (JS ...)

Config files

jsconfig.json #

{
  "exclude": [
    ".git",
    "vendor",
    ".app-cache",
    ".npm",
    "www",
    ".npm-tmp",
    "dist",
    "dist*",
    "node_modules",
    "subfolder/dist",
    "subfolder/node_modules",
    "**/dist/*",
    "**/node_modules/*"
  ]
}

On gists

.Prettierrc

Config files

.prettierrc #

{
  "semi": false,
  "singleQuote": true,
  "useTabs": false,
  "trailingComma": "none",
  "printWidth": 160,
  "arrowParens": "avoid"
}


/* another languages or files */
https://prettier.io/docs/en/options.html
https://prettier.io/docs/en/configuration.html#configuration-overrides





On gists

Loops speed comparision

JavaScript

loops.js #

const numbers = [...Array(10000000)].map(
  (_, index) => index + 1
);
function measurePerf(label, method) {
  console.time(label);
  method();
  console.timeEnd(label);
}
measurePerf('filter', () => {
  const evens = numbers.filter((num) => num % 2 === 0);
});
measurePerf('forEach', () => {
  const evens = [];
  numbers.forEach((num) => {
    if (num % 2 === 0) {
      evens.push(num);
    }
  });
});
measurePerf('for...of', () => {
  const evens = [];
  for (const num of numbers) {
    if (num % 2 === 0) {
      evens.push(num);
    }
  }
});
measurePerf('for', () => {
  const evens = [];
  for (let i = 0; i < numbers.length; i++) {
    const num = numbers[i];
    if (num % 2 === 0) {
      evens.push(num);
    }
  }
});

On gists

Download file via JavaScript

JavaScript

download.js #

// https://javascript.plainenglish.io/how-to-download-a-file-using-javascript-fec4685c0a22

function downloadFile(url, fileName) {
  fetch(url, { method: 'get', mode: 'no-cors', referrerPolicy: 'no-referrer' })
    .then(res => res.blob())
    .then(res => {
      const aElement = document.createElement('a');
      aElement.setAttribute('download', fileName);
      const href = URL.createObjectURL(res);
      aElement.href = href;
      aElement.setAttribute('target', '_blank');
      aElement.click();
      URL.revokeObjectURL(href);
    });
};


downloadFile('https://www.google-analytics.com/analytics.js', 'gooleAnalytics.js')

On gists

Handle Multiple Promises using Async/Await

Vue.js

examples.js #

// https://medium.com/@matodev/handle-multiple-promises-using-async-await-1a05b26dafba

// The wrong and slow way

userIDs = ['fooID1', 'fooID2', ...]
const slowMethod = async (userIDs) => {
    const results = [];
    for (let i = 0; i < userIDs.length; i++) {
        const res = await fetch(`https://api.foo.com/users?uid=${userIDs[i]}`)
        const data = await res.json()
        results.push(data);
    }
    return results;
}
await slowMethod(); //O(n) time



// ✔️ The Fast Way

userIDs = ['fooID1', 'fooID2', ...]
const fastCleanMethod = async (userIDs) => {
    const promises = userIDs.map(async userID => {
        const res = await fetch(`https://api.foo.com/users?uid=${userID}`);
        return await res.json();
    });
    return await Promise.all(promises);
}
await fastCleanMethod(); //O(1) time



// ❌ Fast but Fails Slow

const getUserData = async (userIDs) => {
    const userDataPromise = fetch(`https://api.foo.com/users?uid=${userID}`);
    const userEntriesPromise = fetch(`https://api.foo.com/entries?uid=${userID}`);

    const [userDataRes, userEntriesRes] = [(await userDataPromise).json(), (await userEntriesPromise).json()];
    const [userData, userEntries] = [await userDataRes, await userEntriesRes];
    return {
        ...userData,
        userEntries,
    }
}


// ✔️ Fast and Fails Fast

const getUserData = async (userIDs) => {
    const userDataPromise = fetch(`https://api.foo.com/users?uid=${userID}`);
    const userEntriesPromise = fetch(`https://api.foo.com/entries?uid=${userID}`);

    const [userDataRes, userEntriesRes] = await Promise.all([userDataPromise, userEntriesPromise]);
    const [userData, userEntries] = await Promise.all([userDataRes.json(), userEntriesRes.json()]);
    return {
        ...userData,
        userEntries,
    }
}

On gists

Composable simple storage

Vue.js

example.js #

// src/composables/counter.js
import { computed, readonly, ref } from 'vue';

const count = ref(0);
const next = computed(() => count.value + 1);
const plusOne = () => { count.value += 1 };

export function useCounter() {
  return {
    count: readonly(count),
    next,
    plusOne,
  };
}

On gists

Simple dragging

Vue.js

example.js #

// https://codesandbox.io/s/crimson-sky-7zozs?file=/src/main.js&ck_subscriber_id=1584215866&utm_source=convertkit&utm_medium=email&utm_campaign=%F0%9F%94%A5+%28%2366%29+Multiple+v-models+%28and+4+bonus+tips%21%29+-+8426354

<template>
  <div class="drag-container">
    <img
      alt="Vue logo"
      src="./assets/logo.png"
      :style="{
        left: `${x}px`,
        top: `${y}px`,
        cursor: dragging ? 'grabbing' : 'grab',
      }"
      draggable="false"
      @mousedown="dragging = true"
    />
  </div>
</template>

<script>
import { ref } from "vue";

export default {
  setup() {
    const dragging = ref(false);
    const mouseX = ref(0);
    const mouseY = ref(0);
    const x = ref(100);
    const y = ref(100);

    window.addEventListener("mousemove", (e) => {
      if (dragging.value) {
        const diffX = e.clientX - mouseX.value;
        const diffY = e.clientY - mouseY.value;
        x.value += diffX;
        y.value += diffY;
      }
      mouseX.value = e.clientX;
      mouseY.value = e.clientY;
    });

    window.addEventListener("mouseup", () => {
      dragging.value = false;
    });

    return {
      x,
      y,
      dragging,
    };
  },
};
</script>

<style scoped>
.drag-container {
  width: 100vw;
  height: 100vh;
}

img {
  cursor: grab;
  position: relative;
}
</style>

On gists

Dynamic classes

Vue.js

examples.js #

<div :class="disabled && 'disabled-component'"></div>

<div :class="disabled ? 'disabled-component' : 'not-yet-disabled'"></div>

<div
  :class="{
    primary: isPrimary,
    secondary: isSecondary,
    tertiary: isTertiary,
  }"
/>

<div
  :class="[
    isPrimary && 'primary',
    isSecondary && 'secondary',
    isTertiary && 'tertiary',
  ]"
/>

<div :class="computedClasses" />

<div :class="[computedClasses, { 'active': isActive }]"></div>


const computedClasses = computed(() => ({
  'text-red': isError.value,
  'text-green': isSuccess.value,
  'font-bold': shouldBeBold.value
}))

// or
const computedClasses = computed(() => [
  isError.value && 'text-red',
  isSuccess.value && 'text-green',
  shouldBeBold.value && 'font-bold'
].filter(Boolean))

On gists

Play/Pause video on scroll

JavaScript

on-scroll.js #

    window.addEventListener("load", videoScroll);
    window.addEventListener("scroll", videoScroll);

    function videoScroll() {
      if (document.querySelectorAll("video[autoplay]").length > 0) {
        let windowHeight = window.innerHeight,
            videoEl = document.querySelectorAll("video[autoplay]");

        for (let i = 0; i < videoEl.length; i++) {
          let thisVideoEl = videoEl[i],
              videoHeight = thisVideoEl.clientHeight,
              videoClientRect = thisVideoEl.getBoundingClientRect().top;

          if (videoClientRect <= windowHeight - videoHeight * 0.5 && videoClientRect >= 0 - videoHeight * 0.5) {
            thisVideoEl.play();
          } else {
            thisVideoEl.pause();
          }
        }
      }
    }