10月

28

Redux学习(一)

张努力 前端 vue
Redux 是 JavaScript 的状态容器,提供可预测的状态管理。 概念和 API store store 是 redux 保存数据的地方,通俗的来说就是一个仓库。整个应用里面只能有一个 store 在redux里面提供了一个创建store的 APIcreateStore import { createStore } from 'redux' const store = createStore(...) const state = store.getState() 提供一个获取state的方法 提供一个dispatch的方法更新state 通过 subscribe(listener) 注册监听器 Action 本质上就是一个普通的 js 对象,但是 action 里面必须有一个 type 字段,表示执行的动作 const action = { type: "ADD_TODO", payload: "zhangnuli" }; Action Creator 视图层要发送多少种消息,就有多少种 action,可以定义一个函数生成 Action。 const ADD_TODO = "添加 TODO"; function actionCreator(text) { return { type: ADD_TODO, text }; } const action = addTodo("Learn Redux"); store.subscribe(),一旦 state 发生变化,就会执行这个函数 import { createStore } from "redux"; const store = createStore(reducer); store.subscribe(listener); 派发 action,是让 store 里面的数据发生改变的唯一途径。 import { createStore } from 'redux' let store = createStore(...) function addTodo(text) { return { type: 'ADD_TODO', text } } store.dispatch(addTodo('Read the docs')) Reducer store 收到 action 后,必须需要给出一个新的 state,这样才会出发视图层的变化。这种计算的过程叫做 Reducer。Reducer 是一个函数,接收 action 和 state 作为参数,返回一个新的 state const reducer = function(state, action) { // ... return new_state; }; 在整个 应用中,我们可以给一个 state 的默认值 const defaultState = 0; const reducer = (state = defaultState, action) => { switch (action.type) { case "ADD": return state + action.payload; default: return state; } }; const state = reducer(1, { type: "ADD", payload: 2 }); reducer 是一个纯函数,reducer 不能改变 state,必须返回一个新的 state switch (action.type) { case SET_VISIBILITY_FILTER: return Object.assign({}, state, { visibilityFilter: action.filter }); case ADD_TODO: return Object.assign({}, state, { todos: [ ...state.todos, { text: action.text, completed: false } ] }); default: return state; } Reducer 的拆分 Reducer 函数负责生成 State。由于整个应用只有一个 State 对象,包含所有数据,对于大型应用来说,这个 State 必然十分庞大,导致 Reducer 函数也十分庞大。 没拆分之前的 reducer function todoApp(state = initialState, action) { switch (action.type) { case SET_VISIBILITY_FILTER: return Object.assign({}, state, { visibilityFilter: action.filter }); case ADD_TODO: return Object.assign({}, state, { todos: [ ...state.todos, { text: action.text, completed: false } ] }); case TOGGLE_TODO: return Object.assign({}, state, { todos: state.todos.map((todo, index) => { if (index === action.index) { return Object.assign({}, todo, { completed: !todo.completed }); } return todo; }) }); default: return state; } } 拆分之后的 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 Object.assign({}, todo, { completed: !todo.completed }); } return todo; }); default: return state; } } function todoApp(state = initialState, action) { switch (action.type) { case SET_VISIBILITY_FILTER: return Object.assign({}, state, { visibilityFilter: action.filter }); case ADD_TODO: return Object.assign({}, state, { todos: todos(state.todos, action) }); case TOGGLE_TODO: return Object.assign({}, state, { todos: todos(state.todos, action) }); default: return state; } } 在上面的代码中,把 reducer 进行了拆分,变成了独立的一个函数。Redux 提供了一个combineReducers()方法,用于合并拆分的 reducer import { combineReducers } from "redux"; import * as reducers from "./reducers"; const todoApp = combineReducers(reducers);
阅读更多 >>

10月

23

读明朝那些事

张努力 随笔 读书
在学生时期就曾读过明朝那些事这部书,不过因为学习的原因,就一直没有读完,在最近一段时间,又看见了这个名字,我觉得有必要把这本书读完了 这本书的作者当年明月,并不是一个专业研究这类历史的,当然这本书也非常的幽默和通俗易懂。 这本书是以小说的方式来写,但是又不像三国演义那样,带有偏见的去描述历史。这本书多讲述的事件都是有史可查的。 这本书是以元朝末年到明朝末年为时间点贯穿全文,在每个时间段都会有许许多多形形色色的人,正直的、狡诈的。发现了那些曾在历史的长河里发光发热的人,或者到现在还在口口相传。 帮助朱元璋开过的武将,徐达,常遇春。迁都北京并建立宫城的朱棣,主编《永乐大典》的大才子解缙,留下一一部百科大全,“滚滚长江东逝水,浪花淘尽英雄”的杨慎。 不惧牺牲,为官清廉,写下“千锤万凿出深山,烈火焚烧若等闲。粉骨碎身全不怕,要留清白在人间”千古名诗的于谦。刚正不阿的海青天海瑞。 有名的航海家郑和,七下西洋,完成人类是历史上的壮举。提起来咬牙切齿的魏忠贤。明代最为人推崇的心学创始人王阳明,军事指挥才能也极为突出,他的心学影响了后来一代又一代的仁人志士。大奸臣严嵩,开创”万历新政“的张居正。说出”半似日兮半似月,曾被金龙咬一缺“预言的刘伯温… 抛出那些邪恶之人,我看到那些能人志士对理想的热忱,无论是身在庙堂,还是江湖,都在时时刻刻心系天下,为自己的理想而奋斗着。明知前路没有任何希望,我也要带着自己的尊严和抗争走下去,不同流合污。 在严嵩专权,沈炼,杨继盛死劾严嵩,视死如归。宦官张敏为保护当时还小的明孝宗朱佑樘免受万贵妃的迫害,自杀而死。 读至此总是让人感到深深的震撼,士为知己者死,总有一种东西,它看不见摸不着,旁人无法理解甚至嗤之以鼻,唯有自己知道,这是自己可以交换生命去维护捍卫的,人的气节终将屹立于天地间 英雄从来都有气势恢宏的人生,他们都有过人的天资,让我等凡人须仰视才见。历史从来都是重复的,又从来都是不一样的。今天,尤其是太平盛世下的我等。也不必效法于英雄,不必介怀历史的云烟。和平是任何一个时代人民最美好的追求。我们现在的生活又何尝不是战争年代经过战火洗礼的英雄们想过的生活呢? 建立帝国,制定一系列制度的朱元璋。一生戎马,死在征战路上的朱棣。大胖子朱高炽。有能力但有爱玩蛐蛐的朱瞻基。被俘的皇帝朱祁镇。从地上到天上再到地下朱祁钰。口吃的朱见深。不立妃,不纳妾。生命不息,工作不止的朱佑樘。不让吃猪肉,开办妓院的朱厚照。 喜欢炼丹,追求长生的朱厚熜(嘉靖)。好色的朱载垕。不喜欢上朝的朱翊钧(万历)。吃药吃死的?朱常洛。只想做个木匠的朱由校。悲哀的朱由检。
阅读更多 >>

10月

23

Vue组件之间的传值

张努力 前端 vue
父组件向子组件传值 props传值 可以传递字符串,数组,对象… 子组件写法 <template> <span>{{ title }}</span> </template> <script> export default { props: ['title'] }; </script> 子组件通过props来接收父组件传递过来的值 上面的props是数组的写法,也可以写成对象的方式,可以规定父组件传递过来的值是什么类型 <template> <span>{{ title }}</span> </template> <script> export default { props: { title: String } }; </script> 父组件写法 <template> <div> <Children title='测试'></Children> </div> </template> <script> import Children from "./components/children"; export default { components: { Children }, }; </script> 还可以动态的传值,通过v-bind传递动态数据 <template> <div> <Children v-bind:title="test"></Children> </div> </template> <script> import Children from "./components/children"; export default { data() { return { test: "测试" }; }, components: { Children } }; </script> 子组件向父组件传递数据 子组件主要通过事件给父组件传递消息 通过使用$emit发射事件 子组件写法 <template> <div> <button @click="handEmit"></button> </div> </template> <script> export default { data() { return { list: [1, 2] }; }, methods: { handEmit() { this.$$emit("pops", this.list); } } }; </script> 父组件写法 <template> <div> <Children @pops="getData"></Children> </div> </template> <script> import Children from "./components/children"; export default { data() { return { list: null }; }, methods: { //处理子组件的数据 getData(data) { this.list = data; } }, components: { Children } }; </script> 子组件之间相互传递 子组件与子组件没有直接的传递方法 可以先传递给父组件,再通过父组件传递给字组件
阅读更多 >>

10月

18

Webpack学习 (十四) 抽离公共文件

张努力 工具 webpack
有的时候需要把公共的代码抽离出来,单独打包成一个文件 module.exports = { optimization: { splitChunks: { cacheGroups: { common: { minChunks: 2, chunks: 'initial', minSize: 0 } }, }, } cacheGroups:缓存组 minChunks:被引用多少次才进行抽离 chunks:选择哪些块进行优化,可以是all,async,initial minSize:要生成的块的最小大小 抽离第三方代码库 splitChunks: { cacheGroups: { vendor: { test:/node_modules/, minChunks: 2, chunks: 'initial', minSize: 0, name:"common" }, common: { minChunks: 2, chunks: 'initial', minSize: 0, name:"common" } }, } vendor就是第三方组件库了 引用 new MiniCssExtractPlugin({ filename: "css/[name].css", chunks: ['index',"common"] }), new MiniCssExtractPlugin({ filename: "css/[name].css", chunks: ['about',"common"] }), new HtmlWebpackPlugin({ title: '首页', minify: false, filename: 'index.html', template: path.resolve(__dirname, 'src/index.html'), chunks: ['index',"common"] }), new HtmlWebpackPlugin({ title: '关于', minify: false, filename: 'about.html', template: path.resolve(__dirname, 'src/about.html'), chunks: ['about',"common"] }) 在chunks加入缓存组的名字就可以了
阅读更多 >>

10月

15

Webpack学习 (十三) 多应用打包

张努力 工具 webpack
配置多个出口 entry: { index: './src/index.js', about:'./src/about.js' }, 多个出口 output: { filename: 'js/[name].js', path: path.resolve(__dirname, 'dist') }, [name]代表index和about 在src目录下新建一个about.html,about.js 生成多个HTML文件 new HtmlWebpackPlugin({ title: '首页', minify: false, filename:'index.html', template: path.resolve(__dirname, 'src/index.html'), chunks: ['index'] }), new HtmlWebpackPlugin({ title: '关于', minify: false, filename:'about.html', template: path.resolve(__dirname, 'src/about.html'), chunks: ['about'] }) chunks:代表着入口文件名字,会自动引入对应的JS文件 生成多个CSS文件,并且相应的HTML文件引入对应的css文件 new MiniCssExtractPlugin({ filename: "css/[name].css", chunks: ['index'] }), new MiniCssExtractPlugin({ filename: "css/[name].css", chunks: ['about'] }), chunks:代表着入口文件名字,会自动引入对应的CSS文件 clean-webpack-plugin每次打包清理dist文件夹 在实际开发中我们需要不断的调整代码和修改,会不断的进行打包,每次就会有新的文件产生,造成dist目录里的文件非常多,这样就需要打包前清除一个dist文件夹 安装yarn add clean-webpack-plugin -D 使用,放入需要清理的文件夹 const CleanWebpackPlugin = require("clean-webpack-plugin"); ... plugins:[ new CleanWebpackPlugin(["dist"]) ]
阅读更多 >>

10月

13

Webpack学习 (十二) 文件分类

张努力 工具 webpack
现在打包的结果是所有的文件都在dist目录下,没有进行文件分类,想要把css放在一个文件夹下,图片放在一个文件夹下,js放在一个文件夹下 图片分类 { test: /.(png|jpg|gif)$/, use: [ { loader: 'url-loader', options: { limit: 8192, outputPath:'img/' }, }, ], }, outputPath:输出,上面的是输出到img目录下 css分类 plugins: [ new MiniCssExtractPlugin({ filename: "css/[name].css" }) ] 只需要在filename加上文件夹的名字就可以了 但是css里面的引入背景图片的地址会发生错误,在改造一个css规则 { test: /.css$/, use: [ { loader: MiniCssExtractPlugin.loader, options: { publicPath: '../' } }, 'css-loader', 'postcss-loader'] }, JS分类 output: { filename: 'js/[name].js', path: path.resolve(__dirname, 'dist') }, 在filename里面加上文件夹就可以了
阅读更多 >>

10月

10

Webpack学习 (十一) 图片处理

张努力 工具 webpack
引入图片的方式 在JS动态创建img标签引入 let cImg = new Image() cImg.src = './img/book.png' document.body.append(cImg) //这样是显示不出来的,我们需要导入进来 let cImg = new Image() cImg.src = require('./img/book.png') document.body.append(cImg) 但是这样还是不行,还需要file-loader进行解析 安装 yarn add file-loader -D module.exports = { module: { rules: [ { test: /.(png|jpg|gif)$/, use: [ { loader: 'file-loader', options: {}, }, ], }, ], }, }; 打包后就会看到有一张图片 在css中背景图片引入 .div{ width: 100px; height: 100px; background: url(../img/book.png) no-repeat center; background-size: cover; } css是支持的,因为css-loader可以解析 在html中以img标签引入 需要安装html-loader进行解析 安装 yarn add html-loader 增加一条规则 { test:/.html$/, use:'html-loader' }, 打包后就会发现img 的src图片地址发生了变化 小的图片打包成base64 有的时候,一些小的图片不想发送http请求,我们可以把图片打包成base64格式,从而减少http请求 安装url-loaderyarn add url-loader -D 修改一下配置文件 把上面的file-loader修改成url-loader limit是限制,小于多少的kb的图片换换成base64 { test: /.(png|jpg|gif)$/, use: [ { loader: 'url-loader', options: { limit: 8192 }, }, ], },
阅读更多 >>

类别

时间

标签