// https://play.vuejs.org/#eNqdVE2P2jAQ/SsjXwCJBlXtic2itohDK7W72u7Rl5BMwItjW7bDUiH+e8d2krJbRNXlgOyZN1/Pb3Jkn43J9i2yOctdaYXx4NC3ZsGVaIy2Ho5gsZ5C6/ARGyMLjw9YwwlqqxsYUehogH7XVSE7RzaLt5CbAKVWzkMTLCH69lW68Si6RpMbrvJZ6oM6oIvvQHS7LywqD/nawoyut3//Bl++br3XCj6VUpS7W876ypk2qMYTzhZ3dEgN57OEvhpXSu0wBi7D6UJkqNz9b7suEh9EX5+Js+SYDWOxKfOO2KnFJntyWtE7HLkC4KzUjRES7Z3xgtjjbA7RE3yFlPr5W7R52+K0t5dbLHcX7E/uEGyc3Vt0aPfI2eDzhd2gT+7Vzx94oPPgpK5bSegrzgd0WrahxwT70qqK2j7DxW6/RokItXl0q4NH5fqhQqMBeYp4zkgwyyuj/2n3Q/YxxnF1IhYHtQUln6kGYLkVsoJxBEzeJp//VM0/xVKJPezfua1+JrRwIStJo5SFc2SI8KVWxBINukgq6u75jGJfSijuyZXdfbWr/TKmsrSKBBnXhXQ44apuVRk4hzRxoj0hs30hWyR8eDAg0s/Q3cAX4TF1wnNVYS0Urg4m4I+xyjRFw4nKv9x953/J9ITZOSW9FkxRVaSnOby32NzAuih3G6tJfXMwsm3oUxJQDelFqA7U6YXKxNTs9BvEAbCg
// Parent
<script setup>
import { ref, useTemplateRef } from 'vue'
import Modal from './Modal.vue'
const modalRef = useTemplateRef('modal');
</script>
<template>
Parent <br />
=================== <br />
<button @click="modalRef.open()">Open Modal</button>
<button @click="modalRef.close()">Close Modal</button>
<br /><br /><hr />
<Modal ref="modal" />
</template>
// Child - Modal
<template>
Child (Modal) <br />
=================== <br />
<button @click="open()">Open Modal</button>
<button @click="close()">Close Modal</button>
<div v-show="isOpen" class="ModalContent">Modal Content</div>
</template>
<script setup>
import { ref } from 'vue'
const isOpen = ref(false)
function open() {
isOpen.value = true
}
function close() {
isOpen.value = false
}
defineExpose({ open, close })
</script>
<style>
.ModalContent {
padding: 1rem; background: plum;
margin: 1rem;
}
</style>
const showThumbs = (() => {
// really private ;-)
const state = ref(props.enableThumbs)
return computed({
get: () => state.value,
set: value => {
state.value = value
}
})
})()
/*
-----------------------------------
Nejčastější použití je právě pro:
- Vytvoření privátního scope
- Enkapsulaci dat a logiky
- Vyhnutí se globálnímu scope
- Zachování stavu přes closure
-----------------------------------
* 1. Vytvoření privátního scope
* - proměnné uvnitř neuniknou ven
* - čisté API pro vnější svět
*/
const counter = (() => {
let count = 0 // privátní proměnná
return {
increment() { count++ },
getCount() { return count }
}
})()
/**
* 2. Vyhnutí se globálnímu scope
* - dočasné proměnné zůstanou lokální
* - neznečišťuje globální namespace
*/
(() => {
const temp = 'nějaká dočasná proměnná'
// temp existuje jen uvnitř, neznečišťuje globální scope
})()
/**
* 3. Modulární pattern
* - privátní metody a proměnné
* - veřejné API
*/
const module = (() => {
const privateVar = 'private'
const privateMethod = () => {
console.log(privateVar)
}
return {
publicMethod() {
privateMethod() // má přístup k privátním věcem
}
}
})()
/**
* 4. Closure pro zachování stavu
* - privátní stav
* - reaktivní hodnota
*/
const showThumbs = (() => {
const state = ref(props.enableThumbs) // privátní stav
return computed({
get: () => state.value,
set: (value) => {
state.value = value
}
})
})()
/**
* 5. Vyhnutí se konfliktům
* - lokální aliasy
* - izolace kódu
*/
(() => {
const $ = jQuery // lokální alias pro jQuery
// používání $ uvnitř neovlivní jiné knihovny používající $
})()
/**
* 6. Inicializace
* - nastavení při načtení
* - konfigurace
* - event listenery
*/
(() => {
// nějaká inicializace
const config = {
apiKey: 'xxx',
endpoint: 'https://api.example.com'
}
// nastavení event listenerů
document.addEventListener('DOMContentLoaded', () => {
// inicializace UI
})
// další setup
const init = () => {
// ...
}
init()
})()
/*
@source: https://javascript.plainenglish.io/50-javascript-shortcuts-that-will-make-you-a-code-wizard-in-2025-14dd7aee319c
*/
// 1. Ternary Operator
const status = loggedIn ? "Welcome!" : "Please login.";
// 2. Default Parameters
function greet(name = "Stranger") {
return `Hello, ${name}`;
}
// 3. Arrow Functions
const multiply = (a, b) => a * b;
// 4. Destructuring Objects
const { title, year } = movie;
// 5. Destructuring Arrays
const [first, second] = topResults;
// 6. Template Literals
const greeting = `Hey, ${user.name}!`;
// 7. Spread Operator
const newTeam = [...oldTeam, "Alice"];
// 8. Rest Parameters
function logAll(...args) {
console.log(args);
}
// 9. Optional Chaining
const city = user?.address?.city;
// 10. Nullish Coalescing
const nickname = inputName ?? "Anonymous";
// 12. Logical OR Assignment
settings.volume ||= 50;
// 13. Logical AND Assignment
user.isAdmin &&= false;
// 14. Object Property Shorthand
const age = 24;
const person = { name, age };
// 15. Computed Property Names
const field = "score";
const stats = { [field]: 100 };
// 16. For-of Loop
for (const char of name) {
console.log(char);
}
// 17. forEach
tags.forEach(tag => console.log(`#${tag}`));
// 18. map()
const lengths = names.map(n => n.length);
// 19. filter()
const passed = grades.filter(g => g >= 60);
// 20. reduce()
const sum = numbers.reduce((a, b) => a + b, 0);
// 21. includes()
if (items.includes("🚀")) launch();
// 22. Unique Array with Set
const unique = [...new Set(tags)];
// 23. Object.entries()
Object.entries(data).forEach(([k, v]) => console.log(k, v));
// 24. Object.values()
const values = Object.values(config);
// 25. Object.keys()
const keys = Object.keys(settings);
// 26. Array Method Chaining
data.filter(a => a.active).map(a => a.name);
// 27. Flatten Arrays
const flat = nested.flat(2);
// 28. String.trim()
const cleaned = input.trim();
// 29. padStart()
const padded = id.padStart(5, "0");
// 30. Format Numbers
const price = new Intl.NumberFormat().format(1234567);
// 31. Dynamic Import
const module = await import("./utils.js");
// 32. Promise.all()
await Promise.all([loadUser(), loadPosts()]);
// 33. Async/Await
const getData = async () => {
const res = await fetch(url);
return await res.json();
};
// 34. Optional Function Params
function log(message, level = "info") {
console[level](message);
}
// 35. Number Conversion with +
const num = +"42";
// 36. Boolean Conversion with !!
const isValid = !!userInput;
// 37. Swap Values
[a, b] = [b, a];
// 38. String to Array
const chars = [..."dev"];
// 39. Clone Object
const copy = { ...original };
// 40. Debounce
const debounce = (fn, delay) => {
let timeout;
return (...args) => {
clearTimeout(timeout);
timeout = setTimeout(() => fn(...args), delay);
};
};
// 41. Named Capture Groups in Regex
const url = "https://dev.to";
const match = url.match(/(?<protocol>https?):\/\/(?<host>.+)/);
console.log(match.groups);
// 42. ??= Operator
data.username ??= "guest";
// 43. Numeric Separators
const big = 1_000_000_000;
// 44. Top-Level await (in modules)
const user = await fetchUser();
// 45. Array.from with Map
const numbers = Array.from(new Set([1, 2, 2, 3]));
// 46. Group Array by Property
const grouped = data.reduce((acc, obj) => {
acc[obj.type] = acc[obj.type] || [];
acc[obj.type].push(obj);
return acc;
}, {});
// 47. isFinite()
if (isFinite(num)) { /* safe to use */ }
// 48. Abort Fetch Request
const controller = new AbortController();
fetch(url, { signal: controller.signal });
controller.abort();
// 49. toLocaleString()
(1234567.89).toLocaleString("en-US", {
style: "currency",
currency: "USD"
});
// 50. StructuredClone
const clone = structuredClone(myObj);
const user = { name: "Alice", age: 30 };
// 1. for...in loop - iteruje přes všechny enumerable vlastnosti
console.log("1. for...in loop:");
for (let key in user) {
console.log(`${key}: ${user[key]}`);
}
// 2. Object.keys() - vrací pole klíčů
console.log("\n2. Object.keys():");
Object.keys(user).forEach(key => {
console.log(`${key}: ${user[key]}`);
});
// 3. Object.values() - vrací pole hodnot
console.log("\n3. Object.values():");
Object.values(user).forEach(value => {
console.log(value);
});
// 4. Object.entries() - vrací pole párů [klíč, hodnota]
console.log("\n4. Object.entries():");
Object.entries(user).forEach(([key, value]) => {
console.log(`${key}: ${value}`);
});
// 5. Object.entries() s for...of
console.log("\n5. Object.entries() s for...of:");
for (let [key, value] of Object.entries(user)) {
console.log(`${key}: ${value}`);
}
// 6. Object.keys() s for...of
console.log("\n6. Object.keys() s for...of:");
for (let key of Object.keys(user)) {
console.log(`${key}: ${user[key]}`);
}
// 7. Object.getOwnPropertyNames() - včetně non-enumerable vlastností
console.log("\n7. Object.getOwnPropertyNames():");
Object.getOwnPropertyNames(user).forEach(key => {
console.log(`${key}: ${user[key]}`);
});
// 8. Reflect.ownKeys() - všechny vlastnosti včetně Symbolů
console.log("\n8. Reflect.ownKeys():");
Reflect.ownKeys(user).forEach(key => {
console.log(`${key}: ${user[key]}`);
});
// 9. Map() pro transformaci
console.log("\n9. Map() pro transformaci:");
const transformed = Object.entries(user).map(([key, value]) => `${key.toUpperCase()}: ${value}`);
console.log(transformed);
// 10. Reduce() pro akumulaci
console.log("\n10. Reduce() pro akumulaci:");
const result = Object.entries(user).reduce((acc, [key, value]) => {
acc[key.toUpperCase()] = value;
return acc;
}, {});
console.log(result);
// 11. Filter() pro filtrování
console.log("\n11. Filter() pro filtrování:");
const filtered = Object.entries(user).filter(([key, value]) => typeof value === 'string');
console.log(filtered);
// 12. Some() a Every() pro testování
console.log("\n12. Some() a Every():");
const hasString = Object.values(user).some(value => typeof value === 'string');
const allStrings = Object.values(user).every(value => typeof value === 'string');
console.log(`Obsahuje string: ${hasString}`);
console.log(`Všechny jsou stringy: ${allStrings}`);
// 13. JSON.stringify() s replacer funkcí
console.log("\n13. JSON.stringify() s replacer:");
JSON.stringify(user, (key, value) => {
if (key !== '') console.log(`${key}: ${value}`);
return value;
});
// 14. Object.hasOwnProperty() check
console.log("\n14. for...in s hasOwnProperty:");
for (let key in user) {
if (user.hasOwnProperty(key)) {
console.log(`${key}: ${user[key]}`);
}
}
// 15. Destrukturování s rest operátorem
console.log("\n15. Destrukturování:");
const { name, ...rest } = user;
console.log(`name: ${name}`);
console.log('zbytek:', rest);
// 16. Použití s async/await (pokud by byly hodnoty Promise)
console.log("\n16. Async iterace (příklad):");
async function asyncIteration() {
for (let [key, value] of Object.entries(user)) {
// Simulace async operace
await new Promise(resolve => setTimeout(resolve, 100));
console.log(`Async: ${key}: ${value}`);
}
}
// asyncIteration(); // odkomentuj pro spuštění
const user = { name: "Alice", age: 30 };
// 1. for...in loop - iteruje přes všechny enumerable vlastnosti
console.log("1. for...in loop:");
for (let key in user) {
console.log(`${key}: ${user[key]}`);
}
// 2. Object.keys() - vrací pole klíčů
console.log("\n2. Object.keys():");
Object.keys(user).forEach(key => {
console.log(`${key}: ${user[key]}`);
});
// 3. Object.values() - vrací pole hodnot
console.log("\n3. Object.values():");
Object.values(user).forEach(value => {
console.log(value);
});
// 4. Object.entries() - vrací pole párů [klíč, hodnota]
console.log("\n4. Object.entries():");
Object.entries(user).forEach(([key, value]) => {
console.log(`${key}: ${value}`);
});
// 5. Object.entries() s for...of
console.log("\n5. Object.entries() s for...of:");
for (let [key, value] of Object.entries(user)) {
console.log(`${key}: ${value}`);
}
// 6. Object.keys() s for...of
console.log("\n6. Object.keys() s for...of:");
for (let key of Object.keys(user)) {
console.log(`${key}: ${user[key]}`);
}
// 7. Object.getOwnPropertyNames() - včetně non-enumerable vlastností
console.log("\n7. Object.getOwnPropertyNames():");
Object.getOwnPropertyNames(user).forEach(key => {
console.log(`${key}: ${user[key]}`);
});
// 8. Reflect.ownKeys() - všechny vlastnosti včetně Symbolů
console.log("\n8. Reflect.ownKeys():");
Reflect.ownKeys(user).forEach(key => {
console.log(`${key}: ${user[key]}`);
});
// 9. Map() pro transformaci
console.log("\n9. Map() pro transformaci:");
const transformed = Object.entries(user).map(([key, value]) => `${key.toUpperCase()}: ${value}`);
console.log(transformed);
// 10. Reduce() pro akumulaci
console.log("\n10. Reduce() pro akumulaci:");
const result = Object.entries(user).reduce((acc, [key, value]) => {
acc[key.toUpperCase()] = value;
return acc;
}, {});
console.log(result);
// 11. Filter() pro filtrování
console.log("\n11. Filter() pro filtrování:");
const filtered = Object.entries(user).filter(([key, value]) => typeof value === 'string');
console.log(filtered);
// 12. Some() a Every() pro testování
console.log("\n12. Some() a Every():");
const hasString = Object.values(user).some(value => typeof value === 'string');
const allStrings = Object.values(user).every(value => typeof value === 'string');
console.log(`Obsahuje string: ${hasString}`);
console.log(`Všechny jsou stringy: ${allStrings}`);
// 13. JSON.stringify() s replacer funkcí
console.log("\n13. JSON.stringify() s replacer:");
JSON.stringify(user, (key, value) => {
if (key !== '') console.log(`${key}: ${value}`);
return value;
});
// 14. Object.hasOwnProperty() check
console.log("\n14. for...in s hasOwnProperty:");
for (let key in user) {
if (user.hasOwnProperty(key)) {
console.log(`${key}: ${user[key]}`);
}
}
// 15. Destrukturování s rest operátorem
console.log("\n15. Destrukturování:");
const { name, ...rest } = user;
console.log(`name: ${name}`);
console.log('zbytek:', rest);
// 16. Použití s async/await (pokud by byly hodnoty Promise)
console.log("\n16. Async iterace (příklad):");
async function asyncIteration() {
for (let [key, value] of Object.entries(user)) {
// Simulace async operace
await new Promise(resolve => setTimeout(resolve, 100));
console.log(`Async: ${key}: ${value}`);
}
}
// asyncIteration(); // odkomentuj pro spuštění
// https://www.reddit.com/r/tailwindcss/comments/1icfwbo/here_are_10_tailwind_tricks_shared_by_shadcn_they/
// https://x.com/shadcn/status/1842329158879420864
// 1. Dynamic CSS Variables in Tailwind
<div style={{ "--width": isCollapsed ? "8rem" : "14rem" }} className="w-[--width] transition-all" />
// 2. Data Attribute State Management
<div
data-state={isOpen ? "open" : "closed"}
className="data-[state=open]:bg-blue-500"
/>
// 3. Nested SVG Controll
<div
data-collapsed={isCollapsed}
className="[&[data-collapsed=true]_svg]:rotate-180"
>
<svg>...</svg>
</div>
// 4. Parent-Child Style Inheritance
<section :data-collapsed="isCollapsed"
<div className="[[data-collapsed=true]_&]:rotate-180">
{/* Child inherits rotation when parent has data-collapsed=true */}
</div>
</section>
// 5. Group Data States
<div className="group" data-collapsed={isCollapsed}>
<div className="group-data-[collapsed=true]:rotate-180"/>
</div>
// 6. Data Slots
<div className="data-[slot=action]:*:hover:mr-0">
<div data-slot="action" class="-mr-10">...</div>
</div>
// 7. Peer Element Control
<button className="peer" :data-active="isActive">Menu</button>
<div className="peer-data-[active=true]:bg-blue-500"/>
// 8. Named Group Focus
<div className="group/menu">
<button className="group-focus-within/menu:bg-blue-500"/>
</div>
// 9. Group Has Selectors
<div className="group/menu">
<div className="group-has-[[data-active=true]]/menu:bg-blue-500"/>
</div>
// 10. Variant Props
<button
data-variant={variant}
className="data-[variant=ghost]:border-blue-500"
/>
<!--
https://jsbin.com/bihofirugo/2/edit?html,css,output
-->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<div class="container">
<img src="https://picsum.photos/id/237/200/300" alt="Foto 1">
<img src="https://picsum.photos/id/237/200/300" alt="Foto 1">
<img src="https://picsum.photos/id/237/200/300" alt="Foto 1">
<img src="https://picsum.photos/id/237/200/300" alt="Foto 1">
<img src="https://picsum.photos/id/237/200/300" alt="Foto 1">
<img src="https://picsum.photos/id/237/200/300" alt="Foto 1">
<img src="https://picsum.photos/id/237/200/300" alt="Foto 1">
<img src="https://picsum.photos/id/237/200/300" alt="Foto 1">
</div>
<style>
.container {
white-space: nowrap;
overflow-x: auto;
cursor: grab;
user-select: none; /* Zabrání výběru textu nebo obrázků při tažení */
}
.container img {
display: inline-block;
width: 200px;
height: 150px;
pointer-events: none; /* Zabrání interakci s obrázky (např. drag-and-drop obrázků) */
}
.container.grabbing {
cursor: grabbing;
}
</style>
<script>
const container = document.querySelector('.container');
let isDragging = false;
let startX;
let scrollLeft;
container.addEventListener('mousedown', (e) => {
isDragging = true;
container.classList.add('grabbing');
startX = e.pageX - container.offsetLeft;
scrollLeft = container.scrollLeft;
e.preventDefault(); // Zabrání výchozímu chování (např. výběr textu)
});
container.addEventListener('mousemove', (e) => {
if (!isDragging) return;
e.preventDefault(); // Zabrání výchozímu chování při pohybu
const x = e.pageX - container.offsetLeft;
const walk = (x - startX) / 0.5; // Rychlost scrollování
container.scrollLeft = scrollLeft - walk;
});
container.addEventListener('mouseup', () => {
isDragging = false;
container.classList.remove('grabbing');
});
container.addEventListener('mouseleave', () => {
if (isDragging) {
isDragging = false;
container.classList.remove('grabbing');
}
});
// Pro jistotu přidáme globální posluchač na mouseup, aby se tažení ukončilo i mimo kontejner
document.addEventListener('mouseup', () => {
if (isDragging) {
isDragging = false;
container.classList.remove('grabbing');
}
});
</script>
</body>
</html>
// 1 Když neobalíš objekt do reactive():
const filtersStorage = {
priceValue: computed({
get: () => selectedFilters.value.priceValue,
set: v => selectedFilters.value.priceValue = +v
})
}
// Pak filtersStorage.priceValue je přímo ComputedRef objekt. A ComputedRef se chová jako ref - musíš použít .value pro přístup k hodnotě:
// Bez reactive() wrapper
filtersStorage.priceValue.value // ✅ musíš použít .value
// 2
// Když obalíš objekt do reactive():
const filtersStorage = reactive({
priceValue: computed(...)
})
// S reactive() wrapper
filtersStorage.priceValue // ✅ .value se přidá automaticky
/*
Proč se to děje?
reactive() má speciální chování - automaticky unwrapuje refs na prvním levelu objektu
Tohle je záměrné chování pro lepší DX (developer experience)
Bez reactive() wrapper pracuješ přímo s ComputedRef objektem
*/
// Noob
const eventHandler = e => {
if (e.key === 'Escape') {
this.closeGallery()
}
if (e.key === 'ArrowLeft') {
this.prevMedia()
}
if (e.key === 'ArrowRight') {
this.nextMedia()
}
}
// Profi
const eventHandler = e => {
const keyActions = {
Escape: closeGallery,
ArrowLeft: prevMedia,
ArrowRight: nextMedia
}
keyActions[e.key]?.()
}