React+Electron桌面應(yīng)用開(kāi)發(fā)文章索引
這篇文章繼續(xù)之前的文章坷虑。比起彈窗,底部彈出的小提示更加頻繁滔灶,這次我們介紹如何創(chuàng)建小提示Snackbar瘦癌。
MaterialUI官方給出了Snackbar實(shí)現(xiàn)案例,也很繁瑣乌叶,小提示本質(zhì)上也是全局性的改化,但與彈窗略有區(qū)別的是,小提示可以同時(shí)出現(xiàn)多個(gè)枉昏。
這次我們還是想辦法把它統(tǒng)一化陈肛。
思路分析
snackbar的功能特征:
和彈窗一樣,包含內(nèi)容區(qū)(純文字兄裂,或文字+按鈕)和一個(gè)關(guān)閉按鈕
snackbar并不打斷用戶操作句旱,大多時(shí)候會(huì)幾秒后自動(dòng)消失
所以可能有多個(gè)snackbar同時(shí)出現(xiàn)
snackbar看上去也是全局性的功能阳藻,但實(shí)際應(yīng)該是多個(gè)元素
在任意頁(yè)面都可以創(chuàng)建snackbar
snackbar都應(yīng)該放在App的某個(gè)容器里面統(tǒng)一接管,添加或移除
我們需要一個(gè)快速創(chuàng)建snackbar的全局功能global.$addSnackbar(state)
編寫(xiě)代碼
創(chuàng)建Utitlies/MySnackbar.js。
實(shí)現(xiàn)思路是:
創(chuàng)建一個(gè)snackbars局部變量谈撒,用來(lái)存放所有實(shí)例腥泥,這樣就可以跨越執(zhí)行實(shí)例.setState({open:false})方法關(guān)閉snackbar。(參考xset的實(shí)現(xiàn)思路)
實(shí)現(xiàn)全局化的global.$closeMySnackBar通過(guò)id關(guān)閉特定snackbar方法
創(chuàng)建一個(gè)MySnackbar類啃匿,constructor構(gòu)建函數(shù)里面把每個(gè)實(shí)例通過(guò)id添加到snackbars蛔外,以后就能使用snackbars[id]來(lái)獲取
MySnackbar類中render()通過(guò)style實(shí)現(xiàn)了snackbar的堆疊效果,通過(guò)覆蓋onClose關(guān)閉方法實(shí)現(xiàn)autoHideDuration倒計(jì)時(shí)結(jié)束自動(dòng)關(guān)閉
MySnackbars類是所有snackbar界面dom的容器溯乒,全局化了global.$addMySnackbar方法用來(lái)添加新的snackbar
id這個(gè)參數(shù)專門用來(lái)配合snackbars變量管理和獲取創(chuàng)建的MySnackbar實(shí)例
/*
被加載時(shí)候componentDidMount添加全局方法:
$addSnackbar(state,id)夹厌,state格式請(qǐng)參照官方API說(shuō)明,必須通過(guò)id才能自定義關(guān)閉snackbar的按鈕
$closeMySnackBar(id),關(guān)閉特定的snackbar
*/
import React from 'react'
import h from 'react-hyperscript'
import deepmerge from 'deepmerge'
import Button from 'material-ui/Button'
import Snackbar from 'material-ui/Snackbar'
let snackbars = {} //全部snackbar實(shí)例列表裆悄,關(guān)閉snackbar時(shí)候使用
//輸出關(guān)閉特定snackbar的全局方法
global.$closeMySnackBar = (id) => {
if (snackbars[id]) {
snackbars[id].setState({
open: false
})
}
}
/*
自動(dòng)接收snackbar管理的類
能夠自動(dòng)計(jì)時(shí)關(guān)閉
*/
class MySnackbar extends React.Component {
constructor(props) {
super(props)
this.state = {
open: true
}
}
componentDidMount() {
if (this.props.id) {
snackbars[this.props.id] = this
}
}
render() {
let props = deepmerge(this.props, {
open: this.state.open,
style: {
display: 'block',
position: 'relative',
height: 56,
},
onClose: (event, reason) => {
this.props.onClose && this.props.onClose()
if (reason !== 'clickaway') this.setState({
open: false
})
},
})
return h(Snackbar, props)
}
}
//App中所有snackbar的容器管理
class MySnackbars extends React.Component {
constructor(props) {
super(props)
this.state = {
list: []
}
}
add(state, id) {
console.log('xx', id)
let newOne = h(MySnackbar, deepmerge(state, {
open: true,
id: id //關(guān)閉snackbar時(shí)候使用
}))
this.state.list.push(newOne)
this.setState({
list: this.state.list
})
}
componentDidMount() {
let that = this;
global.$addMySnackbar = (state, id) => {
that.add(state, id)
}
}
render() {
//嵌套兩層div把所有snackbar固定在底部中間
return h('div', {
style: {
bottom: 8,
position: 'fixed',
textAlign: 'center',
width: '100%'
}
}, [
h('div', {
style: {
display: 'inline-block',
}
}, this.state.list)
])
}
}
export default MySnackbars
使用MySnackbars
首先我們還是在App.js中引入import MySnackbar from '../Utilities/MySnackbars'
,并在render()中創(chuàng)建放置snackbars的容器
render() {
let that = this
const css = this.props.classes
return h(MuiThemeProvider, {
theme: Theme,
}, h(Grid, {
container: false,
className: css.app,
}, [
h(Pages[this.state.currentPageName]),
h(MyDialog),
h(MySnackbar),
]))
}
然后我們就可以在其他頁(yè)面中使用了矛纹,比如:
h(Button, {
onClick: () => {
let id = Math.random()
global.$addMySnackbar({
anchorOrigin: {
vertical: 'bottom',
horizontal: 'center',
},
autoHideDuration: 3000,
onClose: () => {
console.log('Home Page said:', that.state.title)
},
message: 'Hello from MySnackbar!',
action: [
h(Button, {
key: 'any',//必須要有這個(gè),值任意
color: 'secondary',
onClick: () => {
global.$closeMySnackBar(id)
console.log('Home Page said:', that.state.title)
}
}, '關(guān)閉')
],
}, id)
}
}, 'add snackbar'),
這生成一個(gè)按鈕
點(diǎn)擊它彈出
多次點(diǎn)擊彈出多個(gè)
點(diǎn)擊紫色按鈕可以關(guān)閉某個(gè)snackbar光稼,或者超過(guò)3秒鐘自動(dòng)消失
致力于讓一切變得簡(jiǎn)單
如果您發(fā)現(xiàn)文章錯(cuò)誤或南,請(qǐng)不吝留言指正;
如果您覺(jué)得有用艾君,請(qǐng)點(diǎn)喜歡采够;
如果您覺(jué)得很有用,歡迎轉(zhuǎn)載~
END