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 Image from 'components/mdx/Image';
|
||||||
import Tab from 'components/RUA/tab';
|
import Tab from 'components/RUA/tab';
|
||||||
import TabItem from 'components/RUA/tab/TabItem';
|
import TabItem from 'components/RUA/tab/TabItem';
|
||||||
|
import RUACodeSandbox from 'components/RUA/RUACodeSandbox';
|
||||||
|
|
||||||
const components = {
|
const components = {
|
||||||
RUASandpack,
|
RUASandpack,
|
||||||
@ -10,6 +11,7 @@ const components = {
|
|||||||
Image,
|
Image,
|
||||||
Tab,
|
Tab,
|
||||||
TabItem,
|
TabItem,
|
||||||
|
RUACodeSandbox,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default components;
|
export default components;
|
||||||
|
@ -4,13 +4,11 @@ import {
|
|||||||
main2,
|
main2,
|
||||||
styles,
|
styles,
|
||||||
} from 'data/sandpack/how-to-load-a-background-with-threejs';
|
} from 'data/sandpack/how-to-load-a-background-with-threejs';
|
||||||
|
import {
|
||||||
import skybox_example from 'public/images/p/how-to-load-a-background-with-threejs/Skybox_example.png';
|
genericApp,
|
||||||
import crawler from 'public/images/p/setting-up-docsearch-for-nextjs/cannot-login-to-algolia-crawler.png';
|
genericChild,
|
||||||
import indexFormat from 'public/images/p/setting-up-docsearch-for-nextjs/index-format.png';
|
hookApp,
|
||||||
import windowsEnv from 'public/images/p/my-develop-environmental/windows-environmentail.png';
|
} from './sandpack/generic-component-encapsulate-reusable-component';
|
||||||
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';
|
|
||||||
|
|
||||||
const data = {
|
const data = {
|
||||||
sandpack: {
|
sandpack: {
|
||||||
@ -18,22 +16,9 @@ const data = {
|
|||||||
'load-background-main': main,
|
'load-background-main': main,
|
||||||
'load-background-main2': main2,
|
'load-background-main2': main2,
|
||||||
'load-background-styles': styles,
|
'load-background-styles': styles,
|
||||||
},
|
'generic-app': genericApp,
|
||||||
images: {
|
'generic-child': genericChild,
|
||||||
'load-background': {
|
'generic-hookApp': hookApp,
|
||||||
skybox_example,
|
|
||||||
},
|
|
||||||
'setting-up-docsearch': {
|
|
||||||
crawler,
|
|
||||||
indexFormat,
|
|
||||||
},
|
|
||||||
'dev-env': {
|
|
||||||
windowsEnv,
|
|
||||||
},
|
|
||||||
miniRouter: {
|
|
||||||
miniRouter1,
|
|
||||||
miniRouter4,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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 应用路由
|
## 现代前端的 Web 应用路由
|
||||||
|
|
||||||
@ -117,7 +123,12 @@ export default Router;
|
|||||||
|
|
||||||
现在我们直接从地址栏访问对应的路由,我们的 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]
|
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 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 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';
|
import child from 'assets/sandpack/generic-component-encapsulate-reusable-component/react-generic/Child.ts';
|
||||||
@ -51,7 +36,7 @@ React Hook Forms 对 TypeScript 支持良好,有了 TypeScript 我们就可以
|
|||||||
<RUASandpack
|
<RUASandpack
|
||||||
template="react-ts"
|
template="react-ts"
|
||||||
files={{
|
files={{
|
||||||
'/App.tsx': app,
|
'/App.tsx': sandpack['generic-hookApp'],
|
||||||
}}
|
}}
|
||||||
customSetup={{
|
customSetup={{
|
||||||
dependencies: {
|
dependencies: {
|
||||||
@ -116,7 +101,14 @@ const Input = ({ name, label, ...rest }: FormInputProps) => {
|
|||||||
|
|
||||||
但是如果仅仅只是这样,我们的组件还不能与 React Hook Forms 一起工作。因为其核心部分 `register` 函数还无法传递给我们的 `Input` 组件。也就是说我们的组件现在还是不可控的,这时候再尝试提交就会发现无法获取其状态。
|
但是如果仅仅只是这样,我们的组件还不能与 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` 函数会根据表单的数据签名和不同的表单项来实现自己的签名。
|
当然我们不能简单的将 `register` 函数塞给 `Input` 组件,因为它还没有合适的签名。`register` 函数会根据表单的数据签名和不同的表单项来实现自己的签名。
|
||||||
|
|
||||||
@ -188,15 +180,36 @@ const sayIt = <T extends number | string>(p: Person<T>) => {
|
|||||||
|
|
||||||
当指定参数为 `p: Person<T>` 时,就需要将函数的泛型传递给类型别名。且类型别名中的泛型约束在了 `<T extends number | string>` 之间,函数必须保证使其子类型。否则就会提示无法满足其类型。
|
当指定参数为 `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` 类型的子类型。
|
和参数类型,泛型也是向下兼容的,只要保证其类型是子类型即可。也就是说这样也是可以的 `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 中的泛型
|
### React 中的泛型
|
||||||
|
|
||||||
@ -207,8 +220,8 @@ const sayIt = <T extends number | string>(p: Person<T>) => {
|
|||||||
<RUASandpack
|
<RUASandpack
|
||||||
template="react-ts"
|
template="react-ts"
|
||||||
files={{
|
files={{
|
||||||
'/App.tsx': app2,
|
'/App.tsx': sandpack['generic-app'],
|
||||||
'/Child.tsx': child,
|
'/Child.tsx': sandpack['generic-child'],
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
@ -229,7 +242,14 @@ const testData = {
|
|||||||
|
|
||||||
但不仅如此,我们还希望我们的子组件能够根据已经存在的值,推断出我们能够传递的 key。
|
但不仅如此,我们还希望我们的子组件能够根据已经存在的值,推断出我们能够传递的 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` 属性的类型。
|
得益于泛型的功劳,我们将 `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>` 。这才使得我们的组件成功接受到了泛型。
|
这是因为 `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.
|
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.
|
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 环境则需要在“设置”-“高级系统设置”-“环境变量”中添加对应的变量到用户/系统变量中。
|
对于 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` 中,以后更新还会用到的。
|
当然这几个主要的变量可以放在 `.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.
|
But i can't login with my Algolia account.
|
||||||
|
|
||||||
<Image
|
<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"
|
alt="Can't login to Algolia Crawler"
|
||||||
|
width="586"
|
||||||
|
height="131"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
So i need find another way to generate my post index.
|
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.
|
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.
|
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