Skip to main content

方式一:先导入再使用

import logo from './images/logo.png'

const Example = () => {
return <img src={logo} alt="" />
}

方式二:直接请求使用

const Example = () => {
return <img src={<img src={require('./images/logo.png')} alt="" />} alt="" />
}

Live Editor
Result
Loading...

import { Dropdown, Menu } from 'antd'
import { useState } from 'react'

interface Props {
measure: {
leftWidth: number
rightWidth: number
widthOfMinute: number
minuteOfWidth: number
}
}

const AreaBar = (props: Props) => {
const {
measure
} = props

const [left, setLeft] = useState<number>(200)
const [width, setWidth] = useState<number>(200)

const hourWidth = measure.widthOfMinute * 60
const twoHoursWidth = measure.widthOfMinute * 120

const contextMenu = (
<Menu items={[
{
key: 'edit',
label: (
<div>编辑</div>
),
},
{
key: 'delete',
label: (
<div>删除</div>
),
}
]} />
)

// 拖动
const handleMouseDown = (e: any) => {
const startX = e.clientX
let _left = left
document.onmousemove = (e2: any) => {
const endX = e2.clientX
const diffX = endX - startX
_left = left + diffX
// 左限
if(_left <= 0) {
_left = 0
}
// 右限
if(_left >= (measure.rightWidth - width)) {
_left = measure.rightWidth - width
}
setLeft(_left)
}
document.onmouseup = () => {
document.onmousemove = null
document.onmouseup = null
// 吸附
const newLeft = Math.floor(_left / hourWidth) * hourWidth
// const newWidth = Math.ceil((_left + width) / hourWidth) * hourWidth - newLeft // 左右吸附
const newWidth = Math.floor((_left + width) / hourWidth) * hourWidth - newLeft // 左吸附
setLeft(newLeft)
setWidth(newWidth)
}
}

// 左拉伸
const handleLeftMouseDown = (e: any) => {
const startX = e.clientX
const maxWidth = width + left
const minLeft = maxWidth - hourWidth
let _left = left
document.onmousemove = (e2: any) => {
const endX = e2.clientX
const diffX = endX - startX
_left = left + diffX
let _width = width - diffX
// 左限
if(_left <= 0) {
_left = 0
_width = maxWidth
}
// 右限
if(_width <= hourWidth) {
_width = hourWidth
_left = minLeft
}
setLeft(_left)
setWidth(_width)
}
document.onmouseup = () => {
document.onmousemove = null
document.onmouseup = null
// 吸附
const newLeft = Math.floor(_left / hourWidth) * hourWidth
setLeft(newLeft)
setWidth(maxWidth - newLeft)
}
}

// 右拉伸
const handleRightMouseDown = (e: any) => {
const startX = e.clientX
let _width = width
document.onmousemove = (e2: any) => {
const endX = e2.clientX
const diffX = endX - startX
_width = width + diffX
// 左限
if(_width <= hourWidth) {
_width = hourWidth
}
// 右限
if(_width >= (measure.rightWidth - left)) {
_width = measure.rightWidth - left
}
setWidth(_width)
}
document.onmouseup = () => {
document.onmousemove = null
document.onmouseup = null
// 吸附
const newWidth = Math.ceil((left + _width) / hourWidth) * hourWidth - left
setWidth(newWidth)
}
}

// 时间范围
const curHours = Math.floor(width * measure.minuteOfWidth / 60)
let leftTime: any = Math.floor(left * measure.minuteOfWidth / 60)
let rightTime = leftTime + curHours
if(rightTime < 10) {
rightTime = '0' + rightTime
}
if(leftTime < 10) {
leftTime = '0' + leftTime
}

return (
<Dropdown trigger={['contextMenu']} overlay={contextMenu} overlayStyle={{width: 80}} placement="bottomRight">
<div className="areabar areabarSelected" style={{left, width}}>
<div className="handlebarLeft" onMouseDown={handleLeftMouseDown}></div>
<div className="area" onMouseDown={handleMouseDown}>
{width > twoHoursWidth && <div className="leftTime">{leftTime}:00</div>}
<div className="centerTime">{curHours}H</div>
{width > twoHoursWidth && <div className="rightTime">{rightTime}:00</div>}
</div>
<div className="handlebarRight" onMouseDown={handleRightMouseDown}></div>
</div>
</Dropdown>
)
}

export default AreaBar

一般均为HTMLElement,特殊的为HTML+标签名+Element ,当然也有些标签名为单字母的例如h1-h6,他们的类型为HTMLHeadingElement。

const mapEle = document.querySelector('#js_map') as HTMLDivElement

也流传这种写法,不过经测试报错。

const mapEle = <HTMLDivElement>document.querySelector('#js_map')
  "a": HTMLAnchorElement;
"abbr": HTMLElement;
"address": HTMLElement;
"applet": HTMLAppletElement;
"area": HTMLAreaElement;
"article": HTMLElement;
"aside": HTMLElement;
"audio": HTMLAudioElement;
"b": HTMLElement;
"base": HTMLBaseElement;
"bdi": HTMLElement;
"bdo": HTMLElement;
"blockquote": HTMLQuoteElement;
"body": HTMLBodyElement;
"br": HTMLBRElement;
"button": HTMLButtonElement;
"canvas": HTMLCanvasElement;
"caption": HTMLTableCaptionElement;
"cite": HTMLElement;
"code": HTMLElement;
"col": HTMLTableColElement;
"colgroup": HTMLTableColElement;
"data": HTMLDataElement;
"datalist": HTMLDataListElement;
"dd": HTMLElement;
"del": HTMLModElement;
"details": HTMLDetailsElement;
"dfn": HTMLElement;
"dialog": HTMLDialogElement;
"dir": HTMLDirectoryElement;
"div": HTMLDivElement;
"dl": HTMLDListElement;
"dt": HTMLElement;
"em": HTMLElement;
"embed": HTMLEmbedElement;
"fieldset": HTMLFieldSetElement;
"figcaption": HTMLElement;
"figure": HTMLElement;
"font": HTMLFontElement;
"footer": HTMLElement;
"form": HTMLFormElement;
"frame": HTMLFrameElement;
"frameset": HTMLFrameSetElement;
"h1": HTMLHeadingElement;
"h2": HTMLHeadingElement;
"h3": HTMLHeadingElement;
"h4": HTMLHeadingElement;
"h5": HTMLHeadingElement;
"h6": HTMLHeadingElement;
"head": HTMLHeadElement;
"header": HTMLElement;
"hgroup": HTMLElement;
"hr": HTMLHRElement;
"html": HTMLHtmlElement;
"i": HTMLElement;
"iframe": HTMLIFrameElement;
"img": HTMLImageElement;
"input": HTMLInputElement;
"ins": HTMLModElement;
"kbd": HTMLElement;
"label": HTMLLabelElement;
"legend": HTMLLegendElement;
"li": HTMLLIElement;
"link": HTMLLinkElement;
"main": HTMLElement;
"map": HTMLMapElement;
"mark": HTMLElement;
"marquee": HTMLMarqueeElement;
"menu": HTMLMenuElement;
"meta": HTMLMetaElement;
"meter": HTMLMeterElement;
"nav": HTMLElement;
"noscript": HTMLElement;
"object": HTMLObjectElement;
"ol": HTMLOListElement;
"optgroup": HTMLOptGroupElement;
"option": HTMLOptionElement;
"output": HTMLOutputElement;
"p": HTMLParagraphElement;
"param": HTMLParamElement;
"picture": HTMLPictureElement;
"pre": HTMLPreElement;
"progress": HTMLProgressElement;
"q": HTMLQuoteElement;
"rp": HTMLElement;
"rt": HTMLElement;
"ruby": HTMLElement;
"s": HTMLElement;
"samp": HTMLElement;
"script": HTMLScriptElement;
"section": HTMLElement;
"select": HTMLSelectElement;
"slot": HTMLSlotElement;
"small": HTMLElement;
"source": HTMLSourceElement;
"span": HTMLSpanElement;
"strong": HTMLElement;
"style": HTMLStyleElement;
"sub": HTMLElement;
"summary": HTMLElement;
"sup": HTMLElement;
"table": HTMLTableElement;
"tbody": HTMLTableSectionElement;
"td": HTMLTableDataCellElement;
"template": HTMLTemplateElement;
"textarea": HTMLTextAreaElement;
"tfoot": HTMLTableSectionElement;
"th": HTMLTableHeaderCellElement;
"thead": HTMLTableSectionElement;
"time": HTMLTimeElement;
"title": HTMLTitleElement;
"tr": HTMLTableRowElement;
"track": HTMLTrackElement;
"u": HTMLElement;
"ul": HTMLUListElement;
"var": HTMLElement;
"video": HTMLVideoElement;
"wbr": HTMLElement;

keyof

const foo = {
name: 'tom',
age: 18
}

const field = 'age'

console.log(foo[field]) // error 元素隐式具有 "any" 类型,因为类型为 "string" 的表达式不能用于索引类型

// 解决
console.log(foo[field as keyof typeof foo])

keyof 介绍

JavaScript 通过 Object.keys() 获取对象的所有属性键值,而 typescript 主要关注的是类型操作,通过 keyof 操作符可以获取对象中的所有键类型组成的联合类型。

示例:

type Person = {
id: number;
name: string;
};

type P = keyof Person; // 'id' | 'name'

keyof 操作符得到的是 Person 类型的所有键值类型即 'id''name' 三个字面量类型组成的联合类型 'id' | 'name'

在获取对象类型的键之后,我们就可以通过类似属性访问的语法来访问该键对应的值的类型。

type P1 = Person["id"] // number
type P2 = Person["id" | "name"] // string | number
type P3 = Person[keyof Person] // string | number

可扩展接口类型

interface Foo {
[key: string]: any
}

const foo: Foo = {
name: 'tom',
age: 18
}

console.log(foo.name)

any 类型

interface Foo {
[key: string]: any
}

const foo: any = {
name: 'tom',
age: 18
}

console.log(foo.name)

修改 tsconfig.json

{
"compilerOptions": {
"suppressImplicitAnyIndexErrors": true,
}
}

非弹层内解决方式

.logo {
 animation: zoom 1.5s infinite;
}
@keyframes zoom {
0%,
20%,
80%,
100% {
transform: scale(1);
}
40%,
50% {
transform: scale(0.9);
}
}

弹层内解决方式

在className后增加 :local 作用域(webpack css module local作用域说明

:global {
.logo :local {
animation: zoom 2.5s ease-out;
}
@keyframes zoom {
0%,
20%,
80%,
100% {
transform: scale(1);
}
40%,
50% {
transform: scale(0.9);
}
}
}