React List - React Router

React.js

Create by jsliang on 2019-04-26 13:13:18
Recently revised in 2019-04-29 15:25:01

Привет друзья, если вы считаете, что эта статья неплохая, не забудьте датьstar, друзья моиstarЭто моя мотивация продолжать обновлять!Адрес GitHub


【2019-08-16】Привет друзья, потому чтоjsliangБиблиотека документации подверглась рефакторингу, некоторые ссылки в этой статье могут быть неработоспособны, иjsliangИзвините за отсутствие сил поддерживать старые статьи на стороне Наггетс. Для тех, кому нужно получать последние статьи, щелкните адрес GitHub выше и перейдите в библиотеку документов, чтобы просмотреть скорректированные статьи.


каталог

Чем отличается передок без закидывания от соленой рыбы?

содержание
каталог
2 Предисловие
Три первых теста
Четыре Введение
Five BrowserРоутер
5.1 Синтаксис BrowserRouter
5.2 BrowserRouter - basename
5.3 BrowserRouter - getUserConfirmation
5.4 BrowserRouter - forceRefresh
5.5 BrowserRouter - keyLength
Шесть HashRouter
6.1 HashRouter - basename
6.2 HashRouter - getUserConfirmation
6.3 HashRouter - hashType
Семь ссылок
7.1 Link - to
7.2 Link - replace
7.3 Link - other
Восемь NavLink
8.1 NavLink - activeClassName
8.2 NavLink - activeStyle
8.3 NavLink - exact
8.4 NavLink - isActive
Девять ПамятиМаршрутизатор
9.1 MemoryRouter - initialEntries
9.2 MemoryRouter - initialIndex
9.3 MemoryRouter - getUserConfirmation
9.4 MemoryRouter - keyLength
10 Перенаправление
10.1 Redirect - from
10.2 Redirect - to
10.3 Redirect - push
10.4 Redirect - exact
Одиннадцатый маршрут
11.1 Route - component
11.2 Route - render
11.3 Route - children
11.4 Route - path
11.5 Route - exact
11.6 Route - location
11.7 Route - sensitive
Двенадцать переключателей
Тринадцать статей первая: история
Часть 14, Часть 2: Разделение кода
Часть 15: Прокрутите вверх
15.1 Пролистнуть вверх после перехода по страницам
15.2 Прокрутите вверх
Шестнадцать статей четыре: Redux
17 Резюме

2 Предисловие

Назад к содержанию

Под внешней маршрутизацией понимается изменение формы URL-пути для переключения на другую страницу, например:

  • localhost:3000/home
  • localhost:3000/user

Переключая разные URL-адреса для отображения разных страниц, мымаршрутизацияКонцепция чего-либо.

В этой статье мы объясним, как гибко использовать плагин React Router в React.

jsliangBaidu лучше обманутьВнешняя маршрутизацияЧто это такое.

  • Использованная литература:
  1. Официальная документация React Router
  2. Документация React Router на китайском языке
  3. Документация React Router на китайском языке (старая)
  4. React Router DOM Документация на китайском языке (1) - Ищу программиста
  5. Документация React Router DOM на китайском языке (2) - Ищут программиста
  • Темы не по теме:

В Интернете есть много статей о React Router, например:

ЗачемjsliangДелать это несколько раз?

  1. Вы записываете свое, а я записываю свое, не мешая друг другу.
  2. Их просмотр ничем не отличается от чтения официального сайта, поэтому мне нужно пройти через официальный сайт самостоятельно.
  3. Запишите то, что я прочитал на официальном сайте, и, кстати, запишите примеры моего приложения, чтобы я мог просмотреть его в следующий раз.

Три первых теста

Назад к содержанию

текущая версия:"react-router-dom": "^5.0.0"

первый, в Create React App мы ссылаемся на React Router:

  • npm i react-router-dom -S

потом, создайте новые страницы в каталоге src для хранения страниц и измените App.js:

Кейс: App.js

import React, { Fragment } from 'react';
import { BrowserRouter, Route, Switch, Redirect } from 'react-router-dom';
import ScrollToTop from './components/ScrollToTop';
import Header from './components/Header';
import TimeLine from './pages/TimeLine';
import NotFound from './pages/404';

function App() {
  return (
    <Fragment>
      <BrowserRouter>
        <Header />
        <ScrollToTop>
          <Switch>
            <Redirect from="/" to="/timeline" exact />
            <Route path="/timeline" component={TimeLine}></Route>
            <Route component={NotFound}></Route>
          </Switch>
        </ScrollToTop>
      </BrowserRouter>
    </Fragment>
  );
}

export default App;

наконец, Определив это в App.js, можно определить соответствующий компонент, а соответствующую страницу можно отобразить и перейти.

Четыре Введение

Назад к содержанию

Ниже мы представляем некоторые часто используемые:

import { 
  BrowserRouter,
  HashRouter,
  Redirect,
  Route,
  NavLink,
  Link,
  MemoryRouter,
  Switch,
  withRouter
} from "react-router-dom";
  1. <BrowserRouter>: Слой оболочки компонента маршрутизации.<Route>а также<Link>обертывающий слой.
  2. <HashRouter>: Слой оболочки компонента маршрутизации. относительно<BrowserRouter>Например, сервер, который больше подходит для статических файлов.
  3. <Redirect>: перенаправление маршрута. оказывать<Redirect>перейдет на новый адрес.
  4. <Route>: маршрутизация. Определите страницу маршрутизации, соответствующую соответствующему компоненту (Component) и пути маршрутизации.
  5. <NavLink>: Активная ссылка. Когда путь в URL-адресе равен пути, определенному этим маршрутом, тег может отображать путь, который он определяет.activeClassName.
  6. <Link>:Связь. прыгать к<Route>В соответствующем маршруте (Компоненте).
  7. <MemoryRouter>: Пока не используется.<Router>можно сохранить в памятиURLистория. Отлично подходит для использования в тестовых средах и средах без браузера, таких как React Native.
  8. <Switch>: Группировка маршрутов. визуализировать первый дочерний элемент, соответствующий этому адресу<Route>или<Redirect>. годный к употреблению<Switch>Займитесь группировкой.
  9. <withRouter>: Комбинация маршрутизации. пройти через<withRouter>Доступ к компонентам более высокого порядкаhistoryсвойства объекта и ближайшие<Route>изmatch. Или используйте его в сочетании с Redux.

Five BrowserРоутер

Назад к содержанию

<BrowserRouter>Для вас будет создан специальный объект истории для записи вашего маршрута, чтобы вы могли вернуться на предыдущую страницу или перейти на указанную страницу маршрута.

отличный от<HashRouter>, используется, когда есть сервер, который отвечает на запрос<BrowserRouter>, используя сервер для статических файлов, используйте<HashRouter>.

Простой случай:

<BrowserRouter>
  <Header />
  <Route path="/" exact component={TimeLine}></Route>
  <Route path="/timeline" component={TimeLine}></Route>
</BrowserRouter>

5.1 Синтаксис BrowserRouter

Назад к содержанию

import { BrowserRouter } from 'react-router-dom'

<BrowserRouter
  basename={optionalString}
  forceRefresh={optionalBool}
  getUserConfirmation={optionalFunc}
  keyLength={optionalNumber}
>
  <App/>
</BrowserRouter>

5.2 BrowserRouter - basename

Назад к содержанию

  • правило:basename: string

Укажите базовый путь для подкаталогов внутри, например:

<BrowserRouter basename="/calendar">
  <Link to="/today"/> 
  {/* 渲染为 <a href="/calendar/today"> */}
</BrowserRouter>

5.3 BrowserRouter - getUserConfirmation

Назад к содержанию

  • правило:getUserConfirmation: function

Функция подтверждения навигации.

// 默认使用 window.confirm。
const getConfirmation = (message, callback) => {
  const allowTransition = window.confirm(message)
  callback(allowTransition)
}

<BrowserRouter getUserConfirmation={getConfirmation}/>

5.4 BrowserRouter - forceRefresh

Назад к содержанию

  • правило:forceRefresh: bool

Если true, маршрутизатор будет использовать полное обновление страницы при навигации по страницам.

const supportsHistory = 'pushState' in window.history
<BrowserRouter forceRefresh={!supportsHistory}/>

5.5 BrowserRouter - keyLength

Назад к содержанию

  • правило:keyLength: number

настроить маршрутизацию в немlocation.keyдлина. По умолчанию 6.

Роль ключа: при переходе по одной и той же ссылке, location.key под маршрутом каждый раз будет меняться, и страницу можно обновить через смену ключа.

<BrowserRouter keyLength={12}/>

Шесть HashRouter

Назад к содержанию

использоватьURLизhashчасть (т.е.window.location.hash)из<Router>СделатьUIа такжеURLсинхронизироваться.

важный намек:HashИстория не поддерживаетсяlocation.keyилиlocation.state.

import { HashRouter } from 'react-router-dom'

<HashRouter>
  <App/>
</HashRouter>

6.1 HashRouter - basename

Назад к содержанию

  • правило:basename: string

Базовый для всех локацийURL, правильно сформированное базовое имя должно иметь косую черту в начале, но не косую черту в конце.

<HashRouter basename="/calendar"/>
<Link to="/today"/> 
{/* 渲染为 <a href="/calendar/today"> */}

6.2 HashRouter - getUserConfirmation

Назад к содержанию

  • правило:getUserConfirmation: func

Функция подтверждения навигации. Window.Confirm используется по умолчанию.

// this is the default behavior
const getConfirmation = (message, callback) => {
  const allowTransition = window.confirm(message)
  callback(allowTransition)
}

<HashRouter getUserConfirmation={getConfirmation}/>

6.3 HashRouter - hashType

Назад к содержанию

  • правило:hashType: string

используется дляwindow.location.hashтип кодирования. Доступные значения:

  • slash- Создайте#/а также#/sunshine/lollipops
  • noslash- Создайте#а также#sunshine/lollipops
  • hashbang- Создайтеajax crawlable,Такие как#!/а также#!/sunshine/lollipops

По умолчаниюslash.

Семь ссылок

Назад к содержанию

Обеспечьте декларативную, доступную навигацию по вашему приложению.

7.1 Link - to

Назад к содержанию

  • Правило 1:to: string

Строковое представление местоположения ссылки, искомое и по имени пути к местоположению ссылкиhashсоздание собственности.

<Link to='/courses?sort=name'>字符串形式跳转</Link>
  • Правило 2:to: object

Объект, который может иметь любое из следующих свойств:

  • pathname: строка, представляющая путь для ссылки.
  • search: представляет строковую форму параметра запроса.
  • hash: введите URLhash,Например#a-hash.
  • state: статус длится доlocation.
<Link to={{
  pathname: '/courses',          // 基础路径
  search: '?sort=name',          // 匹配字段
  hash: '#the-hash',             // 对应内链
  state: { fromDashboard: true } // 未知
}}>
  对象形式跳转
</Link>

7.2 Link - replace

Назад к содержанию

  • правило:replace: bool

еслиtrue, щелчок по ссылке заменяет текущую запись в стеке истории, а не добавляет новую запись.

<Link to="/courses" replace>替换当前 hash 路径</Link>

7.3 Link - other

Назад к содержанию

Вы также можете пройти<a>атрибуты, такие как заголовок,ID,classNameЖдать.

<Link to="/test" id="myTest">测试 1</Link>

Назад к содержанию

Восемь NavLink

Назад к содержанию

Специальная версия Link, которая добавляет атрибуты стиля к отображаемым элементам, когда она соответствует текущему URL-адресу.

  • Выделите главную страницу:<NavLink to="/timeline" activeClassName="active">首页</NavLink>

8.1 NavLink - activeClassName

Назад к содержанию

  • правило:activeClassName: string

Когда класс элемента, который должен быть задан, активен. Данный класс по умолчаниюactive. это будет сclassNameсвойства вместе.

<NavLink
  to="/faq"
  activeClassName="selected"
>FAQs</NavLink>

8.2 NavLink - activeStyle

Назад к содержанию

  • правило:activeStyle: object

Стиль, применяемый к элементу, когда он активен.

<NavLink
  to="/faq"
  activeStyle={{
    fontWeight: 'bold',
    color: 'red'
   }}
>FAQs</NavLink>

8.3 NavLink - exact

Назад к содержанию

  • правило:exact: bool

еслиtrue, применяется только в том случае, если местоположение точно совпадаетactiveкласс/стиль.

<NavLink
  exact
  to="/profile"
>Profile</NavLink>

8.4 NavLink - isActive

Назад к содержанию

  • правило:isActive: function

Функция, которая добавляет дополнительную логику, чтобы определить, активна ли ссылка. Ее следует использовать, если вы хотите сделать больше, чем просто проверить, соответствует ли путь ссылки текущему пути URL.

// 如果链接不仅仅匹配 events/123,而是所有奇数链接都匹配
const oddEvent = (match, location) => {
  if (!match) {
    return false
  }
  const eventID = parseInt(match.params.eventID)
  return !isNaN(eventID) && eventID % 2 === 1
}

<NavLink
  to="/events/123"
  isActive={oddEvent}
>Event 123</NavLink>

Девять ПамятиМаршрутизатор

Назад к содержанию

<Router>можно сохранить в памятиURLистория (не читает и не пишет в адресную строку). Отлично подходит для использования в тестовых средах и средах без браузера, таких как React Native.

<MemoryRouter>
  <App/>
</MemoryRouter>

9.1 MemoryRouter - initialEntries

Назад к содержанию

  • правило:initialEntries: array

historyодин из стекаlocationмножество. Они могут иметь{ pathname, search, hash, state }или простойURLПолный адрес объекта строки.

<MemoryRouter
  initialEntries={[ '/one', '/two', { pathname: '/three' } ]}
  initialIndex={1}
>
  <App/>
</MemoryRouter>

9.2 MemoryRouter - initialIndex

Назад к содержанию

  • правило:initialIndex: number

существуетinitialEntriesИндекс адреса инициализации в массиве.

9.3 MemoryRouter - getUserConfirmation

Назад к содержанию

  • правило:getUserConfirmation: function

Функция подтверждения навигации. В использовании<MemoryRouter>, использовать напрямую<Prompt>, вы должны использовать эту опцию.

9.4 MemoryRouter - keyLength

Назад к содержанию

  • правило:keyLength: number

location.keyдлина. По умолчанию 6.

10 Перенаправление

Назад к содержанию

оказывать<Redirect>перейдет на новый адрес. Этот новый адрес будет перезаписанhistoryТекущий адрес в стеке, аналогичный переадресации на стороне сервера (HTTP 3xx).

Мы можем установить маршрут для перенаправления на другой маршрут, например следующий/точное соответствие перенаправляет на/timelineстраница.

<Redirect from="/" to="/timeline" exact />

10.1 Redirect - from

Назад к содержанию

  • правило:from: string

перенаправитьfromпуть. может быть любымpath-to-regexpидентифицируемый эффективныйURLдорожка.

все совпаденияURLпараметры предоставляютсяtoрежим в .

должны быть включены вtoВсе параметры, используемые в .

toДругие неиспользуемые параметры будут игнорироваться.

<Switch>
  <Redirect from="/old-path" to="/new-path" />
  <Route path="/new-path" component={Place} />
</Switch>

10.2 Redirect - to

Назад к содержанию

  • правило:to: string

перенаправлен наURL, может быть любойpath-to-regexpпонятно и эффективноURLдорожка.

существуетtoиспользуется вURLПараметры должны быть указаныfromпокрытие.

<Redirect to="/somewhere/else" />
  • правило:to: object

перенаправлен наlocation,pathnameможет быть любымpath-to-regexpпонятно и эффективноURLдорожка.

<Redirect
  to={{
    pathname: "/login",
    search: "?utm=your+face",
    state: { referrer: currentLocation }
  }}
/>

10.3 Redirect - push

Назад к содержанию

  • правило:push: bool

когдаtrue, перенаправление подтолкнет новый адрес вhistoryВместо замены текущего адреса.

<Redirect push to="/somewhere/else" />

10.4 Redirect - exact

Назад к содержанию

  • правило:exact: bool

полное совпадениеfrom.

Одиннадцатый маршрут

Назад к содержанию

Пока местоположение приложения совпадает с путем маршрута, компонент будет отображаться.

11.1 Route - component

Назад к содержанию

Компонент React, который будет отображаться только в том случае, если позиция совпадает.

<Route path="/user/:username" component={User}/>

const User = ({ match }) => {
  return <h1>Hello {match.params.username}!</h1>
}

11.2 Route - render

Назад к содержанию

  • правило:render: function

Это обеспечивает удобный встроенный рендеринг и перенос, а не нежелательную переустановку, описанную выше.

Вместо того, чтобы использовать свойство для создания нового для вас, вы можете передать функцию, которая вызывается, когда позиция совпадаетReact element component,Долженrenderсвойства получают все равноroute propsизcomponentРендеринг свойств.

// 行内编写
<Route path="/home" render={() => <div>Home</div>}/>

// 包裹分开写
const FadingRoute = ({ component: Component, ...rest }) => (
  <Route {...rest} render={props => (
    <FadeIn>
      <Component {...props}/>
    </FadeIn>
  )}/>
)

<FadingRoute path="/cool" component={Something}/>

11.3 Route - children

Назад к содержанию

  • правило:children: function

Иногда вам нужно отобразить, соответствует ли путь положению. В этих случаях вы можете использовать функциюchildrenсвойство, оно работает точно так же, как рендеринг, разница в том, есть ли у него совпадение или нет.

childrenRender props получают все равноroute propsтак какcomponentа такжеrenderметод, еслиRouteа такжеURLНесоответствие,matchтогдаnull, что позволяет динамически настраиватьUIИнтерфейс, в зависимости от того, совпадает ли маршрут, если маршрут совпадает, мы добавляемactiveДобрый.

<ul>
  <ListItemLink to="/somewhere"/>
  <ListItemLink to="/somewhere-else"/>
</ul>

const ListItemLink = ({ to, ...rest }) => (
  <Route path={to} children={({ match }) => (
    <li className={match ? 'active' : ''}>
      <Link to={to} {...rest}/>
    </li>
  )}/>
)

11.4 Route - path

Назад к содержанию

  • правило:path: string

Любыеpath-to-regexpдопустимый для синтаксического анализаURLдорожка

<Route path="/users/:id" component={User}/>

11.5 Route - exact

Назад к содержанию

  • правило:exact: bool

еслиtrue, то только если путь точно совпадаетlocation.pathnameсовпадают, когда.

path location.pathname exact matches?
/one /one/two true no
/one /one/two false yes
<Route exact path="/one" component={About}/>

jsliangличный опыт:

  1. ДобавленexactПосле атрибута он будет полностью соответствовать пути, если его не добавить, то вторичный путь также будет соответствовать текущему пути (например/timeline/book).
<BrowserRouter>
  <Route path="/" exact component={TimeLine}></Route>
  <Route path="/timeline" component={TimeLine}></Route>
</BrowserRouter>
  1. Мы можем динамически установитьextraзначение, чтобы определить, нужно ли загружать компонент.
const Home = () => <div>Home</div>;

const App = () => {
  const someVariable = true;

  return (
    <Switch>
      {/* these are good */}
      <Route exact path="/" component={Home} />
      <Route
        path="/about"
        render={props => <About {...props} extra={someVariable} />}
      />
      {/* do not do this */}
      <Route
        path="/contact"
        component={props => <Contact {...props} extra={someVariable} />}
      />
    </Switch>
  );
};

11.6 Route - location

Назад к содержанию

  • правило:location: object

Один<Route>элемент пытается найти совпадениеpathк текущему историческому местоположению (обычно это текущий URL-адрес браузера). Тем не менее, также возможно пройти другое местоpathnameсоответствовать.

11.7 Route - sensitive

Назад к содержанию

  • правило:sensitive: bool

Если путь чувствителен к регистру, тоtrue, совпадает.

path location.pathname sensitive matches?
/one /one true yes
/One /one true no
/One /one false yes
<Route sensitive path="/one" component={About}/>

Двенадцать переключателей

Назад к содержанию

визуализировать первый дочерний элемент, соответствующий этому адресу<Route>или<Redirect>.

годный к употреблению<Switch>Делать группировку, то есть при совпадении сопоставлять соответствующиеpathсоответствующий компонент; если совпадения нет, сопоставьтеNotFoundстраница.

<BrowserRouter>
  <Header />
  <Switch>
    <Route path="/" exact component={TimeLine}></Route>
    <Route path="/timeline" component={TimeLine}></Route>
    <Route component={NotFound}></Route>
  </Switch>
</BrowserRouter>

Тринадцать статей первая: история

Назад к содержанию

historyэто пакет, когда вы устанавливаете React Router, он будет установлен в проект как его зависимый пакет, поэтому вы можете использовать его напрямуюhistoryСвойства и методы в:

  • length - (numberТипы)historyколичество записей в стеке
  • action - (stringтип) текущая операция (push, replace, pop)
  • location - (objectтип) текущее местоположение.locationбудет иметь следующие свойства:
    • pathname - (stringтип) URL-адрес
    • search - (stringtype) строка запроса в URL
    • hash - (stringtype) хэш-фрагмент URL-адреса
    • state - (objectтип), предназначенный, например, для использованияpush(path, state)операция будет
  • locationконкретный, когда помещается в стекlocationусловие. Доступно только в истории браузера и памяти
  • push(path, [state]) - (functionвведитеhistoryДобавить новую запись в стек
  • replace(path, [state]) - (functionтип) заменяется наhistoryтекущая запись в стеке
  • go(n) - (functionтипа) будетhistoryкорректировка указателя в стекеn
  • goBack() - (functionтип) эквивалентенgo(-1)
  • goForward() - (functionтип) эквивалентенgo(1)
  • block(prompt) - (functionтип) блок прыжок

Часть 14, Часть 2: Разделение кода

Назад к содержанию

По мере роста приложения растет и пакет кода.

В конце концов вы обнаружите, что ваши упакованные файлы js слишком велики.

Поэтому нам нужно разделить код и загрузить разные js-файлы по разным маршрутам.

  1. Установите загружаемый React:npm i react-loadable -S
  2. Разделение кода с помощью React Router и React Loadable:
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import Loadable from 'react-loadable';

const Loading = () => <div>Loading...</div>;

const Home = Loadable({
  loader: () => import('./routes/Home'),
  loading: Loading,
});

const About = Loadable({
  loader: () => import('./routes/About'),
  loading: Loading,
});

const App = () => (
  <Router>
    <Switch>
      <Route exact path="/" component={Home}/>
      <Route path="/about" component={About}/>
    </Switch>
  </Router>
);
  1. Упаковка проекта:npm run build

Часть 15: Прокрутите вверх

Назад к содержанию

15.1 Пролистнуть вверх после перехода по страницам

Назад к содержанию

  1. первый, определите папку ScrollToTop в файле глобальных компонентов, где содержимое index.js:

src/components/ScrollToTop/index.js

import { Component } from 'react';
import { withRouter } from 'react-router-dom';

class ScrollToTop extends Component {
    componentDidUpdate(prevProps) {
        if (this.props.location !== prevProps.location) {
          window.scrollTo(0, 0)
        }
    }
    render() {
        return this.props.children
    }
}
 
export default withRouter(ScrollToTop);
  1. потом, используйте функцию ScrollToTop в App.js или на других страницах:

src/App.js

import React, { Fragment } from 'react';
import { BrowserRouter, Route, Switch, Redirect } from 'react-router-dom';
import ScrollToTop from './components/ScrollToTop';
import Header from './components/Header';
import TimeLine from './pages/TimeLine';
import NotFound from './pages/404';

function App() {
  return (
    <Fragment>
      <BrowserRouter>
        <Header />
        <ScrollToTop>
          <Switch>
            <Redirect from="/" to="/timeline" exact />
            <Route path="/timeline" component={TimeLine}></Route>
            <Route component={NotFound}></Route>
          </Switch>
        </ScrollToTop>
      </BrowserRouter>
    </Fragment>
  );
}

export default App;
  1. наконец, когда мы переключаем маршруты, страница будет прокручиваться вверх.

15.2 Прокрутите вверх

Назад к содержанию

Еще не реализовано

Шестнадцать статей четыре: Redux

Назад к содержанию

В проекте мы предпочитаем совмещать React Router и React Redux, на данный момент мы можем:

// before
export default connect(mapStateToProps)(Something)

// after
import { withRouter } from 'react-router-dom'
export default withRouter(connect(mapStateToProps)(Something))

17 Резюме

Назад к содержанию

Если вы чисто за документацию (официальную документацию,jsliangДокументы), вы найдете его неинтересным, неинтересным, скучным, скучным ...

так,jsliangМетод обучения: откройте проект, пролистайте документ, примените его к проекту и отметьте для следующего использования.

Итак, документ закончен, но еще не закончен! Последнее, что я закончил с официальной документацией, а незаконченное — это то, что у React Router могут быть другие приложения в моем проекте, и мне нужно добавлять их по одному.


jsliangРекламный толчок:
Может быть, друг хочет узнать об облачных серверах
Или друг хочет купить облачный сервер
Или маленькому партнеру необходимо обновить облачный сервер
Добро пожаловать, чтобы нажатьПродвижение облачного сервераПроверить!

知识共享许可协议
библиотека документации jsliangЗависит отЛян ЦзюньронгиспользоватьCreative Commons Attribution-NonCommercial-ShareAlike 4.0 Международная лицензияЛицензия.
на основеGitHub.com/l ian Jun Ron…Создание работ выше.
Права на использование, отличные от разрешенных в настоящем Лицензионном соглашении, могут быть получены отCreative Commons.org/licenses/не…получено в.