Js part
Quickly extract numbers from a string
Const STR = "12.6 px"; const numInt = parseInt(str); // numInt: 12 const numFloat = parseFloat(str); / / numInt: 12.6Copy the code
When the existence of an item in an array/object is determined by a condition
object
Assertion + object expansion operator
let isSleep = true; const obj = { name: "logan", ... isSleep && { age: 230 }, }; Obj = {name: "Logan ", age: 230}Copy the code
An array of
Ternary + array expansion operator (predicate expression will have a undefined, arrays will not be filtered by default)
const hasSecond = true
const arr = [
{
num: 1
},
...hasSecond ? [{
num: 2
}] : []
]
Copy the code
Delete the array with the length attribute
const arr = [0, 1, 2, 3, 4, 5]; arr.length = 0; // arr changes to []Copy the code
Fortunately, in VUe3, the VUE team solved this problem by replacing Object.defineProperty with a Proxy and waiting for the official release of VUe3.
Comma operator
The comma operator evaluates each of its operands (left to right) and returns the value of the last operand.
const history = []; Const push = val => (history.push(memory(val)), val);Copy the code
Deconstruct where expressions are commonly used
For of expression line destruct
const cacheList = [
{
id: 1,
date: "2020-05-18",
timeout: 2569
},
{
id: 3,
date: "2020-04-16",
timeout: 7863
},
{
id: 2,
date: "2020-03-21",
timeout: 6387
}
]
for(let {id, date, timeout} of cacheList) {
console.log(id);
console.log(date);
console.log(timeout);
}
Copy the code
Retrieve the remaining attributes of the object
The vue component passes down the props syntax with $attrs and $listener, but react does not provide this scheme, so when the props need to be passed across several layers, we can use the deconstruction method to avoid making our component a props mover.
The following code
Function Parent() {const [list, setList] = useState([]); function Parent() {const [list, setList] = useState([]); const produce = [ { id: 0, name: "x23" } ]; Return (<child list={list} produce={produce} change={setList}/>)}/ / Pass function child (props) {const {list, ... rest} = props; return ( <Grandson {... Function GrandSon(props) {return (<> <ul> {produce. Map (({id, name}) => <Cell key={id} title={name}>)} </ul> <button onClick={change}></button> </> ) }Copy the code
Similarly, this approach can be used in vUE, for example, if you write a table component and want to add custom fields in multiple locations, you can use V-bind to do this.
(The inspiration here comes from the table source section of Layui)
<th v-for="({title, ... rest}) in col" :key="title" v-bind="rest" > {{title}} </th>Copy the code
Parameters are destructed directly, reducing unnecessary temporary variable declarations
window.addEventListener("wheel", function({clientX, clientY}) {
console.log({clientX, clientY});
});
Copy the code
Dynamic property name and property name expression
const type = "email"; const params = { username: "James Rhodes", password: "war machine Rox with an X", [type]: "[email protected]", } const key = "password"; console.log(params[key]); // War machine Rox with an XCopy the code
For example, if you want to dynamically value values in vUE (vue(2.6.0+) dynamic attribute)
<component :[key]="value"></component>
Copy the code
The default value is used
||
function Jarvis(options) {
this.name = options.sir || "Tony Stark";
}
Copy the code
Destruct expression
function Jarvis(options) { const {sir = "Tony Stark"} = options; this.name = sir; // const {Sir :name} = options; // this.name = name; }Copy the code
(negligible) ES11 provides?? operation
function Jarvis(options) {
this.name = options.sir ?? "Tony Stark";
}
Copy the code
Alternative cssText dom. Style. XXX
const dom = document.querySelector(".wrapper"); dom.style.cssText = "width:20px; height:20px; border:solid 1px gray;" ;Copy the code
Use Array’s factory function to create an Array of a specific length
Array.from(arrayLike[, mapFn[, thisArg]])
- ArrayLike A pseudo-array object or iterable that you want to convert to an array.
- MapFn Optional If this parameter is specified, each element in the new array executes the callback function.
- ThisArg Optional This object is optional when the callback function mapFn is executed.
Array.from({ length: 10 }, (v, i) => i + 1); // Output [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]Copy the code
I now use this feature to mock data
app.get('/getProduces', function (req, res) {
res.send({
code: 200,
data: Array.from({length: 6}, (v, i) => ({
name: `produce - ${i}`,
url: `/view/produce/${i}.html`,
type: Math.round(Math.random())
? "new"
: "default",
num: Math.round(Math.random() * 10000),
}))
});
});
Copy the code
Adds data to the array header
Sometimes you might make a stack structure out of arrays
const arr = ["Ferrie", "Natasha"]; arr.unshift("Tony"); // Arr becomes ["Tony", "Ferrie", "Natasha"]Copy the code
Reduce scope lookups
For example, the following code runs in global scope:
<script> var header = document.querySelector("#header"); header.style.cssText = `position: sticky; top: ${offsetTop}px; `; </script>Copy the code
In a script tag, the context of the code is in the global scope, and the compiler is slow to process the global scope because of its complexity. Just like the header variable above, the second line needs to look up the variable in the global scope when it is used. Assuming the header is used in a loop, that might be efficient. So avoid global scopes and choose local scopes instead:
For example 🌰, closure scope
<script> ! function(){ var header = document.querySelector("#header"); header.style.cssText = `position: sticky; top: ${offsetTop}px; `; }() </script>Copy the code
Avoid overusing closures
Even if closures are useful, don’t abuse them; variables in closures are scoped independently. The compiler looks for variables from the current scope to the parent scope. So the depth of closure nesting affects variable lookup time.
For example, 🌰, we have a flow function that defines an animate function. After animate, there is a constant location. Target and rate are in the parent scope of animate. The lookup takes longer than the location,
Function flow(target, rate = 0) {rate += 0.1; Function animate() {const location = getLocation(target.location, 0.5); return Tween.get(target).to({rate}); } return animate(); }Copy the code
You can pass target and rate to animate as parameters. In this way, their scope becomes the same, and the read time is just a matter of how the compiler handles the difference between constants and variables.
Function flow(target, rate = 0) {rate += 0.1; function animate(target, rate) { return Tween.get(target).to({rate}); } return animate(target, rate); }Copy the code
If a global variable needs to be used frequently, you can cache it with a local variable (🌰: I got it myself).
function call() { if(window.location.origin ! == "xxxxxx") return; const hash = getHash(window.location.href); const url = `/api/radio/${window.location.search}/${hash}`; }Copy the code
Using window.location multiple times, we can cache it in the function scope,
function call() { const {location} = window; if(location.origin ! == "xxxxxx") return; const hash = getHash(location.origin, location.hash); const url = `/api/radio/${location.search}/${hash}`; }Copy the code
Alternative = = = = =
Two reasons
- 1. Js is a weakly typed language.
= =
Data types are ignored in favor of more precise ones for better readability= = =
operation - 2. Better compilation speed at compiler processing
= =
Will first convert the two variables to the same type, and then compare whether the values are equal; And processing= = =
Determines whether the types are the same, and then decides whether to compare values for equality.
String template
Discard string concatenation or arrays for better readability. Join (“”), select string template
Const STR = ` original price: ${price}, discount: ${discount}, the final price: ${(price discount). ToFixed (2)} `;Copy the code
The priority of variable modifiers: const > let > var
According to?
var
- You can redeclare it
var starLord = "fool";
starLord = "very fool";
var starLord = "foolish";
Copy the code
- Can be variable promoted
function () { console.log(name); Var name = "Tony"}Copy the code
- Span block scope
- Block scope: {}, conditions, {} of loop statements
{ var Tony = "Iron Man"; } console.log(Tony); If (true) {var Steve = "caption"; } console.log(Steve ); // caption let i = 0; while(i++ < 2) { if(i === 1) { var thor = "Fatty"; } } console.log(thor); // FattyCopy the code
let
Can only be used in the current block-level scope
const
- Const is more semantic, reminding developers that the variable should not be changed;
- The compiler optimizes const to read constants faster than variables. The essential difference is how the compiler handles it internally.
Use promise.all for correct posture
Before ES11 promise. allSettled appeared, promise. all collected promises. When any one of them was wrong, no result could be obtained. In this case, you could perform a catch operation on the Promise objects collected by ALL to manually process err
const p1 = new Promise(...) const p2 = new Promise(...) const p3 = new Promise(...) Promise.all([p1,p2,p3]).then(...) .catch(err => err)Copy the code
Multiple loading conflicts
Introduce a variable loadingCount for counting,
When loading, check whether the quantity is 0. If the condition is met, +1 is used.
If the value is close, -1 is used first. If the value is 0, the command is executed
let loadingCount = 0
function open() {
if(loadingCount > 0) return
loadingCount++;
loading.open();
}
function close() {
loadingCount--
if(loadingCount === 0) {
loading.close()
}
}
Copy the code
After triggering the parent component event in vUE, retrieve the props
props: {
msgList: ...
}
Copy the code
this.$emit("sendMsg", id); $nextTick(() => {this.showdetail = this.msglist && this.msglist. Length > 0; });Copy the code
Conflicts between canvas drawing and clearing functions
Remember to call Context.beginPath () to clear, otherwise the previous line still exists
The CSS part
Debug UI tips
Try adding this style to the debug area (#app)
#app {
outline: 1px #000 solid;
}
Copy the code
Can automatically adapt to the wide/high background image Mosaic scheme
whendom
In the background is a picture whose width and height are determined by the content,
How to achieve the image adaptive height at this time?
(Flicker because we changed the width and height causing the browser to redraw and rearrange)
<style> .box { width: 100px; height: auto; // Change background height arbitrarily: url(/static/img/box-bg-top.png) top no-repeat, url(/static/img/box-bg-bottom.png) bottom no-repeat; } .box:before { content: ''; position: absolute; z-index: -1; top: 80px; right: 0; bottom: 80px; left: 0; background: url(/static/img/box-bg-center.png) repeat; } </style> <body> <div class="box"> </div> </body>Copy the code
Dom itself implements the header and tail of the image through background-position and background-repeat, and then implements the adaptive part in the middle with pseudo-elements
Use pointer-Events properly
In a super-large DOM, with only one small child DOM requiring mouse events, we can do this
.parent {
width: 600px;
height: 500px;
pointer-events: none;
}
.close {
float: right;
width: 10px;
height: 10px;
pointer-events: visible;
}
Copy the code
CSS selectors
After the x th (excluding the x th)
li:nth-of-type(n+x) {
...
}
Copy the code
X th and before (inclusive of x th)
li:nth-of-type(-n+x) {
...
}
Copy the code
Not selector (exclude one)
li:not(:last-child) {
background: #08627f;
}
Copy the code
Font spacing and center
Most people just set spacing to spacing. This causes text to get too big and out of center, so you need the same text-indent value for the first line to be centered
.text {
letter-spacing: 12px;
text-indent: 12px;
}
Copy the code
transform
Instead of left/top, can effectively avoid redrawing
Redrawing and rearranging will cause a splash screen, as you can see in the example above
.dot {
transform: translate3d(10px, 16px, 0);
}
Copy the code
Force GPU rendering on using translateZ
.dot {
transform: translateZ(0);
}
Copy the code
However, if GPU acceleration is enabled, frequent flickering or jitter may occur in the browser. This can be solved as follows:
.dot {
-webkit-backface-visibility:hidden;
-webkit-perspective:1000;
}
Copy the code
Absolute positioning, centering problem with uncertain width and height
.box {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
Copy the code
Give thead border
table {
border-collapse:collapse;
}
thead {
border: 1px #0af solid;
}
Copy the code
Image distortion free
img {
object-fit: cover;
}
Copy the code
Sprites fit the screen
@screen_width: 1920; img { background-image: url("..." ); background-position: 15px 30px; background-size: calc(100vw / @screen_width * 160); }Copy the code
Input to the border
border: none;
outline: none;
Copy the code
The user resizes the DOM
Slightly less compatible
.resize {
resize:both;
}
Copy the code
CSS Smooth scrolling
scroll-container {
scroll-behavior: smooth;
}
Copy the code
<nav>
<a href="#page-1">1</a>
<a href="#page-2">2</a>
<a href="#page-3">3</a>
</nav>
<scroll-container>
<scroll-page id="page-1">1</scroll-page>
<scroll-page id="page-2">2</scroll-page>
<scroll-page id="page-3">3</scroll-page>
</scroll-container>
Copy the code
Height is a percentage when the text is vertically centered
Use table-cell and vertical-align
<style>
.parent {
display: table;
width: 600px;
height: 50%
}
.parent a {
display: table-cell;
vertical-align: middle;
}
</style>
<div class="parent">
<a href="#page-1">1</a>
<a href="#page-2">2</a>
<a href="#page-3">3</a>
</nav>
Copy the code
Var takes the element attribute value
Class, ID, and Keyframes can all be used to directly retrieve attributes on an element
<template>
<div v-for="(item, index) in list"
:style="{'--y': `${index*60}deg`}"
class="around-item u_3d">
<div class="content">{{item}}</div>
</div>
</template>
<style>
@keyframes around-self {
0% {
transform: rotateY(calc(var(--y) * -1));
}
100% {
transform: rotateY(calc(var(--y) * -1 - 360deg));
}
}
.content {
animation: around-self 10s linear 0s infinite;
}
</style>
Copy the code
other
When webpack configures the Loader, narrow the search scope by using test, exclude, and include
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader',
include: [resolve('src/components'), resolve('src/modules')],
options: vueLoaderConfig
},
{
test: /\.js$/,
loader: 'babel-loader',
include: [resolve('src'), resolve('node_modules/webpack-dev-server/client')],
exclude: /node_modules/
},
]
}
Copy the code
Modifiers for script and style tags
preload
Resources are loaded before DOM rendering, usually some of the logic responsible for the first screen rendering
<link rel="preload" href="index.css">
Copy the code
Prefetch, DNS – prefetch
When the page is loaded and there is no work to do, loading is usually some script related to user interaction, such as a third-party pop-up layer
<link rel="prefetch" href="next.css">
<link rel="dns-prefetch" href="//example.com">
Copy the code
No modifiers (asynchronous, no blocking)
Pause parsing document. Request script to execute script to continue parsing document
<script src="index.js" ></script>
Copy the code
defer
Js and user.js are downloaded in parallel, in order of the page, after the execution of other synchronization scripts, and before the execution of DOMContentLoaded events, home.js and user.js are executed successively.
<script src="home.js" defer></script>
<script src="user.js" defer></script>
Copy the code
async
When the script is downloaded, it is immediately executed. The execution sequence of the script is uncertain, and the execution stage is uncertain. It may be executed before or after DOMContentLoaded
<script src="home.js" async></script>
<script src="user.js" async></script>
Copy the code
The image format is webP
Small size, fast request speed, but there are compatibility problems, need to be handled manually