-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Electron项目总结 #23
Comments
Electron调试Redux我们使用electron-devtools-installer 这个插件, electron.app.on('ready', () => {
installExtension(installExtension.VUEJS_DEVTOOLS)
.then(() => {})
.catch(err => {
console.log('Unable to install `vue-devtools`: \n', err)
})
//添加Redux_DevTools
installExtension(installExtension.REDUX_DEVTOOLS)
.then(() => {})
.catch(err => {
console.log('Unable to install `redux-devtools`: \n', err)
})
}) 其中store的js文件中我们需要配置添加composeWithDevTools import { createStore, applyMiddleware } from 'redux';
import { composeWithDevTools } from 'redux-devtools-extension';
import FileManageStore from './test/reducer';
import { combineReducers } from 'redux-immutable';
import thunk from 'redux-thunk';
import Immutable from 'immutable';
let store = createStore(
combineReducers({ FileManageStore }),
Immutable.Map({}),
composeWithDevTools(applyMiddleware(thunk))
);
export default store; |
将immutable.js引入到项目中的改造Redux的本地持久化存储与获取 |
stat属性
|
双击和单击事件绑定到同一个DOM上冲突解决方案类似js截流,200ms之内如果双击则cleartimeOut let timer = 0;
let delay = 200;
let prevent = false;
doClickAction() {
console.log(' click');
}
doDoubleClickAction() {
console.log('Double Click')
}
handleClick() {
let me = this;
timer = setTimeout(function() {
if (!prevent) {
me.doClickAction();
}
prevent = false;
}, delay);
}
handleDoubleClick(){
clearTimeout(timer);
prevent = true;
this.doDoubleClickAction();
}
< button onClick={this.handleClick.bind(this)}
onDoubleClick = {this.handleDoubleClick.bind(this)} > click me </button>
e.target和e.currentTarget区别e.target : 触发事件的元素,谁触发就是谁,用来区分事件委托和冒泡 space-between 实现节点左靠布局chrome浏览器属性-webkit-box-orient 和 css-loader为了防止css-loader编译这个属性,需要这么写 /* autoprefixer: off */
-webkit-box-orient: vertical;
/* autoprefixer: on */ babel编译装饰器babel 6.x
border显示与隐藏切换不影响元素宽高实现方式有三种:
|
Redux中的action异步操作问题:我们在实际的组件拆分中,我们经常会遇到相同的一些业务逻辑,比如aaa触发了,都需要发送ajax请求,我们这里是文件路径保存给redux之前都需要判断路径是否存在,而且判断路径是一个异步操作。在这里我们介绍下Redux-thunk。 //旧的代码
// 选择文件夹路径在边栏
export const setFolderPathActiveInSider = (data) => {
return {
type: actionType.SETFOLDERPATHACTIVEINSIDER,
data
};
} //新的代码
// 选择文件夹路径在边栏
export const setFolderPathActiveInSider = (data) => {
return {
type: actionType.SETFOLDERPATHACTIVEINSIDER,
data
};
}
// 选择文件夹路径在边栏
export const setFolderPathActiveInSiderAsync = (data) => {
return async (dispatch) => {
const exists = await fsExtra.pathExists(data);
if (!exists) {
message.error('路径未找到;该路径已被删除或移动');
return false;
}
dispatch(setFolderPathActiveInSider(data));
return true;
}
} 所以在新的代码中,我们利用dispatch来人为的控制Redux中的action的触发,dispatch我们可以写在异步或者回调函数之中都可以,这样我们就可以利用action做一些统一的处理比如ajax请求等等
|
项目目录引用与别名webpack中的别名配置 resolve: {
alias: {
'@filemanage': path.join(__dirname, '../src/renderer/views/filemanage2')
},
extensions: ['.js', '.jsx', '.vue', '.json', '.css', '.node']
}, //js中的文件路径以及图片路径 import { setFolderPathActiveInSiderAsync } from '@filemanage/store/action';
const CardImage = ({ type, extension }) => {
let imgSrc = require(`@filemanage/assets/icon_file/file.png`);
return (
<img src={imgSrc} alt="File-icon" />
)
} //less中的文件路径 @import "~@filemanage/style/variables.less";
.filemanage-content-option{
padding: 2px 10px;
width: 100%;
height: @filemanageContentOptionHeight;
border-bottom: 1px solid #e8e8e8;
} |
React中的Loading组件
react中实现类似vue中的scoped这里使用css-loader的配置,就可以实现scoped的效果,会将className进行hash处理,相当于vue语法中的scoped;如果不想hash处理就是global化,相当于vue中去掉scoped
React中Mixin的有害性 |
使用asar命令行解压asar文件 --用来解读app文件
|
Electorn中使用better-sqlite3报错错误信息如下:
解决方法:
sqlite3在开发时,会生成.db文件,为了方便我们查看数据,我们使用sqlitebrowser来可视化查看。 |
Electron中获取文件路径在Electron中常用到操作用户的本地路径
在 main process 中通过 electron.app 调用,在renderer process中,通过 remote 模块调用。 Node中的路径处理
|
通过require.context使Reducer模块自动加载
|
Electron平台判断
|
React 16.3以上版本 parent父组件获取循环loop中children子组件的dom结构需求背景:文件管理页面常见的框选需要在容器层面给body绑定mouse事件,同时获取文件card的位置来判断是否在框选范围内。 //渲染子组件Card
getCardList(files) {
let cardList = []
this.cardObjList = []
files.map((file, index) => {
cardList.push(
<Card getRef={elm => ( this.cardObjList.push(elm.getBoundingClientRect()) )} key={index} index={index} file={file} />
)
})
return cardList
}
//父组件
render() {
const { isContentLoading, isShowContextMenu, files } = this.props;
const { selectEle } = this.state;
return (
<div onClick={this.cancelSelectCard}
onMouseDown={this.down}
onMouseMove={this.move}
onMouseUp={this.up}>
{
this.getCardList(files)
}
</div>
);
} //卡片子组件
render() {
const { index, file, connectDragSource } = this.props;
return (
<div
ref={elm => {
connectDragSource(elm)
if (!elm) return;
this.props.getRef(elm);
}}
className={isSelectCard ? "filemanage-content-main-card selected" : "filemanage-content-main-card"}
key={index}
style={{ width: '110px' }}
onClick={(e) => { this.handleClick(e) }}
onDoubleClick={(e) => { this.handleDoubleClick(e, type, path, name, extension) }}>
<div className="card-prew">
<CardImage type={type} extension={extension}></CardImage>
</div>
<div className="card-filename">
{name}
</div>
</div>
);
} 核心代码为子组件中调用父组件的getRef方法并把当前dom传入进去; ref={elm => {
connectDragSource(elm)
if (!elm) return;
this.props.getRef(elm);
}} 父组件中列表清空以及getRef的回调push this.cardObjList = [] //渲染之前列表清空
files.map((file, index) => {
cardList.push(
<Card getRef={elm => ( this.cardObjList.push(elm.getBoundingClientRect()) )} key={index} index={index} file={file} />
) |
技术栈 electron + react + sqlite + immutable + redux
npm包功能总结
<select>
框的混合体。它基于jQuery,具有自动完成功能和本机感觉的键盘导航;用于标记,联系人列表等 //// 使用react-selectThe text was updated successfully, but these errors were encountered: