React Redux
学习必备要点:
- 首先弄明白,Redux在使用React开发应用时,起到什么作用——状态集中管理
- 弄清楚Redux是如何实现状态管理的——store、action、reducer三个概念
- 在React中集成Redux:redux + react-redux(多了一个概念——selector)
- Redux调试工具:redux devtools
redux结构图
其中红色虚线部分为redux的内部集成,不能显示的看到。
- action:是事件,它本质上是JavaScript的普通对象,它描述的是“发生了什么”。action由type:string和其他构成。
- reducer是一个监听器,只有它可以改变状态。是一个纯函数,它不能修改state,所以必须是生成一个新的state。在default情况下,必须但会旧的state。
- store是一个类似数据库的存储(或者可以叫做状态树),需要设计自己的数据结构来在状态树中存储自己的数据。
Redux入门
Redux简介
Redux是一个状态集中管理库。
安装
npm install --save redux
附加包
多数情况下我们需要使用 React 绑定库和开发者工具。
npm install --save react-redux
npm install --save-dev redux-devtools
三大原则
单一数据源
整个应用的state被存储在一棵object tree中,并且这个object tree只存在于唯一一个store中。
State是只读的
惟一改变 state 的方法就是触发 action,action 是一个用于描述已发生事件的普通对象。
使用纯函数来执行修改
为了描述action如何改变状态树,我们需要编写reducers。Reducer只是一些纯函数,他接受先前的state和action,并返回新的state对象。
上图是Redux如何实现状态管理的框架,View(视图) 可以通过store.dispatch()方法传递action。 Action相当于事件模型中的事件,它描述发生了什么。Reducer相当于事件模型中的监听器,它接收一个旧的状态和一个action,从而处理state的更新逻辑,返回一个新的状态,存储到Store中。而从store–>view 的部分,则是通过mapStateToProps
这个函数来从Store中读取状态,然后通过props属性的方式注入到展示组件中。图中红色虚线部分是Redux内部处理,我们不必过多考虑这部分的实现。
Action
Action 是把数据从应用传到store的有效载荷,它是store数据的唯一来源,一般来说,我们通过store.dispatch()将action传到store。
Action创建函数
Action 创建函数 就是生成 action 的方法。“action” 和 “action 创建函数” 这两个概念很容易混在一起,使用时最好注意区分。
Redux中action创建函数只是简单返回一个action。
改变userName的示例:
export function changeUserName(userName) { // action创建函数return { // 返回一个actiontype: 'CHANGE_USERNAME',payload: userName,};
}
Action 本质上是JavaScript 普通对象。我们规定,action 内必须使用一个字符串类型的 type
字段来表示将要执行的动作。多数情况下,type
会被定义成字符串常量。当应用规模越来越大时,建议使用单独的模块或文件来存放 action。
除了 type
字段外,action 对象的结构完全由你自己决定。参照 Flux 标准 Action 获取关于如何构造 action 的建议,另外还需要注意的是,我们应该尽量减少在action中传递数据。
Reducer
Action只是描述有事情发生这一事实,而Reducer用来描述应用是如何更新state。
设计State结构
在 Redux 应用中,所有的 state 都被保存在一个单一对象中。在写代码之前我们首先要想清楚这个对象的结构,要用最简单的形式把应用中的state用对象描述出来。
HelloApp应用的state结构很简单,只需要保存userName即可:
{userName: 'World'}
处理 Reducer 关系时的注意事项
开发复杂的应用时,不可避免会有一些数据相互引用。建议你尽可能地把 state 范式化,不存在嵌套。把所有数据放到一个对象里,每个数据以 ID 为主键,不同实体或列表间通过 ID 相互引用数据。把应用的 state 想像成数据库。这种方法在 normalizr 文档里有详细阐述
Action处理
确定了 state 对象的结构,就可以开始开发 reducer。reducer 就是一个纯函数,接收旧的 state 和 action,返回新的 state。
(state, action) => newState
之所以称作 reducer 是因为它将被传递给 Array.prototype.reduce(reducer, ?initialValue)
方法。保持 reducer 纯净非常重要。永远不要在 reducer 里做以下操作:
- 修改传入参数;
- 执行有副作用的操作,如 API 请求和路由跳转;
- 调用非纯函数,如
Date.now()
或Math.random()
。
在后续的学习终将会介绍如何执行有副作用的操作,现在只需谨记reducer一定要保持纯净。只要传入参数相同,返回计算得到的下一个 state 就一定相同。没有特殊情况、没有副作用,没有 API 请求、没有变量修改,单纯执行计算。
我们将写一个reducer,让它来处理之前定义过的action。我们可以首先指定state的初始状态。
const initState = { /** 指定初始状态 */userName: 'World!'
}export default function helloAppReducer(state=initState, action) {switch(action.type) {case 'CHANGE_USERNAME':return {userName: action.payload, // 改变状态};default:return state; // 返回旧状态}
}
警告:
不要修改
state
。如果涉及多个状态时,可以采用对象展开运算符的支持,来返回一个新的状态。 假设我们的实例中还存在其它状态,但是我们只需要改变userName
的值,那么上述示例我们可以采用以下方式返回新的状态:return {...state,userName: action.payload }
在default情况下返回旧的
state
。 遇到未知的action时,一定要返回旧的state
。
Reducer拆分
这里我们以redux中文文档 中的todo应用为例来说明,在应用的需求中,有添加todo项,设置todo列表的过滤条件等多个action,同理我们就需要写多个reducer来描述状态是怎么改变的,建议把todo列表的更新和设置过滤条件放在两个reducer中去实现:
function todos(state = [], action) {switch (action.type) {case ADD_TODO:return [...state,{text: action.text,completed: false}]case TOGGLE_TODO:return state.map((todo, index) => {if (index === action.index) {return {...todo,completed: !todo.completed}}return todo})default:return state}
}function todoApp(state = initialState, action) {switch (action.type) {case SET_VISIBILITY_FILTER:return {...state,visibilityFilter: action.filter}case ADD_TODO:case TOGGLE_TODO:return {...state,todos: todos(state.todos, action)}default:return state}
}
todos
依旧接收 state
,但它变成了一个数组!现在 todoApp
只把需要更新的一部分 state 传给 todos
函数,todos
函数自己确定如何更新这部分数据。这就是所谓的 reducer 合成,它是开发 Redux 应用最基础的模式。
现在我们可以开发一个函数来做为主 reducer,它调用多个子 reducer 分别处理 state 中的一部分数据,然后再把这些数据合成一个大的单一对象。主 reducer 并不需要设置初始化时完整的 state。初始时,如果传入 undefined
, 子 reducer 将负责返回它们的默认值。这个过程就是reducer合并。
下面的这段代码是reducer合并的两种方式:
export default function todoApp(state = {}, action) {return {visibilityFilter: visibilityFilter(state.visibilityFilter, action),todos: todos(state.todos, action)}
}
每个 reducer 只负责管理全局 state 中它负责的一部分。每个 reducer 的 state 参数都不同,分别对应它管理的那部分 state 数据.
import { combineReducers } from 'redux';const todoApp = combineReducers({visibilityFilter,todos
})export default todoApp;
combineReducers()
所做的只是生成一个函数,这个函数来调用你的一系列 reducer,每个 reducer 筛选出 state 中的一部分数据并处理,然后这个生成的函数再将所有 reducer 的结果合并成一个大的对象。
Store
前面的部分,我们学会使用action来描述发生了什么,使用reducers来根据action更新state的用法。
Store则是把action和reducers联系到一起的对象,它有以下职责:
- 维持应用的 state;
- 提供
getState()
方法获取 state; - 提供
dispatch(action)
方法更新 state; - 通过
subscribe(listener)
注册监听器; - 通过
subscribe(listener)
返回的函数注销监听器。
再次说明Redux应用只有一个单一的store。 当需要拆分处理数据逻辑时,我们应该使用 reducer 组合 而不是创建多个 store。
根据已有的reducer来创建store是非常容易的。在我们的HelloApp应用中,我们将helloAppReducer
导入,并传递给createStore()
。
import { createStore } from 'redux'
import helloAppReducer from './reducers'let store = createStore(helloAppReducer) // 创建store
createStore()
的第二个参数是可选的, 用于设置 state 初始状态。
备注:
其实这种数据结构是有reducer确定的,就像helloAPP的例子中,
const reducer = combineReducers({hello: hello,city: cityReducer
})
而由redux-devtools
工具查看到的是下图这样的:
so,存储在store中的数据结构是由reducer确定的。
数据流
严格的单向数据流 是Redux架构的核心设计。这就意味着应用中所有的数据都遵循相同的生命周期,这样可以让应用变得更加可预测且容易理解。同时也鼓励做数据范式化,这样可以避免使用多个且独立的无法相互引用的重复数据。
Redux应用中数据的生命周期遵循以下4个步骤:
调用
store.dispatch(action)
。Action 就是一个描述“发生了什么”的普通对象。比如:
{ type: 'CHANGE_USERNAME', payload: "Welcome to Redux" };
我们可以在任何地方调用
store.dispatch(action)
包括组件中、XHR回调中、甚至是定时器中。Redux store 调用传入的 reducer 函数。
Store 会把两个参数传入 reducer: 当前的 state 树和 action。
const initState = { /** 指定初始状态 */userName: 'World!' }export default function helloAppReducer(state=initState, action) { // 传入两个参数switch(action.type) {case 'CHANGE_USERNAME':return {userName: action.payload, // 改变状态};default:return state; // 返回当前状态} }
reducer 是纯函数。它仅仅用于计算下一个 state。它应该是完全可预测的:多次传入相同的输入必须产生相同的输出。它不应做有副作用的操作,如 API 调用或路由跳转。这些应该在 dispatch action 前发生。
根 reducer 应该把多个子 reducer 输出合并成一个单一的 state 树。
根 reducer 的结构完全由我们自己决定。Redux 原生提供
combineReducers()
辅助函数,来把根 reducer 拆分成多个函数,用于分别处理 state 树的一个分支。Redux store 保存了根 reducer 返回的完整 state 树。
这个新的树就是应用的下一个state。所有订阅
store.subscribe(listener)
的监听器都将被调用;监听器里可以调用store.getState()
获取当前的state。
示例: Hello App
如果想查看示例的源码,请查看这里。Hello App源码
开始之前我们需要清楚实际上Redux和React之间并没有关系。Redux支持React、Angular、Ember、jQuery甚至纯JavaScript。即便如此,Redux 还是和 React 和 Deku 这类框架搭配起来用最好,因为这类框架允许你以 state 函数的形式来描述界面,Redux 通过 action 的形式来发起 state 变化。
下面我们将用React来开发一个Hello World的简单应用。
安装React Redux
Redux默认并不包含 React 绑定库,需要单独安装。
npm install --save react-redux
容器组件和展示组件
Redux 的 React 绑定库是基于 容器组件和展示组件相分离 的开发思想。而容器组件和展示组件大致有以下不同:
展示组件 | 容器组件 |
---|---|
作用 | 描述如何展现内容、样式 |
是否能直接使用Redux | 否 |
数据来源 | props(属性) |
数据修改 | 从props中调用回调函数 |
调用方式 | 手动 |
大部分的组件都应该是展示型的,但一般需要少数的几个容器组件把它们和Redux store连接起来。
技术上来说我们可以直接使用 store.subscribe()
来编写容器组件。但不建议这么做,因为这样写就无法使用 React Redux 带来的性能优化。同样,不要手写容器组件,我们直接使用 React Redux 的 connect()
方法来生成,后面会详细介绍。
需求分析
我们的需求很简单,我们只是想要展示hello + userName,默认为“Hello World!”,当我们在输入框中输入不同的值时,会显示不同的“hello,_”问候语,由此可以分析出该应用只有一个状态,那就是{ userName: ‘张三’}
展示组件
该应用只有一个展示组件HelloPanel:
HelloPanel
用于显示输入框及展示数据
userName
: 要展示的数据onChange(userName)
: 当输入值发生变化时调用的回调函数
该组件之定义外观并不设计数据从哪里来,如果改变它,传入什么就渲染什么,如果你把代码从Redux迁移到别的架构,该组件可以不做任何改动直接使用。
容器组件
还需要一个容器组件来把展示组件连接到Redux。例如HelloPanel
组件需要一个状态类似HelloApp的容器来监听Redux store变化并处理如何过滤出要展示的数据。
HelloApp
根据当前显示状态来对展示组件进行渲染。
组件编码
Action创建函数
action.js
export function changeUserName(userName) {return {type: 'CHANGE_USERNAME',payload: userName,}; }
Reducer
index.js
const initState = { /** 指定初始状态 */userName: 'World!' }export default function helloAppReducer(state=initState, action) {switch(action.type) {case 'CHANGE_USERNAME':return {userName: action.payload, // 改变状态};default:return state; // 返回当前状态} }
展示组件
HelloPanel.js
import React from 'react';export default function HelloPanel(props) { let input return (<div><p>Hello, {props.userName}</p><input ref={node => {input = node}} onChange={()=>props.onChange(input.value)}/></div> ); }
容器组件
使用
connect()
创建容器组件前,需要先定义mapStateToProps
这个函数来指定如何把当前 Redux store state 映射到展示组件的 props 中。例如:HelloApp
中需要计算const mapStateToProps = (state) => {return { userName: state.userName } // 返回期望注入到展示组件的props中的参数 };
除了读取state,容器组件还能分发action。类似的方式,可以定义
mapDispatchToProps()
方法接收dispatch()
方法并返回期望注入到展示组件的 props 中的回调方法。const mapDispatchToProps = (dispatch) => ({onChange: (userName) => {dispatch(changeUserName(userName)) // 返回期望注入到展示组件的 props 中的回调方法} })
最后,使用
connect()
创建HelloApp
,并传入这两个函数。import { connect } from 'react-redux'; import HelloPanel from './HelloPanel';const HelloApp = connect( // 产生一个新的组件mapStateToProps,mapDispatchToProps, )(HelloPanel)
这就是 React Redux API 的基础,但还漏了一些快捷技巧和强大的配置。建议仔细学习 React Redux文档。如果你担心
mapStateToProps
创建新对象太过频繁,可以学习如何使用 reselect 来 计算衍生数据。
传入Store
所有容器组件都可以访问 Redux store,所以可以手动监听它。一种方式是把它以 props 的形式传入到所有容器组件中。但这太麻烦了,因此必须要用 store
把展示组件包裹一层,恰好在组件树中渲染了一个容器组件。
建议的方式是使用指定的 React Redux 组件 <Provider>
来让所有容器组件都可以访问 store,而不必显示地传递它。只需要在渲染根组件时使用即可。
import React from 'react'
import { render } from 'react-dom'
import { createStore } from 'redux'
import { Provider } from 'react-redux'
import HelloApp from './HelloApp'
import HelloPanel from './reducers'let store = createStore(HelloPanel)render(<Provider store={store}><HelloApp /></Provider>,document.getElementById('root')
)
到这里,我们已经基本掌握了Redux的基础及核心概念,有了这些,我们就可以开发简单的应用,关于Redux的更多实例、高级应用、技巧、API文档等可以查看redux中文文档 。
子状态树与combineReducers(reducers)
简介
随着应用变得复杂,需要对 reducer 函数 进行拆分,拆分后的每一块独立负责管理 state 的一部分。
combineReducers
辅助函数的作用是,把一个由多个不同 reducer 函数作为 value 的 object,合并成一个最终的 reducer 函数,然后就可以对这个 reducer 调用 createStore
。
合并后的 reducer 可以调用各个子 reducer,并把它们的结果合并成一个 state 对象。state 对象的结构由传入的多个 reducer 的 key 决定。
最终,state 对象的结构会是这样的:
{reducer1: ...reducer2: ...
}
使用:
combineReducers({hello, cityReducer
})
state 对象的结构:
// 实际例子
{"hello":{"userName":"张三"}, "cityReducer":{"city":"北京"}
}
通过为传入对象的 reducer 命名不同来控制 state key 的命名。
e.g.:
你可以调用 combineReducers({hello: hello,city: cityReducer})
将 state 结构变为{ hello, city }
通常的做法是命名 reducer,然后 state 再去分割那些信息,因此你可以使用 ES6 的简写方法:combineReducers({ hello, city })
。这与 combineReducers({ hello: hello,city: cityReducer })
一样。
对于reducer的结构,我们规定只能是一级的,也就是
{"hello":{"userName":"张三"}, "cityReducer":{"city":"北京"}
}
这种结构,不能再有子树,这样是为了方便进行管理。
参数
reducers
(Object)是一个对象,它的值(value) 对应不同的 reducer 函数,这些 reducer 函数后面会被合并成一个。下面会介绍传入 reducer 函数需要满足的规则。
之前的文档曾建议使用 ES6 的
import * as reducers
语法来获得 reducer 对象。这一点造成了很多疑问,因此现在建议在reducers/index.js
里使用combineReducers()
来对外输出一个 reducer。下面有示例说明。
返回值
(Function):一个调用 reducers
对象里所有 reducer 的 reducer,并且构造一个与 reducers
对象结构相同的 state 对象。
注意
本函数设计的时候有点偏主观,就是为了避免新手犯一些常见错误。也因些我们故意设定一些规则,但如果你自己手动编写根 redcuer 时并不需要遵守这些规则。
每个传入 combineReducers
的 reducer 都需满足以下规则:
- 所有未匹配到的 action,必须把它接收到的第一个参数也就是那个
state
原封不动返回。 - 永远不能返回
undefined
。当过早return
时非常容易犯这个错误,为了避免错误扩散,遇到这种情况时combineReducers
会抛异常。 - 如果传入的
state
就是undefined
,一定要返回对应 reducer 的初始 state。根据上一条规则,初始 state 禁止使用undefined
。使用 ES6 的默认参数值语法来设置初始 state 很容易,但你也可以手动检查第一个参数是否为undefined
。
实例:
const hello = (state = {userName: 'Hehe'}, action) => { // 设置了初始值switch (action.type) {case 'USER_CHANGE':return {userName: action.userName}// 所有未匹配到的 action,必须把它接收到的第一个参数也就是那个 state 原封不动返回。default: return state}
}export default hello
异步action
学习到这里,我们所接触的下图上的所有实现,都是针对同步事件的。如果只是这样,那么我们肯定不能放心大胆的使用redux在我们的项目中,因为我们实际项目中,更多的都是异步事件。所以接下来,让我们来介绍一个复杂的场景,我们来看看redux是如何应用在大型复杂充满异步事件的场景中的。
我们仍然会遵守上图,这是我们的核心,不能改变,下面我们来看一个实际的例子,工资列表页面。
工资列表页面
也就是一个普通的通过网络请求,去请求列表数据的列表的展示。我们先来分析一下状态,列表页面的状态。
状态(state)
是一种数据结构,存储在store中的数据
异步加载的页面的状态:“加载中;加载成功,展示列表;加载失败” 这三种状态。我们给这三种状态来取一个名字,并设置0,1,2来顺序表示不同的状态。
loadingListStatus:0|1|2
我们主要做的是列表页的展示,那么还有一个最重要的数据结构就是列表数据,我们来取一个名字:
salaryList:[]
接下来我们再来分析一下,action,也就是事件。
事件
列表展示过程中的数据,也就是:“开始加载;加载成功;加载失败”这三个事件。其实整个过程和之前使用promise来实现的异步操作是一样的。我们是监听action,然后产生异步操作,执行dispatch方法,将数据结构保存到store中。
例子
我们来看一个获取列表的请求:
function fetchSalayList(subreddit) {return dispatch => {dispatch(loadingAction(subreddit))// 开始加载return fetch(`http://www.reddit.com/r/${subreddit}.json`).then(response => response.json()).then(json => { // 加载成功dispatch(loadingSucessAction(subreddit, json))}, (error) => { // 加载失败dispatch(loadingErroeAction(subreddit))}}
}
上述这种方式,完全符合我们的核心图表,并且实现了异步操作。
在异步操作这块,我们建议使用 redux-saga 中间件来创建更加复杂的异步 action。其中涉及到es6中的Generators可以在文档中查看。另外,还有 redux-saga的使用的一个例子可以看这里。
异步数据流
默认情况下,createStore()
所创建的 Redux store 没有使用 middleware,所以只支持 同步数据流。
你可以使用 applyMiddleware()
来增强 createStore()
。虽然这不是必须的,但是它可以帮助你用简便的方式来描述异步的 action。
像 redux-thunk 或 redux-promise 这样支持异步的 middleware 都包装了 store 的 dispatch()
方法,以此来让你 dispatch 一些除了 action 以外的其他内容,例如:函数或者 Promise。你所使用的任何 middleware 都可以以自己的方式解析你 dispatch 的任何内容,并继续传递 actions 给下一个 middleware。比如,支持 Promise 的 middleware 能够拦截 Promise,然后为每个 Promise 异步地 dispatch 一对 begin/end actions。
当 middleware 链中的最后一个 middleware 开始 dispatch action 时,这个 action 必须是一个普通对象。这是 同步式的 Redux 数据流 开始的地方(译注:这里应该是指,你可以使用任意多异步的 middleware 去做你想做的事情,但是需要使用普通对象作为最后一个被 dispatch 的 action ,来将处理流程带回同步方式)。
参考
- [React-Redux性能优化](https://segmentfault.com/a/1190000006120707)
- 官网-中文
- redux的异步实现
- es6特性-Generators
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
相关文章
- Vue学习(一)
目录一、Vue概念1、渐进式JavaScript框架1.1、Vue 扩展插件2、作用:3、作者:二、Vue的特点1、与其它前端 JS 框架的关联三、Vue指南3.1、Vue的浏览器插件3.2、简单示例四、MVVM模式4.1、声明式编程4.2、命令式编程4.3 MVC、MVP和MVVM的理解4.3.1 MVC4.3.…...
2024/4/22 0:49:20 - react路由
在 web 应用开发中,路由系统是不可或缺的一部分。在浏览器当前的 URL 发生变化时,路由系统会做出一些响应,用来保证用户界面与 URL 的同步。随着单页应用时代的到来,为之服务的前端路由系统也相继出现了。有一些独立的第三方路由系…...
2024/4/20 19:38:25 - Asp.Net MVC一 : 三层架构、MVC
MVC、MVP、MVVM、Angular.js、Knockout.js、Backbone.js、React.js、Ember.js、Avalon.js、Vue.js 概念摘录认清Android框架 MVC,MVP和MVVM三层架构 将整个业务应用划分为:界面层(User Interface layer, UIL)、业务逻辑层…...
2024/4/21 5:00:30 - vue双向绑定、Proxy、defineproperty
本文原链接:https://www.jianshu.com/p/2df6dcddb0d7 前言 双向绑定其实已经是一个老掉牙的问题了,只要涉及到MVVM框架就不得不谈的知识点,但它毕竟是Vue的三要素之一. Vue三要素 响应式: 例如如何监听数据变化,其中的实现方法就是我们提到的双向绑定模板引擎: 如何…...
2024/4/21 5:00:29 - .NET方面的框架的整理和总结
.NET方面的框架的整理和总结.NET方面的框架的整理和总结分布式缓存框架:.NET方面的框架的整理和总结 自从学习.NET以来,优雅的编程风格,极度简单的可扩展性,足够强大开发工具,极小的学习曲线,让我对这个平…...
2024/4/21 5:00:29 - 实现双向绑定Proxy比defineproperty优劣如何?
前言 双向绑定其实已经是一个老掉牙的问题了,只要涉及到MVVM框架就不得不谈的知识点,但它毕竟是Vue的三要素之一. Vue三要素 响应式: 例如如何监听数据变化,其中的实现方法就是我们提到的双向绑定 模板引擎: 如何解析模板 渲染: Vue如何将监听到的数据变化和解析后的HTML进行…...
2024/4/21 5:00:28 - 前端面试宝典超
一、HTML和CSS 1、你做的页面在哪些流览器测试过?这些浏览器的内核分别是什么? IE: trident内核 Firefox:gecko内核 Safari:webkit内核 Opera:以前是presto内核,Opera现已改用Google Chrome的Blink内核 Chrome:Blink(基于webkit,…...
2024/4/21 5:00:26 - 实现双向绑定Proxy比defineproperty优劣如何
面试官: 实现双向绑定Proxy比defineproperty优劣如何? 面试官系列(4): 实现双向绑定Proxy比defineproperty优劣如何? 往期 面试官系列(1): 如何实现深克隆面试官系列(2): Event Bus的实现面试官系列(3): 前端路由的实现前言 双向绑定其实已经是一个老掉牙的问题了,只要涉及…...
2024/4/21 5:00:25 - 双向绑定篇
面试官: 实现双向绑定Proxy比defineproperty优劣如何? 面试官系列(4): 实现双向绑定Proxy比defineproperty优劣如何? 往期 面试官系列(1): 如何实现深克隆面试官系列(2): Event Bus的实现面试官系列(3): 前端路由的实现前言 双向绑定其实已经是一个老掉牙的问题了,只要涉及到…...
2024/4/21 5:00:25 - prerender-SPA程序的SEO优化策略
随着web2.0的兴起,ajax的时代已经成为了事实,更如今Knockout,backbone, angular,ember前端MDV(model driver view)框架强势而来,Single Page Application已经为大家所熟悉了。如今常见的SPA程序,restfull和前端MDV之类的框架能够实…...
2024/4/21 5:00:24 - Vue基础6天实施笔记
Vue 基础课程 课程介绍 Vue基础语法 指令、过滤器、按键修饰符、生命周期、自定义指令、computed计算属性、watch监听器 axios、ES6模块化、组件、vue单文件组件、WebStorage SPA单页应用、router路由、Promise VueCLI脚手架、element-ui组件库、eslint代码规范检测等等 …...
2024/5/4 1:42:29 - 2017年技术、平台、工具、语言架构
技术、平台、工具、语言&框架,年底应该这样把握技术方向! 原创 2017-12-01 ThoughtWorks InfoQ 作者|ThoughtWorks编辑|小智ThoughtWorks 已于昨日发布了最新一期的技术雷达,InfoQ 第一时间拿到了先手资料&#x…...
2024/4/30 18:59:34 - 深度强化学习落地方法论(3)——算法选择篇
目录前言强化学习——探索和利用的平衡游戏DQNDDPGA3C其他算法 前言 虽然每年RL方向的paper满天飞,但真正具有普遍实用价值的突破性工作实在不多,大多数还是在经典框架基础上的改进和扩展。DRL常规武器库里的存货主要还是老三样:DQN,DDPG和A3C,它们是深度学习时代最成熟、…...
2024/5/3 23:06:11 - ng中定义service和filter的方法
angularjs子定义Service用法? $http的用法? $http是Angularjs内置的服务,用起来可以链式调用,用法如下: myMdoule.controller(LoadDataCtrl,[$scope,$http,function($scope,$http){$http({method : get,url : js/data…...
2024/4/21 5:00:21 - angular7+editor.md
1.下载editor.md源文件 https://pandao.github.io/editor.md/#download 2.将下载的源文件放在项目某目录下: 例如:src/assets/editor.md/ 3.在angular.json文件中,将所需要引入的css、js文件添加进来 "styles": ["src/ass…...
2024/4/20 19:38:36 - Angular 学习系列 - - $sce 和 $sceDelegate
$sce $sce 服务是AngularJs提供的一种严格上下文转义服务。 严格的上下文转义服务 严格的上下文转义(SCE)是一种需要在一定的语境中导致AngularJS绑定值被标记为安全使用语境的模式。由用户通过ng-bind-html绑定任意HTML语句就是这方面的一个例子。我们称这些上下文转义为特权或…...
2024/4/20 19:38:35 - Angular - - $sce 和 $sceDelegate
$sce $sce 服务是AngularJs提供的一种严格上下文转义服务。 严格的上下文转义服务 严格的上下文转义(SCE)是一种需要在一定的语境中导致AngularJS绑定值被标记为安全使用语境的模式。由用户通过ng-bind-html绑定任意HTML语句就是这方面的一个例子。我们称这些上下文转义为特权或…...
2024/4/20 19:38:34 - 一次ionic3上传图片的经历
一次ionic3上传图片的经历 概述 本文只是回顾这样一次经历,所以不会贴大段大段代码当时拿到的需求是,先在手机上写好签名,然后上传到服务器持久化到数据库,最后供web和移动端以图片的形式展示出来。 过程 第一反应是这功能有啥…...
2024/4/20 19:38:33 - angular12实现Markdown显示和编辑
实现Markdown显示 安装 ngx-markdown npm install ngx-markdown --save再angular.json 中引入对应的css文件和js文件 "styles": ["src/styles.css","node_modules/prismjs/themes/prism-okaidia.css","node_modules/prismjs/plugins/li…...
2024/4/21 11:38:13 - angularjs 实现多个图片上传及预览
1 <div class"form-group">2 <label>上传申请单</label>3 <ul class"list_img clearfix">4 <li ng-repeat"imageSrc in imgshows track by $index"…...
2024/4/20 19:38:31
最新文章
- 【C++】学习笔记——vector_1
文章目录 七、vector1. vector的介绍2. vector的使用 未完待续 七、vector vector 1. vector的介绍 学了 string类 后,学习其他容器就非常简单了。 vector 是表示可变大小数组的序列容器。就是高配版数组。用法就是 vector< class T> name 。 2. vector的…...
2024/5/4 5:17:23 - 梯度消失和梯度爆炸的一些处理方法
在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言,在此感激不尽。 权重和梯度的更新公式如下: w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...
2024/3/20 10:50:27 - MongoDB初探:安装与图形化界面保姆级使用指南
文章目录 前言一、MongoDB下载安装下载解压配置环境变量打开mongoDB 二、配置本地MongoDB服务创建文件下载服务测试服务 三、图形化界面Compass GUINavicat GUI 总结 前言 MongoDB是一种流行的开源、面向文档的NoSQL数据库程序。与传统的关系型数据库不同,MongoDB将…...
2024/5/3 7:44:46 - 面试经典算法系列之双指针1 -- 合并两个有序数组
面试经典算法题1 – 合并两个有序数组 LeetCode.88 公众号:阿Q技术站 问题描述 给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。 请你 合并 nums2 到 nums1 中&#…...
2024/5/3 9:00:01 - K8S容器空间不足问题分析和解决
如上图,今天测试环境的K8S平台出现了一个问题,其中的一个容器报错:Free disk space below threshold. Available: 3223552 bytes (threshold: 10485760B),意思服务器硬盘空间不够了。这个问题怎么产生的,又怎么解决的呢…...
2024/5/2 2:38:17 - 【外汇早评】美通胀数据走低,美元调整
原标题:【外汇早评】美通胀数据走低,美元调整昨日美国方面公布了新一期的核心PCE物价指数数据,同比增长1.6%,低于前值和预期值的1.7%,距离美联储的通胀目标2%继续走低,通胀压力较低,且此前美国一季度GDP初值中的消费部分下滑明显,因此市场对美联储后续更可能降息的政策…...
2024/5/1 17:30:59 - 【原油贵金属周评】原油多头拥挤,价格调整
原标题:【原油贵金属周评】原油多头拥挤,价格调整本周国际劳动节,我们喜迎四天假期,但是整个金融市场确实流动性充沛,大事频发,各个商品波动剧烈。美国方面,在本周四凌晨公布5月份的利率决议和新闻发布会,维持联邦基金利率在2.25%-2.50%不变,符合市场预期。同时美联储…...
2024/5/2 16:16:39 - 【外汇周评】靓丽非农不及疲软通胀影响
原标题:【外汇周评】靓丽非农不及疲软通胀影响在刚结束的周五,美国方面公布了新一期的非农就业数据,大幅好于前值和预期,新增就业重新回到20万以上。具体数据: 美国4月非农就业人口变动 26.3万人,预期 19万人,前值 19.6万人。 美国4月失业率 3.6%,预期 3.8%,前值 3…...
2024/4/29 2:29:43 - 【原油贵金属早评】库存继续增加,油价收跌
原标题:【原油贵金属早评】库存继续增加,油价收跌周三清晨公布美国当周API原油库存数据,上周原油库存增加281万桶至4.692亿桶,增幅超过预期的74.4万桶。且有消息人士称,沙特阿美据悉将于6月向亚洲炼油厂额外出售更多原油,印度炼油商预计将每日获得至多20万桶的额外原油供…...
2024/5/3 23:10:03 - 【外汇早评】日本央行会议纪要不改日元强势
原标题:【外汇早评】日本央行会议纪要不改日元强势近两日日元大幅走强与近期市场风险情绪上升,避险资金回流日元有关,也与前一段时间的美日贸易谈判给日本缓冲期,日本方面对汇率问题也避免继续贬值有关。虽然今日早间日本央行公布的利率会议纪要仍然是支持宽松政策,但这符…...
2024/4/27 17:58:04 - 【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响
原标题:【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响近日伊朗局势升温,导致市场担忧影响原油供给,油价试图反弹。此时OPEC表态稳定市场。据消息人士透露,沙特6月石油出口料将低于700万桶/日,沙特已经收到石油消费国提出的6月份扩大出口的“适度要求”,沙特将满…...
2024/4/27 14:22:49 - 【外汇早评】美欲与伊朗重谈协议
原标题:【外汇早评】美欲与伊朗重谈协议美国对伊朗的制裁遭到伊朗的抗议,昨日伊朗方面提出将部分退出伊核协议。而此行为又遭到欧洲方面对伊朗的谴责和警告,伊朗外长昨日回应称,欧洲国家履行它们的义务,伊核协议就能保证存续。据传闻伊朗的导弹已经对准了以色列和美国的航…...
2024/4/28 1:28:33 - 【原油贵金属早评】波动率飙升,市场情绪动荡
原标题:【原油贵金属早评】波动率飙升,市场情绪动荡因中美贸易谈判不安情绪影响,金融市场各资产品种出现明显的波动。随着美国与中方开启第十一轮谈判之际,美国按照既定计划向中国2000亿商品征收25%的关税,市场情绪有所平复,已经开始接受这一事实。虽然波动率-恐慌指数VI…...
2024/4/30 9:43:09 - 【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试
原标题:【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试美国和伊朗的局势继续升温,市场风险情绪上升,避险黄金有向上突破阻力的迹象。原油方面稍显平稳,近期美国和OPEC加大供给及市场需求回落的影响,伊朗局势并未推升油价走强。近期中美贸易谈判摩擦再度升级,美国对中…...
2024/4/27 17:59:30 - 【原油贵金属早评】市场情绪继续恶化,黄金上破
原标题:【原油贵金属早评】市场情绪继续恶化,黄金上破周初中国针对于美国加征关税的进行的反制措施引发市场情绪的大幅波动,人民币汇率出现大幅的贬值动能,金融市场受到非常明显的冲击。尤其是波动率起来之后,对于股市的表现尤其不安。隔夜美国股市出现明显的下行走势,这…...
2024/5/2 15:04:34 - 【外汇早评】美伊僵持,风险情绪继续升温
原标题:【外汇早评】美伊僵持,风险情绪继续升温昨日沙特两艘油轮再次发生爆炸事件,导致波斯湾局势进一步恶化,市场担忧美伊可能会出现摩擦生火,避险品种获得支撑,黄金和日元大幅走强。美指受中美贸易问题影响而在低位震荡。继5月12日,四艘商船在阿联酋领海附近的阿曼湾、…...
2024/4/28 1:34:08 - 【原油贵金属早评】贸易冲突导致需求低迷,油价弱势
原标题:【原油贵金属早评】贸易冲突导致需求低迷,油价弱势近日虽然伊朗局势升温,中东地区几起油船被袭击事件影响,但油价并未走高,而是出于调整结构中。由于市场预期局势失控的可能性较低,而中美贸易问题导致的全球经济衰退风险更大,需求会持续低迷,因此油价调整压力较…...
2024/4/26 19:03:37 - 氧生福地 玩美北湖(上)——为时光守候两千年
原标题:氧生福地 玩美北湖(上)——为时光守候两千年一次说走就走的旅行,只有一张高铁票的距离~ 所以,湖南郴州,我来了~ 从广州南站出发,一个半小时就到达郴州西站了。在动车上,同时改票的南风兄和我居然被分到了一个车厢,所以一路非常愉快地聊了过来。 挺好,最起…...
2024/4/29 20:46:55 - 氧生福地 玩美北湖(中)——永春梯田里的美与鲜
原标题:氧生福地 玩美北湖(中)——永春梯田里的美与鲜一觉醒来,因为大家太爱“美”照,在柳毅山庄去寻找龙女而错过了早餐时间。近十点,向导坏坏还是带着饥肠辘辘的我们去吃郴州最富有盛名的“鱼头粉”。说这是“十二分推荐”,到郴州必吃的美食之一。 哇塞!那个味美香甜…...
2024/4/30 22:21:04 - 氧生福地 玩美北湖(下)——奔跑吧骚年!
原标题:氧生福地 玩美北湖(下)——奔跑吧骚年!让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 啊……啊……啊 两…...
2024/5/1 4:32:01 - 扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!
原标题:扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!扒开伪装医用面膜,翻六倍价格宰客!当行业里的某一品项火爆了,就会有很多商家蹭热度,装逼忽悠,最近火爆朋友圈的医用面膜,被沾上了污点,到底怎么回事呢? “比普通面膜安全、效果好!痘痘、痘印、敏感肌都能用…...
2024/5/4 2:59:34 - 「发现」铁皮石斛仙草之神奇功效用于医用面膜
原标题:「发现」铁皮石斛仙草之神奇功效用于医用面膜丽彦妆铁皮石斛医用面膜|石斛多糖无菌修护补水贴19大优势: 1、铁皮石斛:自唐宋以来,一直被列为皇室贡品,铁皮石斛生于海拔1600米的悬崖峭壁之上,繁殖力差,产量极低,所以古代仅供皇室、贵族享用 2、铁皮石斛自古民间…...
2024/4/28 5:48:52 - 丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者
原标题:丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者【公司简介】 广州华彬企业隶属香港华彬集团有限公司,专注美业21年,其旗下品牌: 「圣茵美」私密荷尔蒙抗衰,产后修复 「圣仪轩」私密荷尔蒙抗衰,产后修复 「花茵莳」私密荷尔蒙抗衰,产后修复 「丽彦妆」专注医学护…...
2024/4/30 9:42:22 - 广州械字号面膜生产厂家OEM/ODM4项须知!
原标题:广州械字号面膜生产厂家OEM/ODM4项须知!广州械字号面膜生产厂家OEM/ODM流程及注意事项解读: 械字号医用面膜,其实在我国并没有严格的定义,通常我们说的医美面膜指的应该是一种「医用敷料」,也就是说,医用面膜其实算作「医疗器械」的一种,又称「医用冷敷贴」。 …...
2024/5/2 9:07:46 - 械字号医用眼膜缓解用眼过度到底有无作用?
原标题:械字号医用眼膜缓解用眼过度到底有无作用?医用眼膜/械字号眼膜/医用冷敷眼贴 凝胶层为亲水高分子材料,含70%以上的水分。体表皮肤温度传导到本产品的凝胶层,热量被凝胶内水分子吸收,通过水分的蒸发带走大量的热量,可迅速地降低体表皮肤局部温度,减轻局部皮肤的灼…...
2024/4/30 9:42:49 - 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...
解析如下:1、长按电脑电源键直至关机,然后再按一次电源健重启电脑,按F8健进入安全模式2、安全模式下进入Windows系统桌面后,按住“winR”打开运行窗口,输入“services.msc”打开服务设置3、在服务界面,选中…...
2022/11/19 21:17:18 - 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。
%读入6幅图像(每一幅图像的大小是564*564) f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...
2022/11/19 21:17:16 - 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...
win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面,在等待界面中我们需要等待操作结束才能关机,虽然这比较麻烦,但是对系统进行配置和升级…...
2022/11/19 21:17:15 - 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...
有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows,请勿关闭计算机”的提示,要过很久才能进入系统,有的用户甚至几个小时也无法进入,下面就教大家这个问题的解决方法。第一种方法:我们首先在左下角的“开始…...
2022/11/19 21:17:14 - win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...
置信有很多用户都跟小编一样遇到过这样的问题,电脑时发现开机屏幕显现“正在配置Windows Update,请勿关机”(如下图所示),而且还需求等大约5分钟才干进入系统。这是怎样回事呢?一切都是正常操作的,为什么开时机呈现“正…...
2022/11/19 21:17:13 - 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...
Win7系统开机启动时总是出现“配置Windows请勿关机”的提示,没过几秒后电脑自动重启,每次开机都这样无法进入系统,此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一:开机按下F8,在出现的Windows高级启动选…...
2022/11/19 21:17:12 - 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...
有不少windows10系统用户反映说碰到这样一个情况,就是电脑提示正在准备windows请勿关闭计算机,碰到这样的问题该怎么解决呢,现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法:1、2、依次…...
2022/11/19 21:17:11 - 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...
今天和大家分享一下win7系统重装了Win7旗舰版系统后,每次关机的时候桌面上都会显示一个“配置Windows Update的界面,提示请勿关闭计算机”,每次停留好几分钟才能正常关机,导致什么情况引起的呢?出现配置Windows Update…...
2022/11/19 21:17:10 - 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...
只能是等着,别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚,只能是考虑备份数据后重装系统了。解决来方案一:管理员运行cmd:net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...
2022/11/19 21:17:09 - 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?
原标题:电脑提示“配置Windows Update请勿关闭计算机”怎么办?win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢?一般的方…...
2022/11/19 21:17:08 - 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...
关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!关机提示 windows7 正在配…...
2022/11/19 21:17:05 - 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...
钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...
2022/11/19 21:17:05 - 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...
前几天班里有位学生电脑(windows 7系统)出问题了,具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面,长时间没反应,无法进入系统。这个问题原来帮其他同学也解决过,网上搜了不少资料&#x…...
2022/11/19 21:17:04 - 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...
本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法,并在最后教给你1种保护系统安全的好方法,一起来看看!电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中,添加了1个新功能在“磁…...
2022/11/19 21:17:03 - 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...
许多用户在长期不使用电脑的时候,开启电脑发现电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机。。.这要怎么办呢?下面小编就带着大家一起看看吧!如果能够正常进入系统,建议您暂时移…...
2022/11/19 21:17:02 - 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...
配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!配置windows update失败 还原更改 请勿关闭计算机&#x…...
2022/11/19 21:17:01 - 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...
不知道大家有没有遇到过这样的一个问题,就是我们的win7系统在关机的时候,总是喜欢显示“准备配置windows,请勿关机”这样的一个页面,没有什么大碍,但是如果一直等着的话就要两个小时甚至更久都关不了机,非常…...
2022/11/19 21:17:00 - 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...
当电脑出现正在准备配置windows请勿关闭计算机时,一般是您正对windows进行升级,但是这个要是长时间没有反应,我们不能再傻等下去了。可能是电脑出了别的问题了,来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...
2022/11/19 21:16:59 - 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...
我们使用电脑的过程中有时会遇到这种情况,当我们打开电脑之后,发现一直停留在一个界面:“配置Windows Update失败,还原更改请勿关闭计算机”,等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢࿰…...
2022/11/19 21:16:58 - 如何在iPhone上关闭“请勿打扰”
Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...
2022/11/19 21:16:57