最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 重读React官网doc需要注意并记住的点

    正文概述 掘金(依依amelie)   2021-03-02   630

    1、React DOM为什么使用camelCase来定义属性的名称?

    2、JSX 防止注入攻击

    你可以安全地在 JSX 当中插入用户输入内容:

    const title = response.potentiallyMaliciousInput;
    // 直接使用是安全的:
    const element = <h1>{title}</h1>;
    

    React DOM 在渲染所有输入内容之前,默认会进行转义。它可以确保在你的应用中,永远不会注入那些并非自己明确编写的内容。所有的内容在渲染之前都被转换成了字符串。这样可以有效地防止 XSS(cross-site-scripting, 跨站脚本)攻击。

    3、React元素与组件的关系

    与浏览器的 DOM 元素不同,React 元素是创建开销极小的普通对象。React DOM 会负责更新 DOM 来与 React 元素保持一致。

    元素是构成 React 应用的最小砖块。元素描述了你在屏幕上想看到的内容。

    const element = <h1>Hello, world</h1>;
    

    组件是由元素构成的。

    4、“根” DOM 节点由 React DOM 管理

    假设你的 HTML 文件某处有一个 <div>

    <div id="root"></div>
    

    我们将其称为“根” DOM 节点,因为该节点内的所有内容都将由 React DOM 管理。 想要将一个 React 元素渲染到根 DOM 节点中,只需把它们一起传入 ReactDOM.render()

    const element = <h1>Hello, world</h1>;
    ReactDOM.render(element, document.getElementById('root'));
    

    5、React元素为不可变对象

    React 元素是不可变对象。一旦被创建,你就无法更改它的子元素或者属性。 一个元素就像电影的单帧:它代表了某个特定时刻的 UI。

    根据我们已有的知识,更新 UI 唯一的方式是创建一个全新的元素,并将其传入 ReactDOM.render()

    在实践中,大多数 React 应用只会调用一次 ReactDOM.render()

    6、React 只更新它需要更新的部分

    React DOM 会将元素和它的子元素与它们之前的状态进行比较,并只会进行必要的更新来使 DOM 达到预期的状态。

    7、组件

    函数组件 与 class 组件

    函数组件:该函数是一个有效的 React 组件,因为它接收唯一带有数据的 “props”(代表属性)对象与并返回一个 React 元素。这类组件被称为“函数组件”,因为它本质上就是 JavaScript 函数。

    function Welcome(props) {
      return <h1>Hello, {props.name}</h1>;
    }
    

    ES6 class组件

    class Welcome extends React.Component {
      render() {
        return <h1>Hello, {this.props.name}</h1>;
      }
    }
    

    原生DOM 标签组件 与 用户自定义的组件

    原生DOM 标签组件

    const element = <div />;
    

    用户自定义的组件:

    const element = <Welcome name="Sara" />;
    

    组合组件 与 提取组件

    组件可以在其输出中引用其他组件,通常来说,每个新的 React 应用程序的顶层组件都是 App 组件。

    function Welcome(props) {
      return <h1>Hello, {props.name}</h1>;
    }
    
    function App() {
      return (
        <div>
          <Welcome name="Sara" />
          <Welcome name="Cahal" />
          <Welcome name="Edite" />
        </div>
      );
    }
    
    ReactDOM.render(
      <App />,
      document.getElementById('root')
    );
    

    提取组件,将组件拆分为更小的组件。 最初看上去,提取组件可能是一件繁重的工作,但是,在大型应用中,构建可复用组件库是完全值得的。根据经验来看,如果 UI 中有一部分被多次使用(Button,Panel,Avatar),或者组件本身就足够复杂(App,FeedStory,Comment),那么它就是一个可提取出独立组件的候选项。

    8、Props 的只读性

    组件无论是使用函数声明还是通过 class 声明,都决不能修改自身的 props。这样的函数被称为“纯函数”,因为该函数不会尝试更改入参,且多次调用下相同的入参始终返回相同的结果。

    9、state

    在不违反上述props的规则的情况下,state 允许 React 组件随用户操作、网络响应或者其他变化而动态更改输出内容。

    函数组件改成class组件步骤

    function Clock(props) {
      return (
        <div>
          <h1>Hello, world!</h1>
          <h2>It is {props.date.toLocaleTimeString()}.</h2>
        </div>
      );
    }
    
    function tick() {
      ReactDOM.render(
        <Clock date={new Date()} />,
        document.getElementById('root')
      );
    }
    
    setInterval(tick, 1000);
    
    1. 通过以下五步将 Clock 的函数组件转成 class 组件
      • 创建一个同名的 ES6 class,并且继承于 React.Component
      • 添加一个空的 render() 方法。
      • 将函数体移动到 render() 方法之中。
      • render() 方法中使用 this.props 替换 props
      • 删除剩余的空函数声明。
    2. 向 class 组件中添加局部的 state,通过以下三步将 date 从 props 移动到 state 中:
      • render() 方法中的 this.props.date 替换成 this.state.date
      • 添加一个 class 构造函数,然后在该函数中为 this.state 赋初值,通过以下方式将 props 传递到父类的构造函数中的super函数里。Class 组件应该始终使用 props 参数来调用父类的构造函数
      • 移除 元素中的 date 属性
    3. 将生命周期方法添加到 Class 中,为 class 组件声明一些特殊的方法,当组件挂载或卸载时就会去执行这些方法:
      • 当 Clock 组件第一次被渲染到 DOM 中的时候,就为其设置一个计时器。“挂载(mount)
        • componentDidMount() 方法会在组件已经被渲染到 DOM 中后运行,所以,最好在这里设置计时器
      • 同时,当 DOM 中 Clock 组件被删除的时候,应该清除计时器。“卸载(unmount)
      • 使用 this.setState() 来时刻更新组件 state
    class Clock extends React.Component {
      constructor(props) {
        super(props);
        this.state = {date: new Date()};
      }
    
      componentDidMount() {
        this.timerID = setInterval(
          () => this.tick(),
          1000
        );
      }
    
      componentWillUnmount() {
        clearInterval(this.timerID);
      }
    
      tick() {
        this.setState({
          date: new Date()
        });
      }
    
      render() {
        return (
          <div>
            <h1>Hello, world!</h1>
            <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
          </div>
        );
      }
    }
    
    ReactDOM.render(
      <Clock />,
      document.getElementById('root')
    );
    

    发生了什么和这些方法的调用顺序:

    1. <Clock /> 被传给 ReactDOM.render()的时候,React 会调用 Clock 组件的构造函数。因为 Clock 需要显示当前的时间,所以它会用一个包含当前时间的对象来初始化 this.state。我们会在之后更新 state。
    2. 之后 React 会调用组件的 render() 方法。这就是 React 确定该在页面上展示什么的方式。然后 React 更新 DOM 来匹配 Clock 渲染的输出。
    3. 当 Clock 的输出被插入到 DOM 中后,React 就会调用 ComponentDidMount() 生命周期方法。在这个方法中,Clock 组件向浏览器请求设置一个计时器来每秒调用一次组件的 tick() 方法。
    4. 浏览器每秒都会调用一次 tick() 方法。 在这方法之中,Clock 组件会通过调用 setState() 来计划进行一次 UI 更新。得益于 setState() 的调用,React 能够知道 state 已经改变了,然后会重新调用 render() 方法来确定页面上该显示什么 这一次,render() 方法中的 this.state.date 就不一样了,如此以来就会渲染输出更新过的时间。React 也会相应的更新 DOM。
    5. 一旦 Clock 组件从 DOM 中被移除,React 就会调用 componentWillUnmount() 生命周期方法,这样计时器就停止了。

    10、关于 setState() 你应该了解三件事:

    不要直接修改 State

    例如,此代码不会重新渲染组件:

    // Wrong
    this.state.comment = 'Hello';
    

    而是应该使用 setState():

    // Correct
    this.setState({comment: 'Hello'});
    

    State 的更新可能是异步的

    出于性能考虑,React 可能会把多个 setState() 调用合并成一个调用。

    因为 this.propsthis.state 可能会异步更新,所以你不要依赖他们的值来更新下一个状态。

    例如,此代码可能会无法更新计数器:

    // Wrong
    this.setState({
      counter: this.state.counter + this.props.increment,
    });
    

    要解决这个问题,可以让 setState() 接收一个函数而不是一个对象。这个函数用上一个 state 作为第一个参数,将此次更新被应用时的 props 做为第二个参数:

    // Correct
    this.setState((state, props) => ({
      counter: state.counter + props.increment
    }));
    

    上面使用了箭头函数,不过使用普通的函数也同样可以:

    // Correct
    this.setState(function(state, props) {
      return {
        counter: state.counter + props.increment
      };
    });
    

    State 的更新会被合并到当前state,并且是浅合并

    当你调用 setState() 的时候,React 会把你提供的对象合并到当前的 state。 例如,你的 state 包含几个独立的变量:

      constructor(props) {
        super(props);
        this.state = {
          posts: [],
          comments: []
        };
      }
    

    然后你可以分别调用 setState() 来单独地更新它们:

      componentDidMount() {
        fetchPosts().then(response => {
          this.setState({
            posts: response.posts
          });
        });
    
        fetchComments().then(response => {
          this.setState({
            comments: response.comments
          });
        });
      }
    

    这里的合并是浅合并,所以 this.setState({comments}) 完整保留了 this.state.posts, 但是完全替换了 this.state.comments

    11、为什么称 state 为局部的或是封装的?

    不管是父组件或是子组件都无法知道某个组件是有状态的还是无状态的,并且它们也并不关心它是函数组件还是 class 组件。

    除了拥有并设置了state的组件,其他组件都无法访问。

    12、数据是向下流动的

    组件可以选择把它的 state 作为 props 通过attribute方式向下传递到它的子组件中,子组件会在其 props 中接收通过attribute方式传进来的参数,但是组件本身无法知道它是来自于 父组件 的 state,或是 父组件 的 props,还是手动输入的。

    这通常会被叫做“自上而下”或是“单向”的数据流。任何的 state 总是所属于特定的组件,而且从该 state 派生的任何数据或 UI 只能影响树中“低于”它们的组件。

    如果你把一个以组件构成的树想象成一个 props 的数据瀑布的话,那么每一个组件的 state 就像是在任意一点上给瀑布增加额外的水源,但是它只能向下流动。

    13、组件实例都是真正独立的

    这三个<Clock />组件都是真正独立的。

    function App() {
      return (
        <div>
          <Clock />
          <Clock />
          <Clock />
        </div>
      );
    }
    
    ReactDOM.render(
      <App />,
      document.getElementById('root')
    );
    

    14、React事件处理 与 DOM事件处理 的不同点

    React 元素的事件处理和 DOM 元素的很相似,但是有一点语法上的不同:

    传统的 HTML

    <button onclick="activateLasers()">
      Activate Lasers
    </button>
    <a href="#" onclick="console.log('The link was clicked.'); return false">
      Click me
    </a>
    

    在 React 中略微不同

    函数组件中

    function ActionLink() {
      function handleClick(e) {                     // e 是一个合成事件
        e.preventDefault();
        console.log('The link was clicked.');
      }
    
      return (
        <div>
          <button onClick={activateLasers}>
            Activate Lasers
          </button>
          <a href="#" onClick={handleClick}>
            Click me
          </a>
        </div>
      );
    }
    

    class组件中(3种方法绑定this

    1. 将事件处理函数声明为 class 中的方法
    class Toggle extends React.Component {
      constructor(props) {
        super(props);
        this.state = {isToggleOn: true};
    
        // 为了在回调中使用 `this`,这个绑定是必不可少的
        this.handleClick = this.handleClick.bind(this);
      }
    
      handleClick() {
        this.setState(state => ({
          isToggleOn: !state.isToggleOn
        }));
      }
    
      render() {
        return (
        // this.handleClick这种调用方法必须在构造函数中绑定this
          <button onClick={this.handleClick}>      
            {this.state.isToggleOn ? 'ON' : 'OFF'}
          </button>
        );
      }
    }
    
    ReactDOM.render(
      <Toggle />,
      document.getElementById('root')
    );
    
    2. 如果觉得使用 bind 很麻烦,可以使用正在使用实验性的 public class fields 语法
    class LoggingButton extends React.Component {
      // 此语法确保 `handleClick` 内的 `this` 已被绑定。
      // 注意: 这是 *实验性* 语法。
      handleClick = () => {
        console.log('this is:', this);
      }
    
      render() {
        return (
          <button onClick={this.handleClick}>
            Click me
          </button>
        );
      }
    }
    
    3. 如果你没有使用 class fields 语法,你可以在回调中使用箭头函数
    class LoggingButton extends React.Component {
      handleClick() {
        console.log('this is:', this);
      }
    
      render() {
        // 此语法确保 `handleClick` 内的 `this` 已被绑定。
        return (
          <button onClick={() => this.handleClick()}>
            Click me
          </button>
        );
      }
    }
    

    15、如何向事件处理程序传递参数?

    若 id 是你要删除那一行的 ID,以下两种方式都可以向事件处理函数传递参数:

    <button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button>
    <button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>
    

    上述两种方式是等价的,分别通过箭头函数Function.prototype.bind 来实现。

    在这两种情况下,React 的事件对象 e 会被作为第二个参数传递。

    如果通过箭头函数的方式,事件对象必须显式的进行传递,而通过 bind 的方式,事件对象以及更多的参数将会被隐式的进行传递。

    16、条件渲染的三种方式

    1. if-else
    2. 与运算符 &&
    3. 三目运算符 condition ? true : false

    元素变量

    使用变量来储存元素。 它可以帮助你有条件地渲染组件的一部分,而其他的渲染部分并不会因此而改变。

    1. if-else

    LoginControl有状态的组件

    它将根据当前的状态来渲染 <LoginButton /> 或者 <LogoutButton />

    class LoginControl extends React.Component {
      constructor(props) {
        super(props);
        this.handleLoginClick = this.handleLoginClick.bind(this);
        this.handleLogoutClick = this.handleLogoutClick.bind(this);
        this.state = {isLoggedIn: false};
      }
    
      handleLoginClick() {
        this.setState({isLoggedIn: true});
      }
    
      handleLogoutClick() {
        this.setState({isLoggedIn: false});
      }
    
      render() {
        const isLoggedIn = this.state.isLoggedIn;
        let button;  // 元素变量
        if (isLoggedIn) {
          button = <LogoutButton onClick={this.handleLogoutClick} />;
        } else {
          button = <LoginButton onClick={this.handleLoginClick} />;
        }
    
        return (
          <div>
            <Greeting isLoggedIn={isLoggedIn} />
            {button}
          </div>
        );
      }
    }
    
    ReactDOM.render(
      <LoginControl />,
      document.getElementById('root')
    );
    

    2. 与运算符 &&

    通过花括号包裹代码,你可以在 JSX 中嵌入表达式。

    在 JavaScript 中,true && expression 总是会返回 expression, 而 false && expression 总是会返回 false

    因此,如果条件是 true,&& 右侧的元素就会被渲染,如果是 false,React 会忽略并跳过它。

    请注意,返回 false 的表达式会使 && 后面的元素被跳过,但会返回 false 表达式。在下面示例中,render 方法的返回值是 <div>0</div>

    function Mailbox(props) {
      const unreadMessages = props.unreadMessages;
      const count = 0;
      return (
        <div>
          <h1>Hello!</h1>
          { count && <h1>Messages: {count}</h1>}         // 返回值是`<h1>Hello!</h1> 0 ...`
          {unreadMessages.length > 0 &&
            <h2>
              You have {unreadMessages.length} unread messages.
            </h2>
          }
        </div>
      );
    }
    
    const messages = ['React', 'Re: React', 'Re:Re: React'];
    ReactDOM.render(
      <Mailbox unreadMessages={messages} />,
      document.getElementById('root')
    );
    

    3. 三目运算符 condition ? true : false

    render() {
      const isLoggedIn = this.state.isLoggedIn;
      return (
        <div>
        	The user is <b>{isLoggedIn ? 'currently' : 'not'}</b> logged in.
          {isLoggedIn
            ? <LogoutButton onClick={this.handleLogoutClick} />
            : <LoginButton onClick={this.handleLoginClick} />
          }
        </div>
      );
    }
    

    阻止组件渲染

    在极少数情况下,你可能希望能隐藏组件,即使它已经被其他组件渲染。若要完成此操作,你可以让 render 方法直接返回 null,而不进行任何渲染

    function WarningBanner(props) {
      if (!props.warn) {
        return null;             // render 方法直接返回 null,而不进行任何渲染
      }
    
      return (
        <div className="warning">
          Warning!
        </div>
      );
    }
    
    class Page extends React.Component {
      constructor(props) {
        super(props);
        this.state = {showWarning: true};
        this.handleToggleClick = this.handleToggleClick.bind(this);
      }
    
      handleToggleClick() {
        this.setState(state => ({
          showWarning: !state.showWarning
        }));
      }
    
      render() {
        return (
          <div>
            <WarningBanner warn={this.state.showWarning} />
            <button onClick={this.handleToggleClick}>
              {this.state.showWarning ? 'Hide' : 'Show'}
            </button>
          </div>
        );
      }
    }
    
    ReactDOM.render(
      <Page />,
      document.getElementById('root')
    );
    

    17、为什么列表必须包含一个特殊的key属性?

    警告 a key should be provided for list items,意思是当你创建一个元素时,必须包括一个特殊的 key 属性。

    key 帮助 React 识别哪些元素改变了,比如被添加或删除。因此你应当给数组中的每一个元素赋予一个确定的标识。

    一个元素的 key 最好是这个元素在列表中拥有的一个独一无二的字符串。通常,我们使用数据中的 id 来作为元素的 key。

    key 只是在兄弟节点之间必须唯一

    数组元素中使用的 key 在其兄弟节点之间应该是独一无二的。然而,它们不需要是全局唯一的。当我们生成两个不同的数组时,我们可以使用相同的 key 值。

    例子:

    function NumberList(props) {
      const numbers = props.numbers;
      const listItems = numbers.map((number) =>
        <ListItem key={number.toString()}
                  value={number} />
      );
      return (
        <ul>
          {listItems}
        </ul>
      );
    }
    

    等价于:

    function NumberList(props) {
      const numbers = props.numbers;
      return (
        <ul>
          {numbers.map((number) =>
            <ListItem key={number.toString()}
                      value={number} />
          )}
        </ul>
      );
    }
    

    JSX 允许在大括号中嵌入任何表达式,这么做有时可以使你的代码更清晰,但有时这种风格也会被滥用。就像在 JavaScript 中一样,何时需要为了可读性提取出一个变量,这完全取决于你。但请记住,如果一个 map() 嵌套了太多层级,那可能就是你提取组件的一个好时机。

    18、为什么不建议用index作为key?

    当元素没有确定 id 的时候,万不得已你可以使用元素索引 index 作为 key。如果列表项目的顺序可能会变化,我们不建议使用索引来用作 key 值,因为这样做会导致性能变差,还可能引起组件状态的问题。可以看看 Robin Pokorny 的深度解析使用索引作为 key 的负面影响这一篇文章。如果你选择不指定显式的 key 值,那么 React 将默认使用索引用作为列表项目的 key 值。

    19、列表key属性的位置

    元素的 key 只有放在就近的数组上下文中才有意义。

    比方说,如果你提取出一个 ListItem 组件,你应该把 key 保留在数组中的这个 <ListItem /> 元素上,而不是放在 ListItem 组件中的 <li> 元素上。

    function ListItem(props) {
      const value = props.value;
      return (
        // 错误!你不需要在这里指定 key:
        <li key={value.toString()}>
          {value}
        </li>
      );
    }
    
    function NumberList(props) {
      const numbers = props.numbers;
      const listItems = numbers.map((number) =>
        // 错误!元素的 key 应该在这里指定:
        <ListItem value={number} />
      );
      return (
        <ul>
          {listItems}
        </ul>
      );
    }
    
    const numbers = [1, 2, 3, 4, 5];
    ReactDOM.render(
      <NumberList numbers={numbers} />,
      document.getElementById('root')
    );
    

    一个好的经验法则是:在 map() 方法中的元素需要设置 key 属性

    function ListItem(props) {
      // 正确!这里不需要指定 key:
      return <li>{props.value}</li>;
    }
    
    function NumberList(props) {
      const numbers = props.numbers;
      const listItems = numbers.map((number) =>
        // 正确!key 应该在数组的上下文中被指定
        <ListItem key={number.toString()} value={number} />
      );
      return (
        <ul>
          {listItems}
        </ul>
      );
    }
    
    const numbers = [1, 2, 3, 4, 5];
    ReactDOM.render(
      <NumberList numbers={numbers} />,
      document.getElementById('root')
    );
    

    20、以 组合 模式来构建React应用

    React 有十分强大的组合模式。我们推荐使用组合而非继承来实现组件间的代码重用。如何通过组合思想来解决这些问题。

    1. 包含关系——考虑“通用容器”时使用

    有些组件无法提前知晓它们子组件的具体内容

    在 Sidebar(侧边栏)和 Dialog(对话框)等展现通用容器(box)的组件中特别容易遇到这种情况。

    props.children

    我们建议这些组件使用一个特殊的 children prop 来将他们的子组件传递到渲染结果中:

    function FancyBorder(props) {
      return (
        <div className={'FancyBorder FancyBorder-' + props.color}>
          {props.children}
        </div>
      );
    }
    

    这使得别的组件可以通过 JSX 嵌套,将任意组件作为子组件传递给它们。

    function WelcomeDialog() {
      return (
        <FancyBorder color="blue">
          <h1 className="Dialog-title">
            Welcome
          </h1>
          <p className="Dialog-message">
            Thank you for visiting our spacecraft!
          </p>
        </FancyBorder>
      );
    }
    

    <FancyBorder> JSX 标签中的所有内容都会作为一个 children prop 传递给 FancyBorder 组件。因为 FancyBorder 将 {props.children} 渲染在一个 <div> 中,被传递的这些子组件最终都会出现在输出结果中。

    props——别的库中“槽”(slot)的概念

    少数情况下,你可能需要在一个组件中预留出几个“洞”。这种情况下,我们可以不使用 children,而是自行约定:将所需内容传入 props,并使用相应的 prop。

    function SplitPane(props) {
      return (
        <div className="SplitPane">
          <div className="SplitPane-left">
            {props.left}
          </div>
          <div className="SplitPane-right">
            {props.right}
          </div>
        </div>
      );
    }
    
    function App() {
      return (
        <SplitPane
          left={
            <Contacts />
          }
          right={
            <Chat />
          } />
      );
    }
    

    2. 特殊实例关系

    有些时候,我们会把一些组件看作是其他组件的特殊实例,可以通过 props 定制并渲染“一般”组件得到“特殊实例”组件

    function Dialog(props) {
      return (
        <FancyBorder color="blue">
          <h1 className="Dialog-title">
            {props.title}
          </h1>
          <p className="Dialog-message">
            {props.message}
          </p>
        </FancyBorder>
      );
    }
    
    function WelcomeDialog() {
      return (
        <Dialog
          
          message="Thank you for visiting our spacecraft!" />
      );
    }
    

    综合例子

    function Dialog(props) {
      return (
        <FancyBorder color="blue">
          <h1 className="Dialog-title">
            {props.title}
          </h1>
          <p className="Dialog-message">
            {props.message}
          </p>
          {props.children}
        </FancyBorder>
      );
    }
    
    class SignUpDialog extends React.Component {
      constructor(props) {
        super(props);
        this.handleChange = this.handleChange.bind(this);
        this.handleSignUp = this.handleSignUp.bind(this);
        this.state = {login: ''};
      }
    
      render() {
        return (
          <Dialog 
                  message="How should we refer to you?">
            <input value={this.state.login}
                   onChange={this.handleChange} />
            <button onClick={this.handleSignUp}>
              Sign Me Up!
            </button>
          </Dialog>
        );
      }
    
      handleChange(e) {
        this.setState({login: e.target.value});
      }
    
      handleSignUp() {
        alert(`Welcome aboard, ${this.state.login}!`);
      }
    }
    

    Hook 相关

    1、为什么用Hook?

    它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。


    起源地下载网 » 重读React官网doc需要注意并记住的点

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元