首页
统计
墙纸
留言
Search
1
PVE8优化
13 阅读
2
Debian 12 / Ubuntu 22.04 使用源安装 LAMP 教程
12 阅读
3
内核版本 4.9 以上的 Linux 系统开启/关闭 BBR 的方法
10 阅读
4
CSS动画
10 阅读
5
jenkins根据分支、文件夹打包
9 阅读
web前端
Vue
CSS
javascript
React
那些年爬过过的坑
ES6
TypeScrippt
ES7
javascript图灵 - 总结
Node
面试总结
React-Native
Web优化
基础
AngularJS
拍摄
Flutter
Dart
Docker
Linux
mysql
PVE
登录
/
注册
Search
标签搜索
vue+elementui
Cicada
累计撰写
161
篇文章
累计收到
57
条评论
首页
栏目
web前端
Vue
CSS
javascript
React
那些年爬过过的坑
ES6
TypeScrippt
ES7
javascript图灵 - 总结
Node
面试总结
React-Native
Web优化
基础
AngularJS
拍摄
Flutter
Dart
Docker
Linux
mysql
PVE
页面
统计
墙纸
留言
搜索到
152
篇与
的结果
2018-06-28
js获取设置光标位置
window.getSelection() //返回一个 Selection 对象,表示用户选择的文本范围或光标的当前位置。 <!DOCTYPE html> <html> <head> <title>js24.html</title> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="this is my page"> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <!--<link rel="stylesheet" type="text/css" href="./styles.css">--> <!-- 输入完毕之后光标自动移动到下一个框的方法 --> <script type="text/javascript"> function moveNext(object, index) { if (object.value.length == 4) { document.forms[0].elements[index + 1].focus(); } } function showResult() { var f = document.forms[0]; var result = ""; for (var i = 0; i < 4; i++) { result += f.elements[i].value; } alert(result); } </script> </head> <body onload="document.forms[0].elements[0].focus();"> <form> <input type="text" size=3 maxlength=4 onkeyup="moveNext(this,0);">- <input type="text" size=3 maxlength=4 onkeyup="moveNext(this,1);">- <input type="text" size=3 maxlength=4 onkeyup="moveNext(this,2);">- <input type="text" size=3 maxlength=4 onkeyup="moveNext(this,3);"><br> <input type="button" value="显示所有" onclick="showResult();"> </form> </body>
2018年06月28日
4 阅读
0 评论
0 点赞
2018-06-28
判断360浏览器
window.onload = function() { //application/vnd.chromium.remoting-viewer 可能为360特有 var is360 = _mime("type", "application/vnd.chromium.remoting-viewer"); if (isChrome() && is360) { alert("检测到是360浏览器"); } } //检测是否是谷歌内核(可排除360及谷歌以外的浏览器) function isChrome() { var ua = navigator.userAgent.toLowerCase(); return ua.indexOf("chrome") > 1; } //测试mime function _mime(option, value) { var mimeTypes = navigator.mimeTypes; for (var mt in mimeTypes) { if (mimeTypes[mt][option] == value) { return true; } } return false; }
2018年06月28日
2 阅读
0 评论
0 点赞
2018-05-06
React按需加载
1.Bundle.js Bundle组件会接受一个名为 load 的 props load值一是一个组件异步加载的方法 load -> function (cb) {...cb(/ 异步加载的组件 /)},由bundle-loader封装 这个方法需要传入一个回调函数作为参数 回调函数会在在方法内异步接收加载完的组件import React from 'react'; class Bundle extends React.Component { constructor(props){ super(props); this.state = { // 默认为空 mod: null } } componentWillMount() { // 加载初始状态 this.load(this.props); } componentWillReceiveProps(nextProps) { if (nextProps.load !== this.props.load) { this.load(nextProps); } } load(props) { // 重置状态 this.setState({ mod: null }); // 传入组件的组件 props.load((mod) => { this.setState({ mod: mod.default ? mod.default : mod }); }); } render() { // 不为空,则渲染传入的子组件函数 return this.state.mod ? this.props.children(this.state.mod) : null; } } export default Bundle; 2.lazyLoad.js 这个包装函数接受两个值,一个为经过bundle-loader封装的组件,另一个是组件的属性import React from 'react'; import Bundle from './Bundle'; // 默认加载组件,可以直接返回 null const Loading = () => <div>Loading...</div>; /* 包装方法,第一次调用后会返回一个组件(函数式组件) 由于要将其作为路由下的组件,所以需要将 props 传入 <Bundle load={loadComponent}> {Comp => (Comp ? <Comp {...props} /> : <Loading />)} </Bundle> */ const lazyLoad = (loadComponent,props) => {//Bundle 包含的是一个函数子组件 由Bundle.js里的this.props.children(this.state.mod)渲染 return( <Bundle load={loadComponent}> {Comp => (Comp ? <Comp {...props} /> : <Loading />)} </Bundle> );} export default lazyLoad; 3.路由使用有两种使用方式,一种是webpack配置(见下面第四点),另一种是在组件内直接引用bundle-loader(下面代码没注释的就是)//import Home from './page/Home.bundle';//这种方式需要配置webpack的loader //import Detail from './page/Detail.bundle';//这种方式需要配置webpack的loader //-------------------------------------------------- import Detail from 'bundle-loader?lazy&name=home!./page/Detail.bundle'; import Home from 'bundle-loader?lazy&name=home!./page/Home.bundle'; <BrowserRouter> <div> <Route exact path="/" render={()=> <Redirect to="/home"/> // <Home dispatch={dispatch} getState={getState} questionList={value.question}></Home> }/> <Route path="/home" render={()=>{ return lazyLoad(Home, { dispatch:dispatch, getState:getState, questionList:value.question } ); }}/> <Route path="/detail" render={(props)=>{ return lazyLoad(Detail, { pid:props.location.id, questionList:value.question, dispatch:dispatch, answer:value.answer } ); }}/> </div> </BrowserRouter> 4.如果使用webpack配置注意这段代码要放在js的loader之前,不然可能会报错,这段配合下面这两句引用使用//import Home from './page/Home.bundle';//这种方式需要配置webpack的loader//import Detail from './page/Detail.bundle';//这种方式需要配置webpack的loader[html] view plain copy{ test: /\.bundle\.js$/, loader: 'bundle-loader', options: { lazy: true, name: '[name]' }
2018年05月06日
0 阅读
0 评论
0 点赞
2018-05-06
react-redux
Redux 是「React 全家桶」中极为重要的一员,它试图为 React 应用提供「可预测化的状态管理」机制。Redux 本身足够简单,除了 React,它还能够支持其他界面框架。所以如果要将 Redux 和 React 结合起来使用,就还需要一些额外的工具,其中最重要的莫过于 react-redux 了。react-redux 提供了两个重要的对象,Provider 和 connect,前者使 React 组件可被连接(connectable),后者把 React 组件和 Redux 的 store 真正连接起来。react-redux 的文档中,对 connect 的描述是一段晦涩难懂的英文,在初学 redux 的时候,我对着这段文档阅读了很久,都没有全部弄明白其中的意思(大概就是,单词我都认识,连起来啥意思就不明白了的感觉吧)。在使用了一段时间 redux 后,本文尝试再次回到这里,给这段文档(同时摘抄在附录中)一个靠谱的解读。预备知识首先回顾一下 redux 的基本用法。如果你还没有阅读过 redux 的文档,你一定要先去阅读一下。const reducer = (state = {count: 0}, action) => { switch (action.type){ case 'INCREASE': return {count: state.count + 1}; case 'DECREASE': return {count: state.count - 1}; default: return state; } } const actions = { increase: () => ({type: 'INCREASE'}), decrease: () => ({type: 'DECREASE'}) } const store = createStore(reducer); store.subscribe(() => console.log(store.getState()) ); store.dispatch(actions.increase()) // {count: 1} store.dispatch(actions.increase()) // {count: 2} store.dispatch(actions.increase()) // {count: 3}通过 reducer 创建一个 store,每当我们在 store 上 dispatch 一个 action,store 内的数据就会相应地发生变化。我们当然可以直接在 React 中使用 Redux:在最外层容器组件中初始化 store,然后将state 上的属性作为 props 层层传递下去。class App extends Component{ componentWillMount(){ store.subscribe((state)=>this.setState(state)) } render(){ return <Comp state={this.state} onIncrease={()=>store.dispatch(actions.increase())} onDecrease={()=>store.dispatch(actions.decrease())} /> } }但这并不是最佳的方式。最佳的方式是使用 react-redux 提供的 Provider 和 connect 方法。使用 react-redux首先在最外层容器中,把所有内容包裹在 Provider 组件中,将之前创建的 store 作为prop 传给 Provider。const App = () => { return ( <Provider store={store}> <Comp/> </Provider> ) };Provider 内的任何一个组件(比如这里的 Comp),如果需要使用 state 中的数据,就必须是「被 connect 过的」组件——使用 connect 方法对「你编写的组件(MyComp)」进行包装后的产物。class MyComp extends Component { // content... } const Comp = connect(...args)(MyComp);可见,connect 方法是重中之重。connect 详解究竟 connect 方法到底做了什么,我们来一探究竟。首先看下函数的签名:connect([mapStateToProps], [mapDispatchToProps], [mergeProps], [options])connect() 接收四个参数,它们分别是 mapStateToProps,mapDispatchToProps,mergeProps和options。mapStateToProps(state, ownProps) : stateProps这个函数允许我们将 store 中的数据作为 props 绑定到组件上。const mapStateToProps = (state) => { return { count: state.count } }这个函数的第一个参数就是 Redux 的 store,我们从中摘取了 count 属性。因为返回了具有 count 属性的对象,所以 MyComp 会有名为 count 的 props 字段。class MyComp extends Component { render(){ return <div>计数:{this.props.count}次</div> } } const Comp = connect(...args)(MyComp);当然,你不必将 state 中的数据原封不动地传入组件,可以根据 state 中的数据,动态地输出组件需要的(最小)属性。const mapStateToProps = (state) => { return { greaterThanFive: state.count > 5 } }函数的第二个参数 ownProps,是 MyComp 自己的 props。有的时候,ownProps 也会对其产生影响。比如,当你在 store 中维护了一个用户列表,而你的组件 MyComp 只关心一个用户(通过 props 中的 userId 体现)。const mapStateToProps = (state, ownProps) => { // state 是 {userList: [{id: 0, name: '王二'}]} return { user: _.find(state.userList, {id: ownProps.userId}) } } class MyComp extends Component { static PropTypes = { userId: PropTypes.string.isRequired, user: PropTypes.object }; render(){ return <div>用户名:{this.props.user.name}</div> } } const Comp = connect(mapStateToProps)(MyComp);当 state 变化,或者 ownProps 变化的时候,mapStateToProps 都会被调用,计算出一个新的stateProps,(在与 ownProps merge 后)更新给 MyComp。这就是将 Redux store 中的数据连接到组件的基本方式。mapDispatchToProps(dispatch, ownProps): dispatchPropsconnect 的第二个参数是 mapDispatchToProps,它的功能是,将 action 作为 props 绑定到MyComp 上。const mapDispatchToProps = (dispatch, ownProps) => { return { increase: (...args) => dispatch(actions.increase(...args)), decrease: (...args) => dispatch(actions.decrease(...args)) } } class MyComp extends Component { render(){ const {count, increase, decrease} = this.props; return (<div> <div>计数:{this.props.count}次</div> <button onClick={increase}>增加</button> <button onClick={decrease}>减少</button> </div>) } } const Comp = connect(mapStateToProps, mapDispatchToProps)(MyComp);由于 mapDispatchToProps 方法返回了具有 increase 属性和 decrease 属性的对象,这两个属性也会成为 MyComp 的 props。如上所示,调用 actions.increase() 只能得到一个 action 对象 {type:'INCREASE'},要触发这个 action 必须在 store 上调用 dispatch 方法。diapatch 正是 mapDispatchToProps 的第一个参数。但是,为了不让 MyComp 组件感知到 dispatch 的存在,我们需要将 increase 和decrease 两个函数包装一下,使之成为直接可被调用的函数(即,调用该方法就会触发dispatch)。Redux 本身提供了 bindActionCreators 函数,来将 action 包装成直接可被调用的函数。import {bindActionCreators} from 'redux'; const mapDispatchToProps = (dispatch, ownProps) => { return bindActionCreators({ increase: action.increase, decrease: action.decrease }); }同样,当 ownProps 变化的时候,该函数也会被调用,生成一个新的 dispatchProps,(在与statePrope 和 ownProps merge 后)更新给 MyComp。注意,action 的变化不会引起上述过程,默认 action 在组件的生命周期中是固定的。[mergeProps(stateProps, dispatchProps, ownProps): props]之前说过,不管是 stateProps 还是 dispatchProps,都需要和 ownProps merge 之后才会被赋给 MyComp。connect 的第三个参数就是用来做这件事。通常情况下,你可以不传这个参数,connect 就会使用 Object.assign 替代该方法。其他最后还有一个 options 选项,比较简单,基本上也不大会用到(尤其是你遵循了其他的一些 React 的「最佳实践」的时候),本文就略过了。希望了解的同学可以直接看文档。注意:和react-router混用时不能把route, connect(mapStateToProps, mapDispatchToProps)(route).必须分发最高层主件原文
2018年05月06日
1 阅读
0 评论
0 点赞
2018-05-06
React-Router V4
react-router-dom:使用 HTML5 提供的 history API 来保持 UI 和 URL 的同步;:使用 URL 的 hash (例如:window.location.hash) 来保持 UI 和 URL 的同步;:能在内存保存你 “URL” 的历史纪录(并没有对地址栏读写);:从不会改变地址;Route主件path(string): 路由匹配路径。(没有path属性的Route 总是会 匹配);exact(bool):为true时,则要求路径与location.pathname必须完全匹配;strict(bool):true的时候,有结尾斜线的路径只能匹配有斜线的location.pathname;Route渲染方式:在地址匹配的时候React的组件才会被渲染,route props也会随着一起被渲染;:这种方式对于内联渲染和包装组件却不引起意料之外的重新挂载特别方便;:与render属性的工作方式基本一样,除了它是不管地址匹配与否都会被调用;Switch主件的独特之处是独它仅仅渲染一个路由。相反地,每一个包含匹配地址(location)的都会被渲染。思考下面的代码路由嵌套V4的嵌套,和V2V3相当不同V4必须在主件的内部嵌套route例子如下:import React, {Component} from 'react'; import {Route} from 'react-router-dom'; import lazyLoad from '../lazyLoad'; import Index from 'bundle-loader?lazy&name=home!./index'; export default class Login extends Component { render() { return ( <div>测试 <Route path={this.props.match.path + '/index'} render={() => { return lazyLoad(Index, { ...this.props }); }}></Route> </div> ); } }
2018年05月06日
1 阅读
0 评论
0 点赞
2018-05-04
React-eslint
eslint配置npm install --save-dev eslint eslint-plugin-html eslint-plugin-import eslint-plugin-node babel-eslint eslint-plugin-reactmodule.exports = { "parser": "babel-eslint", "plugins": [ "react" ], "parserOptions": { "ecmaVersion": 6, "sourceType": "module", "ecmaFeatures": { "jsx": true } }, "env": { "browser": true, "amd": true, "es6": true, "node": true, "mocha": true }, "rules": { "comma-dangle": 1, "quotes": [0, "single"], "no-undef": 1, "global-strict": 0, "no-extra-semi": 1, "no-underscore-dangle": 0, "no-console": 1, "no-unused-vars": 1, "no-trailing-spaces": [1, { "skipBlankLines": true }], "no-unreachable": 1, "no-alert": 0, "react/jsx-uses-react": 1, "react/jsx-uses-vars": 1, "no-extra-semi": 1, //禁止多余的冒号 "no-implicit-coercion": 1, //禁止隐式转换 "no-multi-spaces": 1, //不能用多余的空格 "no-trailing-spaces": 1, //一行结束后面不要有空格 "no-undef": 1, //不能有未定义的变量 "no-unused-vars": [2, { "vars": "all", "args": "after-used" }], //不能有声明后未被使用的变量或参数 "brace-style": [1, "1tbs"], //大括号风格 "callback-return": 1, //避免多次调用回调什么的 "comma-dangle": [2, "never"], //对象字面量项尾不能有逗号 "indent": [1, 2], //缩进风格 "new-parens": 2, //new时必须加小括号 "max-params": [1, 3], //函数最多只能有3个参数 "new-cap": 2, //函数名首行大写必须使用new方式调用,首行小写必须用不带new方式调用 "quote-props": [0, "always"], //对象字面量中的属性名是否强制双引号 "vars-on-top": 2, //var必须放在作用域顶部 //空行最多不能超过100行 "no-multiple-empty-lines": [2, { "max": 1 }], "semi": [1, "always"] //语句强制分号结尾 } }
2018年05月04日
1 阅读
0 评论
0 点赞
2018-04-24
在已有的Vue项目添加单元测试
1.在相对应的文件夹添加一下3个文件.2.安装对应的依赖npm i -D karma karma-webpack phantomjs-prebuilt karma-phantomjs-launcher karma-phantomjs-shim karma-chrome-launcher karma-sourcemap-loader mocha karma-mocha sinon chai sinon-chai karma-sinon-chai karma-spec-reporter karma-coverage运行npm run unit你会看到一下错误信息{ "message": "Error: [vuex] vuex requires a Promise polyfill in this browser.\nat webpack:///~/vuex/dist/vuex.esm.js:97:19 <- index.js:11802:55", "str": "Error: [vuex] vuex requires a Promise polyfill in this browser.\nat webpack:///~/vuex/dist/vuex.esm.js:97:19 <- index.js:11802:55" } //使用Babel polyfill解决了这个问题。以下是我所做的步骤: //安装Babel Polyfill: npm install --save-dev babel-polyfill //然后包括前内源和测试文件的填充工具文件files的部分karma.conf.js: files: [ '../node_modules/babel-polyfill/dist/polyfill.js', 'index.js' ],注意异步主件在断言时必须保证渲染完成.所以要使用nextTick
2018年04月24日
2 阅读
0 评论
0 点赞
2018-04-18
固定浏览器ULR
vm.$watch('$route', (now) => { window.history.pushState(null, null, window.location.origin);});
2018年04月18日
1 阅读
0 评论
0 点赞
2018-04-18
Vuex全局守卫
全局守卫你可以使用 router.beforeEach 注册一个全局前置守卫:const router = new VueRouter({ ... }) router.beforeEach((to, from, next) => { // ... })每个守卫方法接收三个参数:to: Route: 即将要进入的目标 路由对象from: Route: 当前导航正要离开的路由next: Function: 一定要调用该方法来 resolve 这个钩子。执行效果依赖 next 方法的调用参数。next(): 进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed (确认的)。next(false): 中断当前的导航。如果浏览器的 URL 改变了(可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到 from 路由对应的地址。next('/') 或者 next({ path: '/' }): 跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。你可以向 next 传递任意位置对象,且允许设置诸如 replace: true、name: 'home' 之类的选项以及任何用在 router-link 的 to prop 或 router.push 中的选项。next(error): (2.4.0+) 如果传入 next 的参数是一个 Error 实例,则导航会被终止且该错误会被传递给 router.onError() 注册过的回调。利用router.beforeEach禁止跳转不存在的路由router.beforeEach((to, from, next) => { let routes = router.options.routes; //递归判断是否跳转路由 let jump = (arr, to, from, next) => { for (let v of arr) { if (v.path === to.path) { next(); continue; } else { if (v.children instanceof Array && v.children.length > 0) { jump(v.children, to, from, next); } next(false); } } }; jump(routes, to, from, next); });
2018年04月18日
0 阅读
0 评论
0 点赞
2018-04-17
Vue-router向路由主件传参
通过配置路由的props进行传参如果 props 被设置为 true,route.params 将会被设置为组件属性。const User = { props: ['id'], template: '<div>User {{ id }}</div>' } const router = new VueRouter({ routes: [ { path: '/user/:id', component: User, props: true } ] })如果 props 是一个对象,它会被按原样设置为组件属性。当 props 是静态的时候有用。const router = new VueRouter({ routes: [ { path: '/promotion/from-newsletter', component: Promotion, props: { newsletterPopup: false } } //主件的props:['newsletterPopup'] ] })你可以创建一个函数返回 props。const router = new VueRouter({ routes: [ { path: '/search', component: SearchUser, props: (route) => ({ query: route }) } //主件的props:['query'] ] })
2018年04月17日
0 阅读
0 评论
0 点赞
1
...
9
10
11
...
16