Install and initialize MSW v1.2.3 in Angular
mockServiceWorker.js file in the source directory.npm install msw@1.2.3
npx msw init src/ --savewebsite·Indexed 30 days ago
https://christyoung.github.io/notions/A collection of personal technical notes and tips covering front-end development, including CSS layout techniques, JavaScript utilities, React key usage, Vue 3 with TypeScript and Vite, Angular library construction, RxJS operators, and VS Code configurations.
mockServiceWorker.js file in the source directory.npm install msw@1.2.3
npx msw init src/ --save// Password length between 6 and 18 digits
const passwordLengthRegex = /^\d{6,18}$/;
// Ensure password contains both letters and numbers
const passwordCharRegex = /[A-Za-z]+[0-9]/;
// String consisting only of alphanumeric characters or underscores
const alphanumericRegex = /^\w+$/;
// Only Chinese characters
const chineseRegex = /^[\u4e00-\u9fa5]{0,}$/;.start() in the application's entry point (main.ts).// main.ts
import { worker } from './mock/browser';
worker.start();input event may trigger while the user is still selecting a word from a candidate list, before the text is actually committed to the field. To ensure the input event only triggers after the final text is entered, use compositionstart and compositionend events to create a lock.var node = document.querySelector('#person');
var cpLock = false;
// Lock when composition starts (e.g., typing in Chinese IME)
node.addEventListener('compositionstart', function() {
cpLock = true;
});
// Unlock when composition ends (text is committed)
node.addEventListener('compositionend', function() {
cpLock = false;
});
// Only execute logic if the user is not currently composing text
node.addEventListener('input', function() {
if (!cpLock) {
console.log(this.value);
}
});overflow-x: auto from triggering a scrollbar. To maintain the fixed width of child elements and enable horizontal scrolling when the total width exceeds the parent container, set flex-shrink: 0 on the child elements..container {
display: flex;
width: 100%;
height: 600px;
background: green;
overflow-x: auto; /* Enables horizontal scrolling */
}
.chzn-choices {
width: 20%;
height: 200px;
background: red;
flex-shrink: 0; /* Prevents the item from shrinking, forcing the container to scroll */
}@media print query to define styles specifically for printing. Instead of rewriting all CSS, only override the properties that differ from the screen display. It is recommended to manually set colors (e.g., black text on white background) because browsers may automatically alter colors to save ink.@media print {
body {
color: #000;
background: #fff;
}
/* Hide irrelevant elements like navigation or sidebars */
nav, aside {
display: none;
}
}Observable instance and call .subscribe() to start receiving values. The Observable defines the data production logic via a subscriber, while the subscription defines how to handle those values.import { Observable } from 'rxjs';
(() => {
// Define the Observable and its data production
const _instance = new Observable(subscriber => {
subscriber.next(1);
subscriber.complete();
});
// Subscribe to the Observable to handle the values
_instance.subscribe({
next: (val) => console.log(`hello ${val}`),
complete: () => console.log('i have been already finished~')
});
})();RxJS uses specific terminology to describe the flow of data and the management of streams:
subscribe method that allows you to cancel the execution using .unsubscribe().then works in Promises).Standard position: fixed anchors an element to the viewport. To make an element appear 'fixed' relative to a specific parent container (where the element stays put while other content inside that parent scrolls), use a wrapper element (an 'assistor') with position: relative.
By placing the 'fixed' child as a direct descendant of the relative assistor and the scrollable content inside a separate parent div, the child remains positioned relative to the assistor's boundaries and does not move when the inner parent's scrollbar is used.
<div class="assistor">
<div class="parent">
<div class="child">Fixed Position Area</div>
<div class="placeholder">Scrollable Content Area</div>
</div>
</div>.assistor {
position: relative; /* Essential: provides the coordinate system for the child */
display: block;
width: 500px;
height: 300px;
background-color: #ddd;
}
.parent {
width: 500px;
height: 300px;
background-color: #888;
overflow: auto; /* Essential: enables scrolling for the content */
}
.child {
position: absolute; /* Essential: positions relative to .assistor, not .parent */
width: 120px;
height: 120px;
margin: 100px 50px;
background-color: #333;
color: #fff;
}
.placeholder {
width: 1000px;
height: 1000px;
color: #fff;
}.vscode folder in the project root and add a file named snippets.code-snippets. Define snippets in this file using a JSON format containing a prefix, body (as an array of strings), and a description.{
"snippet": {
"prefix": "mySnippet",
"body": [
"console.log('Hello, World!');"
],
"description": "My custom code snippet"
}
}# List existing remote repositories
git remote -v
# Add a new remote repository with a specific name
git remote add [origin-name] [repo-url]
# Push code to a specific remote
git push [origin-name]When destructuring state from a Pinia store in Vue 3, the reactivity behavior depends on the data type:
To ensure consistency and maintain reactivity regardless of whether the state is an object or a primitive, use the storeToRefs utility to convert the destructured properties into Ref variables.
import { storeToRefs } from 'pinia'
import { useUserStore } from '@/stores/user'
const store = useUserStore()
// Use storeToRefs to maintain reactivity for both primitives and objects
const { name, settings } = storeToRefs(store)