react---react入门

学习链接:

React

Release v3.4.2 · facebook/react-devtools · GitHub

代码链接:https://gitee.com/leimiao_x/react-study/

1.react介绍

react是用于构建用户界面的javaScript 库,是一个将数据渲染为HTML视图的开源 JavaScript库由FaceBook软件工程师Jordan Walke创建,2013年5月宣布开源。

why react:原生js的痛点-原生JS通过DOM Api操作DOM繁琐、效率低;浏览器会进行大量的重绘重排;原生JS没有组件化编码方案,代码复用率低。

react 特点:

  • 采用组件化模式、声明式编码,提高开发效率及组件复用率。 
  • React Native 中可以使用 React语法进行移动端开发
  • 使用虚拟DOM (通过虚拟DOM对比有差异的地方)+ 优秀的Diffing算法,尽量减少与真实DOM的交互

以下代码中将会使用的依赖库

<!-- 引入react核心库 注意:react核心库要放在react-dom之前引入-->
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<!-- 引入react-dom,用于支持react操作DOM -->
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<!-- 引入babel,用于将jsx转为js -->
<script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>

2.虚拟DOM

  • 本质上是一个Object对象,一般对象;
  • 虚拟DOM比较 ”轻",真实DOM比较 “重”, 因为虚拟DOM是React内部在用,无需真实DOM这么多的属性;
  • 虚拟DOM最终会被React转化成真实DOM,呈现在页面上。
 // 渲染页面的容器-必须要有--下文为了精简代码不写这个了
 <div id="app"></div> 
 <script type="text/babel"> //注意:要写babel,下文为了精简代码不写这个了      
      //1.1使用JS创建虚拟DOM
      // const VDOM = React.createElement('h1', {id: 'title'}, 
       React.createElement('span',{}, 'hello, React')) 
      //1.2使用JSX创建虚拟DOM
      const VDOM = (
        <h1 id="title">
          <span>Hello React</span>
        </h1>
      ); 
      //2.渲染虚拟DOM到页面--必须要有--下文为了精简代码不写这个了
      ReactDOM.render(VDOM, document.getElementById("app")); 
      console.log("虚拟dom>>>>>>", VDOM);
      const TDOM = document.getElementById("app1");
      console.log("真实dom>>>>>>", TDOM);
      debugger;
    </script>

 对比上图,虚拟DOM上的属性要比真实DOM上的属性少的多,因此操作起来也比较方便。

 react创建虚拟DOM的两种方式:JS和JSX方式

//1使用JS创建虚拟DOM
const VDOM = React.createElement(
  "h1",
  { id: "title" },
  React.createElement("span", {}, "hello, React")
);
//2使用JSX创建虚拟DOM
const VDOM = (
  <h1 id="title">
    <span>Hello React</span>
  </h1>
);

3.JSX

JSX语法规则:

● 定义虚拟DOM时,不要写引号【const vdom=<h1>hello</h1>】
●标签中混入JS表达式时要用 {}  【const vdom=<h1 id={myId}>{myData}</h1>】
●样式的类名指定不用 class,要用
className【const vdom=<h1 className="title">hello</h1>
●内联样式,要用style = {{key: value}} 的形式去写【const vdom=<h1 style={{color:'red',fontSize:'30px'}}>hello</h1>
●只有一个根标签
●标签必须闭合
●标签首字母(1)若小写字母开头,则将该标签转为 html同名元素,若html中无该标签,则报错;2)若大写字母开头,react就去渲染对应的组件,若组件没有定义,则报错

const myId = "iDKKa";
const myData = "heLLo ReaCt";
const data = ["react", "vue", "angular"];

const vDom = (
  <div>
    <h1 id={myId.toLowerCase()} className="title">
      <span style={{ color: "red", fontSize: "30px" }}>
        {myData.toLowerCase()}
      </span>
    </h1>
    <ul>
      {data.map((item, index) => (
        <li key={index}>{item}</li>
      ))}
    </ul>
  </div>
);
注意:{}内只能写js表达式,不能写js语句
js表达式:a,a+b,fn(1),arr.map(),function test(){} 一个表达式会产生一个值,可以放在任何一个需要值的地方;
  • js语句:if(){},for(){},swith(){case:xxx} 等控制代码走向的,没有值
  • 4.Hello React

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
    </style>
  </head>
  <body>
    <!-- 容器 -->
    <div id="app"></div>
    <div id="app1"></div>
      <!-- 引入react核心库 注意:react核心库要放在react-dom之前引入-->
      <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
      <!-- 引入react-dom,用于支持react操作DOM -->
      <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
      <!-- 引入babel,用于将jsx转为js -->
      <script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
      <script type="text/babel">
      //注意:要写babel
      //1.1使用JS创建虚拟DOM
      // const VDOM = React.createElement('h1', {id: 'title'}, React.createElement('span',{}, 'hello, React')) //纯js创建虚拟dom
      //1.2使用JSX创建虚拟DOM
      const VDOM = (
        <h1 id="title">
          <span>Hello React</span>
        </h1>
      ); //jsx创建虚拟dom
      ReactDOM.render(VDOM, document.getElementById("app")); //2.渲染虚拟DOM到页面
      console.log("虚拟dom>>>>>>", VDOM);
      const TDOM = document.getElementById("app1");
      console.log("真实dom>>>>>>", TDOM);
      debugger;
    </script>
  </body>
</html>
  • 总结:
  • CDN方式引入:react核心库 ;react-dom:用于支持react操作DOM;babel:es6转es5,jsx转js 
  • 过程分两步:(1)创建虚拟DOM(2)渲染虚拟DOM到页面
  • 注意:react核心库要放在react-dom之前引入;<script type="text/babel">;要有一个容器 <div id="app"></div>

5.函数式组件

定义组件可通过函数或类实现,分为函数式组件和类式组件

函数式组件

function MyComponent() {
  console.log(this);
  return <h1>函数式组件适用于简单组件的定义</h1>;
}
ReactDOM.render(<MyComponent />, document.getElementById("app"));

  执行了ReactDOM.render(...之后,发生了什么)

  • React解析组件标签,找到了MyComponent组件
  • 发现组件是使用函数定义的,随后调用该函数,将返回的虚拟DOM转为真实的DOM,随后呈现在页面上。

注意必须有return

6.类式组件

补充类的基本知识

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script type="text/javascript">
        class Person{//创建一个Person类
            constructor(name,age){
                //构造函数中的this指向谁?---类的实例
                this.name=name
                this.age=age
            }
            a=1//  类中可以直接写赋值语句
            // 一般方法,speak方法放在哪?---类的原型对象上,供实例使用
            sayHi(){
                console.log(`Hi,I am ${this.name}`);
            }
        }
        const p1=new Person("maidu",12) //创建一个Person类的实例对象
        console.log(p1);
        p1.sayHi()

        //继承
        class Student extends Person{
            constructor(name,age,grade){
               super(name,age)
                this.grade=grade
            }
            //重写从父类继承的方法
            sayHi(){
                console.log(`Hi,I am ${this.name},我在${this.grade}`);
            }
            study(){
                console.log("我爱学习");
            }
        }
        const s1=new Student("eason",3,"幼儿园")
        console.log(s1);
        s1.sayHi()
        s1.study()
    </script>
</body>
</html>
  • 类中的构造器不是必须写的,要对实例进行一些初始化的操作,如添加指定属性时才写
  • 如果A类继承了B类,且A类型写了构造器,那么A类构造器中的super是必须要调用的
  • 类中所定义的方法,都是放在了类的原型对象上,供实列使用
  • 类中可以直接写赋值语句【a=1】

类式组件

// 1、创建类式组件
class MyComponent extends React.Component {
  // render放在哪?---MyComponent的原型对象上,供实例使用
  // render中的this是谁?---MyComponent的实例对象,<=>MyComponent组件实例对象
  render() {
    console.log(this);
    return <h1>类式组件适用于复杂组件的定义</h1>;
  }
}
// 2.渲染组件到页面
ReactDOM.render(<MyComponent />, document.getElementById("app"));

执行了ReactDOM.render(...之后,发生了什么)

  • React解析组件标签,找到了MyComponent组件
  • 发现组件是使用类定义的,随后new 出来该类的实例,并通过该实例调用到原型上的render方法
  •  将render 返回的虚拟DOM转为真实DOM,随后呈现在页面上

7.组件三大属性1_state

  • state 的值是对象【state={key:value}】
  • 状态数据不能直接修改更新,必须要用内置api--- setState
  • 组件中render方法中和constructor中的this都为组件实例对象
  • 组件自定义方法中的this 为undefined解决办法:bind改变this执行;箭头函数(一般用第二种,通过赋值语句+箭头函数定义事件解决this指向问题)
 //构造器调用---1次
 constructor(props) {
    super(props); //this必须放在super之后使用
    console.log("constructor", this);
    this.state = { isChinese: true, name1: "maidu", name2: "麦嘟" };
    this.cL = this.changeLanguage.bind(this);//1.bind 
  }
 // 2.赋值语句+箭头函数解决this指向问题
changeLanguage = () => {}
  • 注意元素绑定事件正确写法:onClick = { this.demo },this.demo是函数的回调
  • 错误写法: onClick = { this.demo() },  this.demo() 是函数的执行  
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Document</title>
  </head>
  <body>
    <div id="app"></div>
    <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
    <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
    <script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
    <script type="text/babel">
      class Language extends React.Component {
        state = { isChinese: true, name1: "maidu", name2: "麦嘟" };
        render() {
          const { isChinese, name1, name2 } = this.state;
          return (
            <div onClick={this.changeLanguage}>{isChinese ? name2 : name1}</div>
          );
        }
        // 赋值语句+箭头函数解决this指向问题
        changeLanguage = () => {
          let flag = this.state.isChinese;
          this.setState({
            isChinese: !flag,
          });
        };
      }
      ReactDOM.render(<Language />, document.getElementById("app"));
    </script>
  </body>
</html>

8.组件三大属性2_props

  • 在类组件中 直接 this.props就可以拿到 组件传进来的值对象了
  • React 的组件的props传值,可以使用三点运算符 展开 Object,仅限于 组件的props的传值
  • props是只读,不可以修改
  • 构造器是否接受 props,是否传递给super,取决于:是否希望在构造器中通过this访问 props
  • ES6 中三点运算符,可以展开数组,但是不可以展开 Object,因为Object不是一个iterator,不是可迭代的
let arr1 = [1, 2, 3];
let arr2 = [4, 5, 6];
console.log(...arr1);
let arr3 = [...arr1, ...arr2];
console.log(arr3);

function sum(...arg) {
  return arg.reduce((prev, cur) => prev + cur);
}
console.log(sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
let obj = { name: "maidu", age: 12, action: { eat: "apple" } };
// console.log(...obj);//报错,对象不是一个iterator,不是可迭代的,...不能展开对象
let obj2 = { ...obj }; //..是浅拷贝,仅第一层值不受影响
obj2.name = "麦嘟";
obj2.action.eat = "orange";
console.log(obj);
console.log(obj2);
let obj3 = { ...obj, name: "ct" };
console.log(obj3);

类式组件使用props

class Person extends React.Component {
    render() {
        console.log('props>>>>>>>',this.props);
        const {name,age,sex}=this.props
        return (
         <ul>
          <li>姓名:{name}</li>
          <li>年龄:{age}</li>
          <li>性别:{sex}</li>
         </ul>
       );
    }
}
ReactDOM.render(<Person name="maidu"  age="18" sex="男"/>, document.getElementById("app1"));
ReactDOM.render(<Person name="ct" age={16} sex="男" />, document.getElementById("app2"));
const p = { name: "maidu", age: 12, sex: "女" };
ReactDOM.render(<Person {...p} />, document.getElementById("app3"));

 React内置了一些 方法 对 props传入的属性进行 检查,15.5版本之后React.PropTypes 已移入另一个包中了

对Props进行属性和必要性限制

// 对标签属性进行类型和必要性限制
Person.propTypes = {
  name: PropTypes.string.isRequired,
  age: PropTypes.number,
  sex: PropTypes.string,
  speak: PropTypes.func, //此处不写function因为function是个关键字
};
// 给标签属性设置默认值
Person.defaultProps = {
  sex: "女",
};
function speak() {
  console.log("我说话了");
}

也可以把以上代码放在类里面,通过static关键字定义,相当于类的静态成员

class Person extends React.Component {
    // 对标签属性进行类型和必要性限制
    static propTypes = {
      name: PropTypes.string.isRequired,
      age: PropTypes.number,
      sex: PropTypes.string,
      speak: PropTypes.func, //此处不写function因为function是个关键字
    };
    // 给标签属性设置默认值
    static defaultProps = {
      sex: "女",
    };
}

函数式组件使用props

function Person(props) {
  const { name, age, sex } = props;
  return (
    <ul>
      <li>姓名:{name}</li>
      <li>年龄:{age}</li>
      <li>性别:{sex}</li>
    </ul>
  );
}
// 对标签属性进行类型和必要性限制
Person.propTypes = {
  name: PropTypes.string.isRequired,
  age: PropTypes.number,
  sex: PropTypes.string,
  speak: PropTypes.func, //此处不写function因为function是个关键字
};
// 给标签属性设置默认值
Person.defaultProps = {
  sex: "女",
};
function speak() {
  console.log("我说话了");
}
ReactDOM.render(
  <Person name="maidu" age={12} speak={speak} />,
  document.getElementById("app1")
);
ReactDOM.render(
  <Person name="ct" age={16} sex="男" />,
  document.getElementById("app2")
);
const p = { name: "maidu", age: 12, sex: "女" };
ReactDOM.render(<Person {...p} />, document.getElementById("app3"));

9.组件三大属性3_ref

字符串形式的 ref,官方不建议使用,以后会弃用

   绑定组件【ref="input1"】,获取值【 this.refs.input1.value】

class MyComponent extends React.Component {
  showData1 = () => {
    console.log("refs>>>>>", this, this.refs.input1);
    const { input1 } = this.refs;
    alert(input1.value);
  };
  render() {
    return (
      <div>
        <input ref="input1" type="text" placeholder="请输入" />
        <button onClick={this.showData1}>按钮</button>&nbsp;
      </div>
    );
  }
}

回调形式的ref 

绑定组件【ref={(c) => (this.input1 = c)】,获取值【this.input1.value】

回调函数形式的ref中回调函数,【ref={(c) => (this.input1 = c)】这种内联形式会执行2次,但是影响不大;可以通过把回调绑定在class的属性上

JSX中注释代码{/* */},使用{}表示里面要写JS代码了,因此这里面才能用JS代码注释的方式来注释

class MyComponent extends React.Component {
    state = { isHot: true };
    showData1 = () => {
      console.log("refs>>>>>", this);
      const { input1 } = this;
      alert(input1.value);
    };
    changeWeather = () => {
      const { isHot } = this.state;
      this.setState({
        isHot: !isHot,
      });
    };
    saveInput1 = (c) => {
      this.input1 = c;
      console.log("@", c);
    };
    //回调函数形式的ref中回调函数,内联形式会执行2次;可以通过把回调绑定在class的属性上--具体解释见官网

    render() {
      return (
        <div>
          <h1>今天天气很{this.state.isHot ? "炎热" : "凉爽"}</h1>
          {/* <input
            ref={(c) => {this.input1 = c; console.log("@",c)}} //将ref指向的节点c(currentNode)给this.input1
            type="text"
            placeholder="请输入"
          />*/}
          <input
            ref={this.saveInput1} //将ref指向的节点c(currentNode)给this.input1
            type="text"
            placeholder="请输入"
          />
          <br />
          <br />
          <button onClick={this.showData1}>点我获取输入框数据</button>&nbsp;
          <button onClick={this.changeWeather}>点我切换天气</button>
        </div>
      );
    }
  }
  ReactDOM.render(<MyComponent />, document.getElementById("app"));

createRef:官方最推荐的写法,createRef是只能存一个值,后面的值会直接覆盖前面定义的值,键值对的形式存储。因此通过这种形式绑定N个组件,需要createRef N次,感觉也挺费事。。。

class MyComponent extends React.Component {
  myRef1 = React.createRef();
  myRef2 = React.createRef();
  showData1 = () => {
    const { current } = this.myRef1;
    alert(current.value);
  };
  showData2 = () => {
    const { current } = this.myRef2;
    alert(current.value);
  };
  render() {
    return (
      <div>
        <input ref={this.myRef1} type="text" placeholder="请输入" />
        &nbsp;
        <button onClick={this.showData1}>按钮</button>&nbsp;
        <input
          ref={this.myRef2}
          type="text"
          placeholder="请输入"
          onBlur={this.showData2}
        />
      </div>
    );
  }
}

10. 事件处理

通过onXxx属性指定事件处理函数,如onClick,onBlur等

  • React使用的是自定义(合成)事件,而不是使用的原生的DOM事件(onclick,onblur等) --- 为了更好的兼容性。react在自定义事件中处理了一些兼容性问题
  • React中的事件是通过事件委托方式处理的(委托给组件最外层的元素)--为了高效。事件委托通过事件冒泡实现,把事件委托给组件最外层的元素。

 注意:不要过度使用ref:可以通过event.target得到发生事件的DOM元素对象,事件绑定和事件触发作用同一对象通过获取event来减少refs的使用。

class MyComponent extends React.Component {
    showData2 = (e) => {
      console.log(e.target);
      alert(e.target.value); //事件绑定和事件触发作用同一对象通过获取event来减少refs的使用
    };
    render() {
      return (
          <input
            type="text"
            placeholder="请输入"
            onBlur={this.showData2}
          />
      );
    }
  }

11.非受控组件&受控组件

(1)非受控组件:相对于受控组件来说,属性没有在 state状态里面维护的都是非受控组件,属性现造现取。

class Login extends React.Component {
  handleLogin = (e) => {
    e.preventDefault(); //阻止表单默认的提交事件
    const { username, password } = this;
    alert(`用户名:${username.value},密码:${password.value}`);
  };
  render() {
    return (
      <form onSubmit={this.handleLogin}>
        用户名:{" "}
        <input ref={(c) => (this.username = c)} type="text" name="username" />
        密码:
        <input ref={(c) => (this.password = c)} type="text" name="password" />
        <button>登录</button>
      </form>
    );
  }
}

(2)受控组件:数据都放在 state状态里面维护,相当于 vue的数据双向绑定 

class Login extends React.Component {
  state = {
    username: "",
    password: "",
  };
  //受控组件:
  handleLogin = (e) => {
    e.preventDefault(); //阻止表单默认的提交事件
    const { username, password } = this.state;
    alert(`用户名:${username},密码:${password}`);
  };
  saveUsername = (e) => {
    this.setState({ username: e.target.value });
  };
  savePassword = (e) => {
    this.setState({
      password: e.target.value,
    });
  };
  render() {
    return (
      <form onSubmit={this.handleLogin}>
        用户名:{" "}
        <input onChange={this.saveUsername} type="text" name="username" />
        密码:
        <input onChange={this.savePassword} type="text" name="password" />
        <button>登录</button>
      </form>
    );
  }
}

12.高阶函数&函数的柯里化

高阶函数: 如果一个函数符合下面2个规范中的任何一个,那该函数就是高阶函数

  • 若A函数,接收的参数是一个函数,那么A就可以称之为高阶函数
  • 若A函数,调用的返回值仍然是一个函数,那么A就可以称之为高阶函数
  • 常见的高阶函数: Promise、setTimeout、arr.map()、arr.reduce()等

函数的柯里化: 通过函数调用继续返回函数的方式,实现多次接收参数最后统一处理的函数编码形式。

 //函数柯里化
 saveFormData = (dataType) => {
    return (e) => {
      this.setState({ [dataType]: e.target.value });
    };
  };

  render() {
    return (
      <form onSubmit={this.handleLogin}>
        用户名:{" "}
        <input
          onChange={this.saveFormData("username")}
          type="text"
          name="username"
        />
        密码:
        <input
          onChange={this.saveFormData("password")}
          type="text"
          name="password"
        />
        <button>登录</button>
      </form>
    );
  }

 this.setState({[dataType]: event.target.value}) 中的 [dataType]为什么可以读变量呢?---在数组里面是 array[a] =1 就可以赋值数据, 同理 

不使用函数柯里化的实现

saveFormData = (dataType, e) => {
  this.setState({ [dataType]: e.target.value });
};

<input
  onChange={(e) => this.saveFormData("username", e)}
  type="text"
  name="username"
/>;

13.DOM的 diffing算法

逐层比较,最小粒度是标签

经典面试题

react/vue 中key有什么作用?(key的内部原理是什么?)

简单的说:key是虚拟DOM对象的标识,在更新显示时key起到及其重要的作用

详细说:当状态中的数据发生变化时,react会根据 【新数据】生成 【新的虚拟DOM】,随后React进行【新虚拟DOM】与【旧虚拟DOM】的diff比较,比较规则如下:

                a. 旧虚拟DOM中找到了与新虚拟DOM相同的key

                  1. 若虚拟DOM中内容没有变,直接使用之前的真实DOM

                  2. 若虚拟DOM中内容变了,则生成新的真实DOM,随后替换掉页面中之前的真实DOM

                b. 旧虚拟DOM中未找到与新虚拟DOM相同的key

                  根据数据创建新的真实的DOM,随后渲染到页面

为什么遍历列表时key最好不要用index?

用index作为key可能会引发的问题:

  • 若对数据进行:逆序添加、逆序删除等破环顺序操作:会产生没有必要的真实DOM更新 =》界面效果没有问题,但效率低
  •  如果结构中还包含输入类的DOM:会产生错误DOM更新 =》界面有问题
  •  注意:如果不存在对数据的逆序添加、逆序删除等破环顺序操作,仅用于渲染列表用于展示,使用index作为key是没有问题的。

开发中如何选择key?

  • 最好使用每条数据的唯一标识作为key,比如:id、手机号、身份证号、学号等唯一值
  • 如果确定只是简单的展示数据,用index也是可以的。
     
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
入门react-native,首先你需要安装react-native-image-to-pdf库。你可以通过以下命令进行自动安装: $ npm install react-native-image-to-pdf --save 或者 $ yarn add react-native-image-to-pdf 然后,你需要将这个库链接到你的项目中,如果是iOS项目,在Xcode的项目导航器中,右键单击项目,选择"Link Binary With Libraries"选项。 接下来,你需要导入React和View模块,创建一个React组件,并实现render方法。在render方法中,使用View组件来布局你的界面。比如,你可以使用flex属性控制子组件的布局和比例。 最后,你需要注意在使用Chrome调试时无法观测到React Native中的网络请求。你可以使用第三方的调试工具,如react-native-debugger,或者使用抓包工具如Charles、Fiddler来进行观测。同时,你还需要处理服务器的响应数据。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [react-native-image-to-pdf:react-native插件可将图像转换为PDF](https://download.csdn.net/download/weixin_42118701/19074635)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [ReactNative入门](https://blog.csdn.net/SeaState/article/details/113697867)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值