ddee

ddee 查看完整档案

广州编辑广东行政职业学院  |  计算机应用技术 编辑  |  填写所在公司/组织 aa.com 编辑
编辑

喜欢音乐、撸码、运动

个人动态

ddee 发布了文章 · 2019-08-31

react中使用Fragments

在官方文档中,原文是,“React 中的一个常见模式是一个组件返回多个元素。Fragments 允许你将子列表分组,而无需向 DOM 添加额外节点。”,意思就是你在写组件的时候,外面再套一个Fragments。类似于vue中的template
为什么要使用Fragments,举个例子,比如我们要做个表格组件,父组件的代码是这样
class Table extends React.Component {
  render() {
    return (
      <table>
        <tr>
          <Columns />
        </tr>
      </table>
    );
  }
}
如果子组件Columns的代码是这样的话,在 <Columns /> 的 render() 中使用了父 div,则生成的 HTML 将无效
class Columns extends React.Component {
  render() {
    return (
      <div>
        <td>Hello</td>
        <td>World</td>
      </div>
    );
  }
}
Fragments解决了这个问题,Columns组件中加入Fragments后,生成的html就正常了
class Columns extends React.Component {
  render() {
    return (
      <React.Fragment>
        <td>Hello</td>
        <td>World</td>
      </React.Fragment>
    );
  }
}
查看原文

赞 0 收藏 0 评论 0

ddee 发布了文章 · 2019-08-31

react中Suspense的使用

关于Suspense的使用,先来看下示例代码

const OtherComponent = React.lazy(() => import('./OtherComponent'));

function MyComponent() {
  return (
    <div>
      <Suspense fallback={<div>Loading...</div>}>
        <OtherComponent />
      </Suspense>
    </div>
  );
}
OtherComponent是通过懒加载加载进来的,所以渲染页面的时候可能会有延迟,但使用了Suspense之后,可优化交互。

<OtherComponent />外面使用Suspense标签,并在fallback中声明OtherComponent加载完成前做的事,即可优化整个页面的交互

fallback 属性接受任何在组件加载过程中你想展示的 React 元素。你可以将 Suspense 组件置于懒加载组件之上的任何位置。你甚至可以用一个 Suspense 组件包裹多个懒加载组件。
const OtherComponent = React.lazy(() => import('./OtherComponent'));
const AnotherComponent = React.lazy(() => import('./AnotherComponent'));

function MyComponent() {
  return (
    <div>
      <Suspense fallback={<div>Loading...</div>}>
        <section>
          <OtherComponent />
          <AnotherComponent />
        </section>
      </Suspense>
    </div>
  );
}
查看原文

赞 4 收藏 1 评论 0

ddee 发布了文章 · 2019-08-31

关于react中refs的使用

在react中,可以使用refs来访问dom,或者在render中创建react对象。

使用refs的主要用途是

  1. 做一些动画的交互
  2. 媒体控件的播放
  3. 获取焦点、获取文本等
使用refs的方式有两种,一种是使用React.createRef() API,另一种是使用 回调形式的refs

先来介绍第一种方式,使用React.createRef() API


import React, { Component } from 'react'
export default class App extends React.Component {
  constructor(props) {
    super(props);
    // 创建一个 ref 来存储 textInput 的 DOM 元素
    this.textInput = React.createRef();
    this.focusTextInput = this.focusTextInput.bind(this);
  }

  focusTextInput() {
    // 直接使用原生 API 使 text 输入框获得焦点
    // 注意:我们通过 "current" 来访问 DOM 节点
    this.textInput.current.focus();
    console.log(this.textInput.current);//这边输出input的dom对象
  }

  render() {
    // 告诉 React 我们想把 <input> ref 关联到
    // 构造器里创建的 `textInput` 上
    return (
      <div>
        <input
          type="text"
          ref={this.textInput} />

        <input
          type="button"
          value="点击我获取焦点"
          onClick={this.focusTextInput}
        />
      </div>
    );
   }
 }
第二种是回调 Refs,React 将在组件挂载时,会调用 ref 回调函数并传入 DOM 元素,当卸载时调用它并传入 null。在 componentDidMount 或 componentDidUpdate 触发前,React 会保证 refs 一定是最新的。
import React, { Component } from 'react'
export default class App extends React.Component {
  constructor(props) {
    super(props);
    // 创建一个 ref 来存储 textInput 的 DOM 元素
    this.textInput = null;
    this.setTextInputRef = element => {
      this.textInput = element;
    };
    this.focusTextInput = () => {
      // 使用原生 DOM API 使 text 输入框获得焦点
      if (this.textInput) this.textInput.focus();
    };
  }

  componentDidMount() {
    // 组件挂载后,让文本框自动获得焦点
    this.focusTextInput();
  }

  render() {
    // 使用 `ref` 的回调函数将 text 输入框 DOM 节点的引用存储到 React
    // 实例上(比如 this.textInput)
    return (
      <div>
        <input
          type="text"
          ref={this.setTextInputRef}
        />
        <input
          type="button"
          value="点击我获取焦点"
          onClick={this.focusTextInput}
        />
      </div>
    );
  }
}
后面来讲下,父子组件怎么样传递refs,你可以在组件间传递回调形式的 refs,代码如下
import React, { Component } from 'react'
function CustomTextInput(props) {
  return (
    <div>
      <input ref={props.inputRef} />
    </div>
  );
}

class App extends React.Component {
  constructor(props) {
    super(props);
    // 创建一个 ref 来存储 textInput 的 DOM 元素
    this.inputElement = null;
    this.setTextInputRef = element => {
      this.inputElement = element;
    };
    this.focusTextInput = () => {
      // 使用原生 DOM API 使 text 输入框获得焦点
      console.log(this.inputElement)
      if (this.inputElement) this.inputElement.focus();
    };
  }
  componentDidMount() {
    // 组件挂载后,让文本框自动获得焦点
    this.focusTextInput();
  }
  render() {
    return (
      <div> 
      <CustomTextInput
        inputRef={el => this.inputElement = el}
      />
      <input
          type="button"
          value="点击我获取焦点"
          onClick={this.focusTextInput}
        />
      </div>
    );
  }
}
在上面的例子中,App 把它的 refs 回调函数当作 inputRef props 传递给了 CustomTextInput,而且 CustomTextInput 把相同的函数作为特殊的 ref 属性传递给了 <input>。结果是,在 App 中的 this.inputElement 会被设置为与 CustomTextInput 中的 input 元素相对应的 DOM 节点。
使用 React.forwardRef 来获取传递 ref,React 传递 ref 给 fowardRef 内函数 (props, ref) => ...,作为其第二个参数,然后转发到它渲染的 DOM
import React, { Component } from 'react'
const CustomTextInput = React.forwardRef((props, ref) => (
  <div>
      <input ref={ref} />
   </div>
));

class App extends React.Component {
  constructor(props) {
    super(props);
    // 创建一个 ref 来存储 textInput 的 DOM 元素
    this.inputElement = React.createRef();
    this.focusTextInput = () => {
      // 使用原生 DOM API 使 text 输入框获得焦点
      console.log(this.inputElement)
      this.inputElement.current.focus();
    };
  }

  render() {
    return (
      <div> 
      <CustomTextInput
        ref={this.inputElement}
      />
      <input
          type="button"
          value="点击我获取焦点"
          onClick={this.focusTextInput}
        />
      </div>
    );
  }
}
查看原文

赞 1 收藏 0 评论 0

ddee 收藏了文章 · 2018-07-11

react-router-dom v^4学习历程(一)

react-router-dom的版本已经更新到了4.1.1,那么我们就一起来学习学习react v4这个新版路由的基本使用吧!

在学习路由之前我们先需要复习几个基础知识,关于react组件的构建,和分离组件到另外的文件

生成react组件的方式

  • 我们可以采用一个函数来快速生成一个 react组件

观察如下代码

import React from 'react'
const Mycomponent=()=>(
  <div>
    <h2>这是我的第一个函数组件</h2>
  </div>
  
)
ReactDOM.render(<Mycomponent/>,document.getElementById('example'))

渲染组件到根节点上,可以看出没有任何问题。
我们也可以把这个组件分离到另外一个文件中,用es6的 语法import default export导入导出,然后在index.jsx中引用它

//Mycomponent.jsx
import React from 'react'
const Mycomponent=()=>(
  <div>
    <h2>这是我的第一个函数组件</h2>
  </div>
  
)
export default Mycomponent
//index.jsx
import Mycomponent from './Mycomponent'

这样我们就可以做到函数式构建的react组件在react项目中模块化使用

  • 第二种就是我们常用的class方式声明组件

   import React from 'react'
    export default class Topic extends React.Component{
    
    render(){
      return (
        <div>
        <h3>{this.props.match.params.topicId}</h3>
      </div>
    
        )
      }
    }

向构造react组件模板的函数中传入路由参数

如果一个react组件作为Route的component属性值,如下

 <Route  exact path="/" component={Home}></Route>
  • 函数式声明Home时,它的模板定义函数就会默认接受一个对象作为参数,里面包含了路由的各种信息
    图片描述

这样我们就可以利用模板定义函数参数中的信息获取到路由中的参数。
`

  const Topic=({match})=>//es6语法将参数对象中的match属性
 (                         //赋值给参数match
 <div>
<h3>{match.params.topicId}</h3>
 </div>
)
  • 如果是用类的方式声明的组件那么获取路由参数信息的办法是在jsx渲染模板中
    this.props.match.params


预备知识完毕,下面我们就看看怎么做一个react路由

路由基本用法

路由要解决的基本需求是从一个链接点击到另外一个链接,在页面中无刷新跳转到页面的另外一部分内容。类似于tabs面板。
例如有如下界面图片描述

三个组件如下:

const App=()=>(
  <h2>主页</h2>
)
const Hot=()=>(<div><h2>热门</h2></div>)
const Content=()=>(
  <h2>文章</h2>
)
const Zhuanlan=()=>(<div>
  <h2>专栏</h2>
</div>)

那么在需要使用路由的页面组件里面,渲染如下模板

 import {Link,Route,BrowserRouter as Router} from 'react-router-dom' 
  (<Router>
  <div>
    <ul>
      <li><Link to="/">主页</Link></li>
      <li><Link to="/hot">热门</Link></li>
      <li><Link to="/zhuanlan">专栏</Link></li>
    </ul>
    <hr/>
    <Route  exact path="/" component={App}></Route>
    <Route path="/hot" component={Hot} ></Route>
    <Route path="/zhuanlan" component={Zhuanlan}></Route>
  </div>
</Router>)

注意使用Router作为最外层标签,里面只能有一个一级子节点,用Link来导航 ,to指定路径,Route指定要导航到的组件,这样一个路由的基本使用就成型了。exact用于精准匹配路径,不用exact也会匹配到匹配的路径的子路径,这样两个路由组件都会显示。我们需要的是每次切换只会显示一个Route中指定的组件

路由的嵌套和路径中参数传递

  • 在一个子组件Hot中,再嵌套一个子路由我们应该怎么做?
    很简单就是把路由Route再写入Hot的模板中实现路由嵌套。

  • 路径中传递参数到路由到的组件,就是在路径前面加上: ,这样这个路由地址就会变成一个参数被组件接受到。例如${match.url}/:id
    ${match.url}可以获取到当前的基础路径。然后在路由用到的组件中可以用

match.params(函数式声明的组件中,match需要在函数参数中引入)或this.props.match.params(React class类render函数中)
示例如下

  ///父组件中
    const Hot=({match})=>(<div>
    
    <h2>热门</h2>
    <Link to={`${match.url}/article`}>文章</Link>
    <Link to={`${match.url}/qa`}>问答</Link>
    <Link to={`${match.url}/news`}>新闻</Link>
    <hr/>
    <Route path={`${match.url}/:type`} component={Content}></Route>
    
    </div>)
    //子组件中
    const Content=({match})=>(
  <div>
  <h2>热门子目录</h2>
<p>{match.params.type}</p>
  </div>
)

总结
1.组件生成的方式有两种,render在类中显式渲染,函数生成。
2.路由的基本用法Router>Route path component指定路径和组件,Link添加导航按钮链接,to指定路径地址
3.路由的嵌套,直接在子组件模板中添加Route,Link,match.url引入基础路径
4.路由路径参数传递到模板,用baseUrl/:id类似格式,组件中用match.params.id接收。

查看原文

ddee 发布了文章 · 2018-06-16

关于mongodb数据库的增删改查

查看所有数据库列表

show dbs

使用数据库、创建数据库

use student

如果真的想把这个数据库创建成功,那么必须插入一个数据。

数据库中不能直接插入数据,只能往集合(collections)中插入数据。不需要专门创建集合,只 需要写点语法插入数据就会创建集合:

db.student.insert({“name”:”xiaoming”});

db.student 系统发现 student 是一个陌生的集合名字,所以就自动创建了集合。 显示当前的数据集合(mysql 中叫表)

show collections

删除数据库,删除当前所在的数据库

db.dropDatabase();

删除集合

db.COLLECTION_NAME.drop()
db.user.drop()

db.表名.insert({"name":"zhangsan"}); student 集合名称(表)

查询

1、查询所有记录

db.userInfo.find();

相当于:
select* from userInfo;

2、查询去掉后的当前聚集集合中的某列的重复数据

db.userInfo.distinct("name");

会过滤掉 name 中的相同数据
相当于:select distict name from userInfo;

3、查询 age = 22 的记录

db.userInfo.find({"age": 22});

相当于:select * from userInfo where age = 22;

4、查询 age > 22 的记录

db.userInfo.find({age: {$gt: 22}});

相当于:select * from userInfo where age >22;

5、查询 age < 22 的记录

db.userInfo.find({age: {$lt: 22}});

相当于:select * from userInfo where age <22;

6、查询 age >= 25 的记录

db.userInfo.find({age: {$gte: 25}});

相当于:select * from userInfo where age >= 25;

7、查询 age <= 25 的记录

db.userInfo.find({age: {$lte: 25}});

8、查询 age >= 23 并且 age <= 26 注意书写格式

db.userInfo.find({age: {$gte: 23, $lte: 26}});

9、查询 name 中包含 mongo 的数据 模糊查询用于搜索

db.userInfo.find({name: /mongo/});

相当于: select * from userInfo where name like ‘%mongo%’;

11、查询指定列 name、age 数据

db.userInfo.find({}, {name: 1, age: 1});

相当于:select name, age from userInfo;
当然 name 也可以用 true 或 false,当用 ture 的情况下河 name:1 效果一样,如果用 false 就 是排除 name,显示 name 以外的列信息。

12、查询指定列 name、age 数据, age > 25

db.userInfo.find({age: {$gt: 25}}, {name: 1, age: 1});

相当于:select name, age from userInfo where age >25;

13、按照年龄排序 1 升序 -1 降序

升序:db.userInfo.find().sort({age: 1});
降序:db.userInfo.find().sort({age: -1});

14、查询 name = zhangsan, age = 22 的数据

db.userInfo.find({name: 'zhangsan', age: 22});

相当于:select * from userInfo where name = ‘zhangsan’ and age = ‘22’;

15、查询前 5 条数据

db.userInfo.find().limit(5);

相当于:selecttop 5 * from userInfo;

16、查询 10 条以后的数据

db.userInfo.find().skip(10);

相当于:select from userInfo where id not in ( selecttop 10 from userInfo)

17、查询在 5-10 之间的数据

db.userInfo.find().limit(10).skip(5);

可用于分页,limit 是 pageSize,skip 是第几页*pageSize

18、or 与 查询

db.userInfo.find({$or: [{age: 22}, {age: 25}]});

相当于:select * from userInfo where age = 22 or age = 25;

19、findOne 查询第一条数据

db.userInfo.findOne();

相当于:selecttop 1 * from userInfo; db.userInfo.find().limit(1);

20、查询某个结果集的记录条数 统计数量

db.userInfo.find({age: {$gte: 25}}).count();

相当于:select count(*) from userInfo where age >= 20;

如果要返回限制之后的记录数量,要使用 count(true)或者 count(非 0) db.users.find().skip(10).limit(5).count(true)

修改

修改里面还有查询条件。你要该谁,要告诉 mongo。
查找名字叫做小明的,把年龄更改为 16 岁:

db.student.update({"name":"小明"},{$set:{"age":16}});

查找数学成绩是 70,把年龄更改为 33 岁:

db.student.update({"score.shuxue":70},{$set:{"age":33}});

更改所有匹配项目:

db.student.update({"sex":"男"},{$set:{"age":33}},{multi: true});

完整替换,不出现$set 关键字了: 注意

db.student.update({"name":"小明"},{"name":"大明","age":16});

db.users.update({name: 'Lisi'}, {$inc: {age: 50}}, false, true);

相当于:update users set age = age + 50 where name = ‘Lisi’;

db.users.update({name: 'Lisi'}, {$inc: {age: 50}, $set: {name: 'hoho'}}, false, true);

相当于:update users set age = age + 50, name = ‘hoho’ where name = ‘Lisi’;

删除

db.collectionsNames.remove( { "borough": "Manhattan" } )
db.users.remove({age: 132});

删除一个

db.restaurants.remove( { "borough": "Queens" }, { justOne: true } )
查看原文

赞 1 收藏 2 评论 0

ddee 发布了文章 · 2018-06-16

关于mongodb数据库的增删改查

查看所有数据库列表

show dbs

使用数据库、创建数据库

use student

如果真的想把这个数据库创建成功,那么必须插入一个数据。

数据库中不能直接插入数据,只能往集合(collections)中插入数据。不需要专门创建集合,只 需要写点语法插入数据就会创建集合:

db.student.insert({“name”:”xiaoming”});

db.student 系统发现 student 是一个陌生的集合名字,所以就自动创建了集合。 显示当前的数据集合(mysql 中叫表)

show collections

删除数据库,删除当前所在的数据库

db.dropDatabase();

删除集合

db.COLLECTION_NAME.drop()
db.user.drop()

db.表名.insert({"name":"zhangsan"}); student 集合名称(表)

查询

1、查询所有记录

db.userInfo.find();

相当于:
select* from userInfo;

2、查询去掉后的当前聚集集合中的某列的重复数据

db.userInfo.distinct("name");

会过滤掉 name 中的相同数据
相当于:select distict name from userInfo;

3、查询 age = 22 的记录

db.userInfo.find({"age": 22});

相当于:select * from userInfo where age = 22;

4、查询 age > 22 的记录

db.userInfo.find({age: {$gt: 22}});

相当于:select * from userInfo where age >22;

5、查询 age < 22 的记录

db.userInfo.find({age: {$lt: 22}});

相当于:select * from userInfo where age <22;

6、查询 age >= 25 的记录

db.userInfo.find({age: {$gte: 25}});

相当于:select * from userInfo where age >= 25;

7、查询 age <= 25 的记录

db.userInfo.find({age: {$lte: 25}});

8、查询 age >= 23 并且 age <= 26 注意书写格式

db.userInfo.find({age: {$gte: 23, $lte: 26}});

9、查询 name 中包含 mongo 的数据 模糊查询用于搜索

db.userInfo.find({name: /mongo/});

相当于: select * from userInfo where name like ‘%mongo%’;

11、查询指定列 name、age 数据

db.userInfo.find({}, {name: 1, age: 1});

相当于:select name, age from userInfo;
当然 name 也可以用 true 或 false,当用 ture 的情况下河 name:1 效果一样,如果用 false 就 是排除 name,显示 name 以外的列信息。

12、查询指定列 name、age 数据, age > 25

db.userInfo.find({age: {$gt: 25}}, {name: 1, age: 1});

相当于:select name, age from userInfo where age >25;

13、按照年龄排序 1 升序 -1 降序

升序:db.userInfo.find().sort({age: 1});
降序:db.userInfo.find().sort({age: -1});

14、查询 name = zhangsan, age = 22 的数据

db.userInfo.find({name: 'zhangsan', age: 22});

相当于:select * from userInfo where name = ‘zhangsan’ and age = ‘22’;

15、查询前 5 条数据

db.userInfo.find().limit(5);

相当于:selecttop 5 * from userInfo;

16、查询 10 条以后的数据

db.userInfo.find().skip(10);

相当于:select from userInfo where id not in ( selecttop 10 from userInfo)

17、查询在 5-10 之间的数据

db.userInfo.find().limit(10).skip(5);

可用于分页,limit 是 pageSize,skip 是第几页*pageSize

18、or 与 查询

db.userInfo.find({$or: [{age: 22}, {age: 25}]});

相当于:select * from userInfo where age = 22 or age = 25;

19、findOne 查询第一条数据

db.userInfo.findOne();

相当于:selecttop 1 * from userInfo; db.userInfo.find().limit(1);

20、查询某个结果集的记录条数 统计数量

db.userInfo.find({age: {$gte: 25}}).count();

相当于:select count(*) from userInfo where age >= 20;

如果要返回限制之后的记录数量,要使用 count(true)或者 count(非 0) db.users.find().skip(10).limit(5).count(true)

修改

修改里面还有查询条件。你要该谁,要告诉 mongo。
查找名字叫做小明的,把年龄更改为 16 岁:

db.student.update({"name":"小明"},{$set:{"age":16}});

查找数学成绩是 70,把年龄更改为 33 岁:

db.student.update({"score.shuxue":70},{$set:{"age":33}});

更改所有匹配项目:

db.student.update({"sex":"男"},{$set:{"age":33}},{multi: true});

完整替换,不出现$set 关键字了: 注意

db.student.update({"name":"小明"},{"name":"大明","age":16});

db.users.update({name: 'Lisi'}, {$inc: {age: 50}}, false, true);

相当于:update users set age = age + 50 where name = ‘Lisi’;

db.users.update({name: 'Lisi'}, {$inc: {age: 50}, $set: {name: 'hoho'}}, false, true);

相当于:update users set age = age + 50, name = ‘hoho’ where name = ‘Lisi’;

删除

db.collectionsNames.remove( { "borough": "Manhattan" } )
db.users.remove({age: 132});

删除一个

db.restaurants.remove( { "borough": "Queens" }, { justOne: true } )
查看原文

赞 1 收藏 2 评论 0

ddee 收藏了文章 · 2018-06-16

前端面试日记(二)

大概是在6月11号在Boss直聘投的简历,6月12号中午收到电话约的面试时间,刚开始说是13号晚上7点;后面可能时间有变,中午来了个电话说改到9-10点;怎么说算是第一次面试自己目标公司之一吧,记录下不管过没过,也是一份宝贵经历。
  • (面试时间:2018-6-12 晚上:9.00;时长:1小时11分钟;公司:6666,(一面))

(一)简单的介绍下自己

  • 介绍的真的很简单。。。。。。

(二)平时都是怎么学习前端的?

  • me:学习前端的话,我主要是以书籍为主、然后是网站视频、博客、文档等学习理论,之后再通过代码实践。。。
  • H:前端的学习的话一般是得通过实践的,平时有自己做过项目吗?
  • me:学习基础的js阶段的话主要是通过实现一些基本特效和模块功能;在学习jQuery的时候做过一个

(三)做过哪些项目,你在其中主要工作

  • 说了下使用JQuery阶段,做过一个比较简单的商场;
  • 在接触React是,也就是最近做的项目是一个完全使用React全家桶搭建的二手商场;
  • 其中主要的工作的话就是负责前端的大部分工作,包括界面的规划,还有就是前后端交互等;
  • 估计是一面,之后并没有很深入的问项目了,直接转到谈实习经历。

(四)看你有在淘宝美工的实习经历,说说你的工作

  • 当时是在深圳的一家小型的电商公司实习的,主要工作的话,包括一些简单的PS图片处理;
  • 还有就是店铺的代码美工优化,因为在淘宝和阿里的平台上店铺的装修可以通过代码进行书写;但是都会有对应的使用限制(简单的说了下自己的日常工作)

(五)React组件的创建方式和区别

  • React组件在本质上就是一个类,创建方式可以说用三种形式:
  1. React.createClass:是最传统、兼容性最好的方法,当是相对与其他ES6的创建方式来说代码量偏多;
  2. ES6 class创建:React.Component是以ES6的形式来创建react的组件的,是React目前极为推荐的创建有状态组件的方式,最终会取代React.createClass形式;相对于 React.createClass可以更好实现代码复用;
  3. 无状态组件(直接函数定义):只传入两个参数props、context两个参数;不存在state,没有生命周期;
  • 说的优缺点不是太详细,这里科普下:

1、 无状态函数式组件

  • 无状态组件的创建形式使用一个使代码的可读性更好,并且减少了大量冗余的代码,精简至只有一个render方法,大大的增强了编写一个组件的便利
  • 无状态组件不会像其它两种方法一样在调用时会创建新实例;它创建时始终保持了一个实例,避免了不必要的检测和内存分配,坐到了内部的优化;
  • 组件不能访问this对象

    • 无状态组件由于没有实例化过程,所以无法访问组件this中的对象,例如:this.state等均不能访问。
  • 组件无法访问生命周期的方法

2、React.createClass

  • 创建有状态的组件,这些组件是要被实例化的,并且可以访问组件的生命周期方法。
  • 一般需要管理组件内部的状态、使用生命周期方法或者进行this绑定会使用这种形式创建组件。

3、React.createClass与React.Component区别

  • 函数this自绑定

    • React.createClass创建的组件,其每一个成员函数的this都有React自动绑定;
    • React.Component创建的组件,其成员函数不会自动绑定this,需要开发者手动bind绑定,否则this不能获取当前组件实例对象。
  • 组件属性类型propTypes及其默认props、state属性配置不同
const ItemComponent = React.createClass({
    propTypes: { 
        name: React.PropTypes.string
    },
     getInitialState(){ 
        return {
            isLogin: false
        }
    },
    getDefaultProps(){ 
        return {
            name: 'li'    
        }
    }
    render(){
        return <div>{this.props.name}</div>
    }
})
//  VS
class ItemComponent extends React.Component {
    static propTypes = {
        name: PropTypes.string
    };

    static defaultProps = {
        name: ''
    };
    constructor(props) {
        super(props)
        this.state = {
             isLogin: false
        }
    }
    render(){
        return <div>{this.props.name}</div>
    }
}

(六)说说React生命周期

(七)React中不管在生命情况下只要调用了Reader方法,界面都会重新渲染吗?

  • 答:不一定
  • 问:为什么呢?
  • 答:。。。。(当时没想到为啥?但问了呢肯定是有坑的)落落的回答了一点概念;
  • 解答:React在调用render方法后只是构建出了虚拟DOM,之后还会经历Diff算法的调和过程,找出最小差异树,然后通过最少的DOM操作将其构建到真实的DOM中;
  • 答:(恍悟,原来是问这个意思,赶紧补下)但是在render方法调用后,我们该是没有办法对其进行渲染的阻止的;这些过程只能由React内部控制。

(八)问个简单的CSS基础,说说相对布局和绝对布局

  • 恩恩,好好~没有骗人

(九)问下js基础,数组的操作

  • 不会改变原数组的方法:

    • concat:拼接两个数组,返回拼接后的数组;
    • filter():接收一个函数作为参数,数组中每个元素执行函数,返回执行该函数时返回true的元素组成的数组。
    • map: 返回执行函数后组成的数组;
    • reduce:累加器;
    • slice() 方法返回一个从开始到结束(不包括结束)选择的数组的一部分浅拷贝到一个新数组对象
    • forEach() 方法对数组的每个元素执行一次提供的函数
    • join() 方法将一个数组(或一个类数组对象)的所有元素连接成一个字符串并返回这个字符串。
  • 会改变原数组

    • pop()删除尾部元素,返回删除的元素;
    • push()添加尾部元素,返回数组长度;
    • shift()删除头部元素,返回删除的元素;
    • unshift()网头部添加元素,返回长度;
    • splice()添加、删除,

(十)你怎么理解同源策略?

  • 同源限制主要是为了安全,如果没有同源限制存在浏览器中的cookie等其他数据可以任意读取,不同域下DOM任意操作,Ajax任意请求,这会有很严重的安全隐患;
  • 为了保护不同站点和用户的隐私安全,个浏览器便制定了同源策略;
  • 所谓同源即要求协议、域名、端口号完全相同;
  • 一般解决跨域的方式常用的有JSONP(只支持 GET 请求)、跨域资源共享CORS(服务器端通过设置Access-Control-Allow-Origin来进行的)、服务器端设置代理请求:服务器端不受同源策略限制

(十一)浏览器向服务器发送请求,有哪些请求方式

  • 1)GET:获取数据
  • (2)POST:提交数据
  • (3)HEAD:请求头信息
  • (4)PUT:上传文档到服务器
  • (5)DELETE:删除远程服务器上的某个文档
  • (6)OPTION

(十二)你说你常用get、和post请求,说说区别

  • 发送的请求数不一样,get发送一个TCP数据包,post两个;
  • get向服务器请求数据,数据放于URL后相对不安全、post发送数据相对更加安全点;
  • post数据发送大小大于get;但两种都会有限制(浏览器和服务器都会限制)

(十三)状态码的话说说301和302的区别?

  • 一个临时重定向;一个永久重定向

(十三)简单的说说在浏览器中输入一个RUL但显示页面的整个过程?

(十三)问些简单的算法,就说说你所知道的排序算法吧?

  • 冒泡排序
  • 选择排序
  • 插入排序
  • 归并排序
  • 快速排序

(十四)对于你个数值(十进制)如何最快的知道它在二进制中有多少个1

  • 恩恩,直接传化为二进制就知道啦?求解?????
  • 给我耐心的讲解了,当时懂了点,现在再多研究下吧

(十五)给你一块正方体蛋糕,中间任意位置挖出一个小正方体,如何切一刀将它切成等分的两半

  • 还好不是太难,想想看……………………
整个过程CSS、Js没怎么问,感觉侧重于框架、网络、算法这些;相比之前的面试问题没有很多,就是涉及的比较广,偏向于问实践;然后面试官挺好的,不同的或者不足的都会给指出,给解释
  • 说一个礼拜左右给结果,恩恩~不过怎样数据结构偏弱,补补再说!
大概能想起这么多了
查看原文

ddee 提出了问题 · 2018-06-14

请问用nginx怎么解决本地服务器跨域问题

我自己写了个nodejs服务器接口
想用nginx做跨域处理,请问怎么做
(就是想试一下不在接口中做操作,只通过nginx来实现跨域,可行吗)

关注 2 回答 1

ddee 提出了问题 · 2018-06-05

解决大家有用过“给赞”小程序吗,它那个“赞赏码”的制作原理是什么

大家有用过“给赞”小程序吗,它那个“赞赏码”的制作原理是什么

关注 2 回答 1

ddee 赞了文章 · 2018-05-20

理解Node.js(译文)

前言

总括 :这篇文章十分生动形象的的介绍了Node,满足了读者想去了解Node的需求。作者是Node的第一批贡献者之一,德国前端大神。译者觉得作者的比喻很适合初学者理解Node,特此翻译。

译者 :原文网址里有只小蚂蚁的效果很有意思(多次鼠标悬浮会有惊喜),哈哈哈,可以去看一下哦。

本文属于译文

正文

当我向别人介绍Node.js 的时候一般会有两种反应,要么是立马就弄明白它是个什么玩意儿,要么是被它搞的很糊涂。

如果你现在还处于后者,下面就是我对于node的解释:

  • 它是一个命令行工具,你可以下载一个tarball文件,编译然后安装源文件;

  • 它可以让你在你的终端输入node my_app.js 来运行Javascript程序;

  • Node的JS代码是由 V8 javascript 引擎(就是那个使得Chrome如此之快的东西)所执行的;

  • Node提供了诸如访问网络或是操作文件系统的Javascript API

“但我也可以用 Ruby, Python, Php,Java, ...等语言来做我想要做的事啊”

我听到你说的话了,你是对的。Node不是狡猾的独角兽,这点很抱歉,它不会帮你做你该做的事。它仅仅是一个工具,而且他也不会替代你现在所常用的一些工具,至少现在不会。

"说重点!!!"

好的,我会的,当你需要同时做好几件事的时候Node会表现的十分优秀。你有写了一段代码然后对他说"我想你可以并行运行!"的体验吗?哈哈哈,在Node中除了你的代码所有的东西都是并行运行的。

"啊?!"

是的,没错,除了你的代码之外所有的代码都是并行运行的。为了理解这一点,你可以把你自己的代码想象成一个国王,而Node就是他的仆人军队。

新的一天是这样开始的:某个仆人叫醒了国王,然后问他是否需要什么。国王给了这个仆人一个任务清单然后就回去继续睡觉了。然后这个仆人就把任务清单上的任务分发下去,仆人们开始工作了。

当一个仆人完成了他的任务的时候,他就跑到国王寝宫外面排队等候报告。国王一次只能听取一个仆人报告任务,有的时候国王会在仆人报告结束的时候给他更多的任务。(看你代码咋写咯)

生活是美好的,因为国王的诸多仆人同时执行多个任务,但报告结果的时候是一个一个来的,所以国王能够很专注。

"那确实很美好,但你能结束这个愚蠢的比喻用更加geek的方式来告诉我吗?"

好的,一个node程序或许是下面这样的:

var fs = require('fs')
  , sys = require('sys');
//译者注:sys is deprecated. Use util instead.这里我们直接用console.log即可
fs.readFile('treasure-chamber-report.txt', function(report) {
  //sys.puts("oh, look at all my money: "+report);
  console.log("oh, look at all my money: "+report)
});

fs.writeFile('letter-to-princess.txt', '...', function() {
  //sys.puts("can't wait to hear back from her!");
  console.log("can't wait to hear back from her!")
});

你的代码(国王)给了node(仆人)两个任务即读(readFile)和写(writeFile)文件,然后就去睡大觉了。一旦node完成了某个任务,跟这个任务对应的回调就会触发。但同一时间只能有一个回调被触发,在那个回调执行完成之前,所有其它的回调都得排队等待。进一步说,回调触发的顺序是不能被保证的。

"所以我不必担心代码在同一时间访问同一个数据结构?"

你确实理解了,这就是JavaScript的单进程/事件循环设计美丽的地方。

"好棒,但我为什么应该用它呢?"

一个原因是效率。在一个web应用中,响应时间主要是花在了执行数据库查询上面,而用node,你可以一次性执行所有的数据库查询。将响应时间减少到了执行最慢的数据库查询所用的时间。

另一个原因是Javascript。你可以使用Node让你的浏览器和后端共享代码。Javascript也在渐渐成为一门真正的通用语言。不管你在过去是用Python, Ruby, Java, PHP, ...等等,你都或多或少的使用过Javasctipt,对吗?

最后一个原因是原生速度。V8正在不断的推进作为地球上最快的动态语言编译器之一的边界,我也想不到有任何其它的语言在速度上能够像Javascript一样不断的高歌猛进。再进一步说,node的I/O设备真的十分的轻量,能够让你尽可能最大程度的利用系统的I/O容量。

"所以你是说从现在开始我应该用Node写我所有的应用么?"

是也不是,一旦你开始舞弄node这柄锤子,所有的东西都会开始变得像钉子。但如果你当前的工作有一个deadline,你可以参考下面的几点来做决定用不用node:

  • 低响应时间/高并发是否重要?Node真的很擅长处理这俩问题;

  • 项目有多大?小项目没问题,如果是大项目就应该认真评估了(可用的库,修复一个bug所需的资源或者two upstream等等)

"我能在Node中访问DOM吗?"

这是一个好问题!答案是不行,DOM是浏览器的东西吗,不过幸好node的JS引擎(V8)跟那些混乱的东西是完全分离的。不过,有人在以node模块的形式来实现DOM,或许带来令人兴奋的可能性比如对客户端代码进行单元测试。(译者注:现在已经有人实现了这个模块,详情查看Node-dom)。

"难道事件驱动编程真的很难吗?"

这取决于你自己,如果你已经学会了如何在浏览器里调用Ajax或是调用某个事件,那么学习node对你不会是什么难题。

同时,测试驱动开发能够真正的帮助你从做一个可维护的设计开始学习node。

"我应该从哪里学到更多?"

Tim Caswell正在运作优秀的How To Node博客。在twitter上Follow nodejs。订阅邮件列表。(译者注:也可以结合Node.js 6.9.5 文档进行学习,另外,译者写了一个node的小应用node-sample可以clone下来看下)

后记

本篇文章的比如讲真是有些简单了,但从现实事物中找到真正相对应的也是在太难。,另外,由于时间原因,本文一些不妥之处或是当时还处在实验性阶段的东西译者或删或改。能力有限,水平一般,翻译不妥之处,还望指正。感谢。

查看原文

赞 4 收藏 19 评论 1

认证与成就

  • 获得 10 次点赞
  • 获得 45 枚徽章 获得 0 枚金徽章, 获得 10 枚银徽章, 获得 35 枚铜徽章

擅长技能
编辑

开源项目 & 著作
编辑

(゚∀゚ )
暂时没有

注册于 2017-08-09
个人主页被 576 人浏览