mirror of
https://github.com/DefectingCat/DefectingCat.github.io
synced 2025-07-16 01:01:38 +00:00
Change way to import images
This commit is contained in:
@ -3,6 +3,7 @@ import Anchor from 'components/mdx/Anchor';
|
||||
import Image from 'components/mdx/Image';
|
||||
import Tab from 'components/RUA/tab';
|
||||
import TabItem from 'components/RUA/tab/TabItem';
|
||||
import RUACodeSandbox from 'components/RUA/RUACodeSandbox';
|
||||
|
||||
const components = {
|
||||
RUASandpack,
|
||||
@ -10,6 +11,7 @@ const components = {
|
||||
Image,
|
||||
Tab,
|
||||
TabItem,
|
||||
RUACodeSandbox,
|
||||
};
|
||||
|
||||
export default components;
|
||||
|
@ -4,13 +4,11 @@ import {
|
||||
main2,
|
||||
styles,
|
||||
} from 'data/sandpack/how-to-load-a-background-with-threejs';
|
||||
|
||||
import skybox_example from 'public/images/p/how-to-load-a-background-with-threejs/Skybox_example.png';
|
||||
import crawler from 'public/images/p/setting-up-docsearch-for-nextjs/cannot-login-to-algolia-crawler.png';
|
||||
import indexFormat from 'public/images/p/setting-up-docsearch-for-nextjs/index-format.png';
|
||||
import windowsEnv from 'public/images/p/my-develop-environmental/windows-environmentail.png';
|
||||
import miniRouter1 from 'public/images/p/create-a-mini-router-for-react/router.webp';
|
||||
import miniRouter4 from 'public/images/p/create-a-mini-router-for-react/image-20210823154009498.webp';
|
||||
import {
|
||||
genericApp,
|
||||
genericChild,
|
||||
hookApp,
|
||||
} from './sandpack/generic-component-encapsulate-reusable-component';
|
||||
|
||||
const data = {
|
||||
sandpack: {
|
||||
@ -18,22 +16,9 @@ const data = {
|
||||
'load-background-main': main,
|
||||
'load-background-main2': main2,
|
||||
'load-background-styles': styles,
|
||||
},
|
||||
images: {
|
||||
'load-background': {
|
||||
skybox_example,
|
||||
},
|
||||
'setting-up-docsearch': {
|
||||
crawler,
|
||||
indexFormat,
|
||||
},
|
||||
'dev-env': {
|
||||
windowsEnv,
|
||||
},
|
||||
miniRouter: {
|
||||
miniRouter1,
|
||||
miniRouter4,
|
||||
},
|
||||
'generic-app': genericApp,
|
||||
'generic-child': genericChild,
|
||||
'generic-hookApp': hookApp,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -6,7 +6,13 @@ tags: [JavaScript, React]
|
||||
|
||||
路由不仅仅只是网络的代名词,它更像是一种表达路径的概念。与网络中的路由相似,前端中的页面路由也是带领我们前往指定的地方。
|
||||
|
||||
<Image src={images.miniRouter.miniRouter1} placeholder="" priority />
|
||||
<Image
|
||||
src={'/images/p/create-a-mini-router-for-react/router.webp'}
|
||||
placeholder=""
|
||||
priority
|
||||
width="1366"
|
||||
height="900"
|
||||
/>
|
||||
|
||||
## 现代前端的 Web 应用路由
|
||||
|
||||
@ -117,7 +123,12 @@ export default Router;
|
||||
|
||||
现在我们直接从地址栏访问对应的路由,我们的 Router 组件应该就可以根据已经注册好的路由配置文件来找到正确的组件,并将其渲染出来了。
|
||||
|
||||
<Image src={images.miniRouter.miniRouter4} alt="image-20210823154009498" />
|
||||
<Image
|
||||
src={'/images/p/create-a-mini-router-for-react/image-20210823154009498.webp'}
|
||||
alt="image-20210823154009498"
|
||||
width="419"
|
||||
height="227"
|
||||
/>
|
||||
|
||||
### 切换路由
|
||||
|
||||
|
@ -4,21 +4,6 @@ date: '2022-08-12'
|
||||
tags: [TypeScript, React]
|
||||
---
|
||||
|
||||
export const meta = {
|
||||
title: '组件泛型实例-封装可复用的表单组件',
|
||||
date: '2022-08-12',
|
||||
tags: ['TypeScript', 'React'],
|
||||
};
|
||||
|
||||
import Layout from 'layouts/MDXLayout';
|
||||
import dynamic from 'next/dynamic';
|
||||
import Image from 'components/mdx/Image';
|
||||
import image0 from 'assets/images/p/generic-component-encapsulate-reusable-component/Untitled.png';
|
||||
import image1 from 'assets/images/p/generic-component-encapsulate-reusable-component/Untitled.png';
|
||||
import image2 from 'assets/images/p/generic-component-encapsulate-reusable-component/Untitled.png';
|
||||
import image3 from 'assets/images/p/generic-component-encapsulate-reusable-component/Untitled.png';
|
||||
import image4 from 'assets/images/p/generic-component-encapsulate-reusable-component/Untitled.png';
|
||||
import image5 from 'assets/images/p/generic-component-encapsulate-reusable-component/Untitled.png';
|
||||
import app from 'assets/sandpack/generic-component-encapsulate-reusable-component/hook-form-basic/App.ts';
|
||||
import app2 from 'assets/sandpack/generic-component-encapsulate-reusable-component/react-generic/App.ts';
|
||||
import child from 'assets/sandpack/generic-component-encapsulate-reusable-component/react-generic/Child.ts';
|
||||
@ -51,7 +36,7 @@ React Hook Forms 对 TypeScript 支持良好,有了 TypeScript 我们就可以
|
||||
<RUASandpack
|
||||
template="react-ts"
|
||||
files={{
|
||||
'/App.tsx': app,
|
||||
'/App.tsx': sandpack['generic-hookApp'],
|
||||
}}
|
||||
customSetup={{
|
||||
dependencies: {
|
||||
@ -116,7 +101,14 @@ const Input = ({ name, label, ...rest }: FormInputProps) => {
|
||||
|
||||
但是如果仅仅只是这样,我们的组件还不能与 React Hook Forms 一起工作。因为其核心部分 `register` 函数还无法传递给我们的 `Input` 组件。也就是说我们的组件现在还是不可控的,这时候再尝试提交就会发现无法获取其状态。
|
||||
|
||||
<Image src={image0} alt="无法获取其状态" />
|
||||
<Image
|
||||
src={
|
||||
'/images/p/generic-component-encapsulate-reusable-component/Untitled.png'
|
||||
}
|
||||
alt="无法获取其状态"
|
||||
width="493"
|
||||
height="478"
|
||||
/>
|
||||
|
||||
当然我们不能简单的将 `register` 函数塞给 `Input` 组件,因为它还没有合适的签名。`register` 函数会根据表单的数据签名和不同的表单项来实现自己的签名。
|
||||
|
||||
@ -188,15 +180,36 @@ const sayIt = <T extends number | string>(p: Person<T>) => {
|
||||
|
||||
当指定参数为 `p: Person<T>` 时,就需要将函数的泛型传递给类型别名。且类型别名中的泛型约束在了 `<T extends number | string>` 之间,函数必须保证使其子类型。否则就会提示无法满足其类型。
|
||||
|
||||
<Image src={image1} alt="未约束的泛型" />
|
||||
<Image
|
||||
src={
|
||||
'/images/p/generic-component-encapsulate-reusable-component/Untitled-1.png'
|
||||
}
|
||||
alt="未约束的泛型"
|
||||
width="516"
|
||||
height="131"
|
||||
/>
|
||||
|
||||
和参数类型,泛型也是向下兼容的,只要保证其类型是子类型即可。也就是说这样也是可以的 `const sayIt = <T extends 42>(p: Person<T>) => {}` 。数字 42 是 `number` 类型的子类型。
|
||||
|
||||
随后在调用函数时,就能发现泛型给我们带来的作用了。
|
||||
|
||||
<Image src={image2} alt="传递数字给泛型" />
|
||||
<Image
|
||||
src={
|
||||
'/images/p/generic-component-encapsulate-reusable-component/Untitled-2.png'
|
||||
}
|
||||
alt="传递数字给泛型"
|
||||
width="416"
|
||||
height="158"
|
||||
/>
|
||||
|
||||
<Image src={image3} alt="传递字符串给泛型" />
|
||||
<Image
|
||||
src={
|
||||
'/images/p/generic-component-encapsulate-reusable-component/Untitled-3.png'
|
||||
}
|
||||
alt="传递字符串给泛型"
|
||||
width="504"
|
||||
height="156"
|
||||
/>
|
||||
|
||||
### React 中的泛型
|
||||
|
||||
@ -207,8 +220,8 @@ const sayIt = <T extends number | string>(p: Person<T>) => {
|
||||
<RUASandpack
|
||||
template="react-ts"
|
||||
files={{
|
||||
'/App.tsx': app2,
|
||||
'/Child.tsx': child,
|
||||
'/App.tsx': sandpack['generic-app'],
|
||||
'/Child.tsx': sandpack['generic-child'],
|
||||
}}
|
||||
/>
|
||||
|
||||
@ -229,7 +242,14 @@ const testData = {
|
||||
|
||||
但不仅如此,我们还希望我们的子组件能够根据已经存在的值,推断出我们能够传递的 key。
|
||||
|
||||
<Image src={image4} alt="类型推断" />
|
||||
<Image
|
||||
src={
|
||||
'/images/p/generic-component-encapsulate-reusable-component/Untitled-4.png'
|
||||
}
|
||||
alt="类型推断"
|
||||
width="743"
|
||||
height="118"
|
||||
/>
|
||||
|
||||
这正是泛型的作用。
|
||||
|
||||
@ -318,7 +338,14 @@ const Input = <T extends Record<string, unknown>>({
|
||||
|
||||
得益于泛型的功劳,我们将 `register` 函数传递给 `Input` 组件时,我们的组件就知道了这次表单的类型。并且确定了 `name` 属性的类型。
|
||||
|
||||
<Image src={image5} alt="类型推断" />
|
||||
<Image
|
||||
src={
|
||||
'/images/p/generic-component-encapsulate-reusable-component/Untitled-5.png'
|
||||
}
|
||||
alt="类型推断"
|
||||
width="623"
|
||||
height="230"
|
||||
/>
|
||||
|
||||
这是因为 `register` 函数本身的签名:`const register: UseFormRegister<FormData>` 。这才使得我们的组件成功接受到了泛型。
|
||||
|
||||
|
@ -81,7 +81,11 @@ We need set texture to cube box each side. so we need six pictures.
|
||||
|
||||
The skybox is six images that can be connected each other.
|
||||
|
||||
<Image src={images['load-background']['skybox_example']} />
|
||||
<Image
|
||||
src={'/images/p/how-to-load-a-background-with-threejs/Skybox_example.png'}
|
||||
width="512"
|
||||
height="384"
|
||||
/>
|
||||
|
||||
We just need load six images in some order, and set them to the scene background.
|
||||
|
||||
|
@ -202,7 +202,12 @@ source $HOME/.cargo/env
|
||||
|
||||
对于 Windoiws 环境则需要在“设置”-“高级系统设置”-“环境变量”中添加对应的变量到用户/系统变量中。
|
||||
|
||||
<Image src={images['dev-env'].windowsEnv} alt="Windows environmentail" />
|
||||
<Image
|
||||
src={'/images/p/my-develop-environmental/windows-environmentail.png'}
|
||||
alt="Windows environmentail"
|
||||
width="1024"
|
||||
height="259"
|
||||
/>
|
||||
|
||||
当然这几个主要的变量可以放在 `.zshrc` 中,以后更新还会用到的。
|
||||
|
||||
|
@ -27,8 +27,12 @@ They introduct the [Algolia Crawler web interface](https://crawler.algolia.com/a
|
||||
But i can't login with my Algolia account.
|
||||
|
||||
<Image
|
||||
src={images['setting-up-docsearch'].crawler}
|
||||
src={
|
||||
'/images/p/setting-up-docsearch-for-nextjs/cannot-login-to-algolia-crawler.png'
|
||||
}
|
||||
alt="Can't login to Algolia Crawler"
|
||||
width="586"
|
||||
height="131"
|
||||
/>
|
||||
|
||||
So i need find another way to generate my post index.
|
||||
@ -39,7 +43,12 @@ The DocSearch frontend UI read result as specific format. We just need to provid
|
||||
|
||||
Then DocSearch fronted UI can works.
|
||||
|
||||
<Image src={images['setting-up-docsearch'].indexFormat} alt="Index format" />
|
||||
<Image
|
||||
src={'/images/p/setting-up-docsearch-for-nextjs/index-format.png'}
|
||||
alt="Index format"
|
||||
width="516"
|
||||
height="197"
|
||||
/>
|
||||
|
||||
So we need post same format to Algolia.
|
||||
|
||||
|
@ -0,0 +1,90 @@
|
||||
export const genericApp = `import "./styles.css";
|
||||
import Child from "./Child";
|
||||
|
||||
const testData = {
|
||||
name: "xfy",
|
||||
age: 18
|
||||
};
|
||||
|
||||
export default function App() {
|
||||
return (
|
||||
<div className="App">
|
||||
<h1>Hello CodeSandbox</h1>
|
||||
<h2>Start editing to see some magic happen!</h2>
|
||||
|
||||
<div>
|
||||
<Child data={testData} name="name" />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}`;
|
||||
|
||||
export const genericChild = `import { useState } from "react";
|
||||
|
||||
type Props<T extends Record<string, unknown>> = {
|
||||
name: keyof T;
|
||||
data: T;
|
||||
};
|
||||
|
||||
const Child = <T extends Record<string, unknown>>({ name, data }: Props<T>) => {
|
||||
const [showName, setShowName] = useState<T[keyof T]>();
|
||||
const valid = () => {
|
||||
console.log(data[name]);
|
||||
setShowName(data[name]);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div>{name}</div>
|
||||
<button onClick={valid}>Show {name}</button>
|
||||
|
||||
<div>{JSON.stringify(showName)}</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default Child;`;
|
||||
|
||||
export const hookApp = `import { useForm } from 'react-hook-form';
|
||||
|
||||
type Pet = 'Cat' | 'Dog';
|
||||
type FormData = {
|
||||
firstName: string;
|
||||
lastName: string;
|
||||
favorite: Pet;
|
||||
};
|
||||
|
||||
export default function App() {
|
||||
const {
|
||||
register,
|
||||
handleSubmit,
|
||||
formState: { errors },
|
||||
} = useForm<FormData>();
|
||||
const onSubmit = handleSubmit((data) => console.log(data));
|
||||
|
||||
return (
|
||||
<div>
|
||||
<form onSubmit={onSubmit}>
|
||||
<div>
|
||||
<label htmlFor="firstname">First name:</label>
|
||||
<input type="text" id="firstname" {...register('firstName')} />
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label htmlFor="lastname">Last name:</label>
|
||||
<input type="text" id="lastname" {...register('lastName')} />
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label htmlFor="favorite">Favorite pet:</label>
|
||||
<select id="favorite" {...register('favorite')}>
|
||||
<option value="cat">Cat</option>
|
||||
<option value="dog">Dog</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<button>Submit</button>
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
}`;
|
Reference in New Issue
Block a user