用Taro做個微信小程序Todo, 小白工作記錄
微信小程序框架: Taro
做微信小程序的框架, 幾個比較主流的:
- 官方的
WePY
: https://tencent.github.io/wepy/document.html#/ - 美團(tuán)的
mpvue
: http://mpvue.com/mpvue/#-html - 京東的
Taro
: https://taro.aotu.io/
前兩者都是Vue風(fēng)格的, Taro是React的.
本篇本著學(xué)習(xí)的目的, 用Taro做一個簡單的小程序.
代碼在這里: https://github.com/mengdd/mini-program-todo
背景:
一直做Android開發(fā), 最近想把其他各種技術(shù)都擼一擼, 拓展一下視野.
之前練過微信小程序原生開發(fā)的例子, 基本上只知道個大概, 翻書馬冬梅, 合書馬什么梅?
所以這次用框架了, 覺得還是要有個輸出, 這樣印象深刻一些.
所以本文是從一個小白的角度, 手把手做練習(xí)的.
Taro程序環(huán)境
這部分參考:
- 官方文檔: https://nervjs.github.io/taro/docs/README.html
- Getting Started:
https://nervjs.github.io/taro/docs/GETTING-STARTED.html
要有node環(huán)境, 推薦用nvm來管理.
需要安裝CLI工具:
npm install -g @tarojs/cli
創(chuàng)建項(xiàng)目并運(yùn)行
創(chuàng)建項(xiàng)目
創(chuàng)建模板項(xiàng)目:
taro init myApp
在這個階段會有一些問題要回答.
* 請輸入項(xiàng)目介紹坡贺! My awesome project blablabla.
* 是否需要使用 TypeScript 慎恒? Yes
* 請選擇 CSS 預(yù)處理器(Sass/Less/Stylus) Sass
* 請選擇模板 默認(rèn)模板
完了之后會自動安裝依賴:
npm install
然后就成功啦!
運(yùn)行
Taro需要運(yùn)行不同的命令, 將Taro代碼編譯成不同端的代碼, 然后在對應(yīng)的開發(fā)工具中查看效果.
這里僅說微信小程序. 還是需要微信開發(fā)者工具:
https://developers.weixin.qq.com/miniprogram/dev/devtools/download.html
import這個項(xiàng)目就行了.
開發(fā)前微信開發(fā)者工具的項(xiàng)目設(shè)置要注意:
需要設(shè)置關(guān)閉ES6轉(zhuǎn)ES5功能, 開啟可能報錯.
需要設(shè)置關(guān)閉上傳代碼時樣式自動補(bǔ)全, 開啟可能報錯.
需要設(shè)置關(guān)閉代碼壓縮上傳, 開啟可能報錯.
這些默認(rèn)都是關(guān)閉的.
微信小程序的編譯預(yù)覽及打包:
npm script
$ npm run dev:weapp
$ npm run build:weapp
或者:
$ taro build --type weapp --watch
$ taro build --type weapp
加上--watch
會監(jiān)聽文件修改, 去掉會對代碼進(jìn)行壓縮打包.
運(yùn)行編譯命令之后就可以在微信開發(fā)者工具中預(yù)覽了. 是顯示一個Hello World.
項(xiàng)目結(jié)構(gòu)
因?yàn)閯?chuàng)建項(xiàng)目的時候用了TypeScript, 所以項(xiàng)目結(jié)構(gòu)是這樣的:
├── dist 編譯結(jié)果目錄
├── config 配置目錄
| ├── dev.js 開發(fā)時配置
| ├── index.js 默認(rèn)配置
| └── prod.js 打包時配置
├── src 源碼目錄
| ├── pages 頁面文件目錄
| | ├── index index頁面目錄
| | | ├── index.scss index頁面樣式
| | | └── index.tsx index頁面邏輯
| ├── app.scss 項(xiàng)目總通用樣式
| ├── app.tsx 項(xiàng)目入口文件
| └── index.html
└── package.json
如果需要創(chuàng)建組件, 可以在src
下創(chuàng)建component
目錄來統(tǒng)一存放組件.
"Hello world!"就在index.tsx
中.
IDE
關(guān)于IDE:
我發(fā)現(xiàn)用微信開發(fā)者工具是打不開這些后綴名為scss
和tsx
的文件的.
微信開發(fā)者工具只能用來預(yù)覽.
后來用了Intellij, 是能查看文件了,
但是開始寫代碼之后, 發(fā)現(xiàn)沒有自動提示, 也沒有自動格式化工具.
又下了個VS CODE:
brew cask install visual-studio-code
格式化的快捷鍵是:
Shift + Alt + F
.
后來我在Text Editor設(shè)置里勾選了Format On Save
.
編寫代碼
Step 1: 靜態(tài)頁面顯示
先弄幾個數(shù)據(jù)靜態(tài)顯示一下:
export default class Index extends Component {
config: Config = {
navigationBarTitleText: '首頁'
}
constructor(props) {
super(props)
this.state = {
list: ['get up', 'eat breakfast', 'study',]
}
inputVal: ''
}
render() {
let { list, inputVal } = this.state
return (
<View className='index'>
<View className='list_wrap'>
<Text>Todo List</Text>
{
list.map((item, index) => {
return <View>
<Text>{index + 1}.{item}</Text>
</View>
})
}
</View>
</View>
)
}
}
然后命令行運(yùn)行:
taro build --type weapp --watch
就會直接顯示出來結(jié)果. 之后的修改也是隨時呈現(xiàn).
這里IDE報告兩個TypeScript的問題:
Property 'list' does not exist on type 'Readonly<{}>'
和:
Property 'inputVal' does not exist on type 'Index'.
按照這里的方法修改的:
interface MyProps {
}
interface MyState {
list: Array<string>;
inputVal: string;
}
export default class Index extends Component<MyProps, MyState> {
//...
}
代碼中設(shè)置值的時候調(diào)用this.setState()
.
Step 2: 添加和刪除項(xiàng)目
加上輸入框, 添加和刪除按鈕的對應(yīng)方法.
完整代碼:
interface MyProps {
}
interface MyState {
list: Array<string>;
inputVal: string;
}
export default class Index extends Component<MyProps, MyState> {
config: Config = {
navigationBarTitleText: '首頁'
}
constructor(props) {
super(props)
this.state = {
list: ['get up', 'eat breakfast', 'study',],
inputVal: ''
}
}
addItem() {
let { list } = this.state
const inputVal = this.state.inputVal
if (inputVal == '') return
else {
list.push(inputVal)
}
this.setState({
list,
inputVal: ''
})
}
removeItem(index) {
let { list } = this.state
list.splice(index, 1)
this.setState({
list
})
}
inputHandler(e) {
this.setState({ inputVal: e.target.value })
}
render() {
let { list, inputVal } = this.state
return (
<View className='index'>
<Input className='input' type='text' value={inputVal} onInput={this.inputHandler.bind(this)} />
<Text className='add' onClick={this.addItem.bind(this)}>添加</Text>
<View className='list_wrap'>
<Text>Todo List</Text>
{
list.map((item, index) => {
return <View className='list_item'>
<Text>{index + 1}.{item}</Text>
<Text className='del' onClick={this.removeItem.bind(this, index)}>刪除</Text>
</View>
})
}
</View>
</View>
)
}
}
Step 3: 樣式調(diào)整
用了這里面的樣式: https://juejin.im/book/5b73a131f265da28065fb1cd
然后企圖調(diào)整button的對齊. (CSS不太擅長, 請輕拍, 請指教.)
.input {
display: inline-block;
margin: 32px;
border: 1px solid #666;
width: 65%;
vertical-align: middle;
}
.list_wrap {
padding: 32px;
}
.list_item {
margin: 20px 0;
}
.add,
.del {
display: inline-block;
width: 120px;
height: 60px;
margin: 0 10px;
padding: 0 10px;
font-size: 22px;
line-height: 60px;
text-align: center;
border-radius: 10px;
box-sizing: border-box;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
justify-content: center;
vertical-align: middle;
}
.add {
background-color: #5c89e4;
color: #fff;
border: 1px solid #5c89e4;
}
.del {
background-color: #fff;
color: #5c89e4;
border: 1px solid #5c89e4;
position: absolute;
right: 32px;
}
Taro命令
快速生成新的頁面文件:
Taro create --name [頁面名稱]