小程序開發(fā)之wepy


title: 小程序教程之wepy

參考文檔
  1. 中文文檔:https://tencent.github.io/wepy/document.html#/?id=app%e5%b0%8f%e7%a8%8b%e5%ba%8f%e5%ae%9e%e4%be%8b
  2. github:https://github.com/Tencent/wepy
  3. 微信小程序開發(fā)資源導(dǎo)航:http://www.yimijili.com/xcxwzdh.html
  4. over
VSCode自動(dòng)補(bǔ)齊Vue語法

打卡VScode、首選項(xiàng) 、設(shè)置,或者直接Comand+,快捷鍵

補(bǔ)全的語法為類Vue語法

用戶設(shè)置一欄中改成:

// {
//     "window.zoomLevel": 0,
//     "editor.fontSize": 16,
//     "files.associations": {
//         "*.wpy": "vue",
//         "*.wxss": "css",
//         "*.wxml": "html"
//     }
// }

// Place your settings in this file to overwrite the default settings
{

// 配置 glob 模式以排除文件和文件夾。
"files.exclude": {
  "**/.git": true,
  "**/.svn": true,
  "**/.hg": true,
  "**/CVS": true,
  "**/.DS_Store": true,
  // "**/node_modules": true,
  "**/bower_components": true
  // "**/dist": true
},
// 配置語言的文件關(guān)聯(lián)(如: "*.extension": "html")。這些關(guān)聯(lián)的優(yōu)先級(jí)高于已安裝語言的默認(rèn)關(guān)聯(lián)。
"files.associations": {
  "*.vue": "vue",
  "*.wpy": "vue",
  "*.wxss": "postcss",
  "*.tpl": "vue",
  "*.md@xxx": "markdown",
  "*.wepy": "vue"
},
// 一個(gè)制表符等于的空格數(shù)。該設(shè)置在 `editor.detectIndentation` 啟用時(shí)根據(jù)文件內(nèi)容進(jìn)行重寫。
"editor.tabSize": 2,
// 當(dāng)打開文件時(shí),將基于文件內(nèi)容檢測(cè) "editor.tabSize" 和 "editor.insertSpaces"。
"editor.detectIndentation": false,
"window.zoomLevel": 1,
"editor.wordWrap": "on",
"workbench.iconTheme": "vs-seti",
"editor.wordSeparators": "`~!@#$%^&*()=+[{]}\\|;:'\",.<>/?。",
"editor.minimap.enabled": true,
// 控制鍵入時(shí)是否應(yīng)自動(dòng)顯示建議
"editor.quickSuggestions": {
  "other": true,
  "comments": true,
  "strings": true
},
// 配置 glob 模式以在搜索中排除文件和文件夾。從 files.exclude 設(shè)置中繼承所有 glob 模式。
"search.exclude": {
  "**/node_modules": true,
  "**/bower_components": true,
  "**/dist": true
},
// 控制編輯器是否應(yīng)呈現(xiàn)縮進(jìn)參考線
"editor.renderIndentGuides": true,
"emmet.syntaxProfiles": {
  "vue-html": "html",
  "vue": "html"
},

// 配置內(nèi)置 HTML 語言支持是否建議 Angular V1 標(biāo)記和屬性。
"html.suggest.angular1": false,
// 自動(dòng)更新擴(kuò)展
"extensions.autoUpdate": true,
// 對(duì)屬性進(jìn)行換行。
"html.format.wrapAttributes": "auto",
// Link file types to the beautifier type
"beautify.language": {
  "js": {
    "type": [
      "javascript",
      "json"
    ],
    "filename": [
      ".jshintrc",
      ".jsbeautify",
      ".eslintrc.js"
    ]
  },
  "css": [
    "css",
    "scss"
  ],
  "html": [
    "htm",
    "html"
  ]
},
"git.enabled": false,
"editor.renderControlCharacters": true,
"typescript.check.npmIsInstalled": false,
"extensions.ignoreRecommendations": false,
// 覆蓋當(dāng)前所選顏色主題的顏色。 此為實(shí)驗(yàn)性設(shè)置,因?yàn)橄乱话姹局袑⒏念伾Q。
// "workbench.experimental.colorCustomizations": {
//   "statusBarBackground": "#666666",
//   "panelBackground": "#555555",
//   "sideBarBackground": "#444444"
// }
// When enabled, emmet abbreviations are expanded when pressing TAB.
"emmet.triggerExpansionOnTab": true,
"workbench.panel.location": "bottom",
  "editor.fontSize": 16
}

over

快速入門
  1. 初始化項(xiàng)目

    1.全局安裝或者更新wepy命令行工具
    $ npm install wepy-cli -g
    
    2.在開發(fā)目錄中生成Demo開發(fā)項(xiàng)目
    wepy new myproject
    # 1.7.0之后的版本使用 wepy init standard myproject 初始化項(xiàng)目,使用 wepy list 查看項(xiàng)目模板
    
    3.編譯
    $ cd project
    $ npm install 
    $ wepy build --watch 或者
    $ npm run dev
    
  2. 項(xiàng)目目錄

    ├── dist                   微信開發(fā)者工具指定的目錄(該目錄由WePY的build指令自動(dòng)編譯生成,請(qǐng)不要直接修改該目錄下的文件)
    ├── node_modules           
    ├── src                    代碼編寫的目錄(該目錄為使用WePY后的開發(fā)目錄)
    |   ├── components         WePY組件目錄(組件不屬于完整頁面,僅供完整頁面或其他組件引用)
    |   |   ├── com_a.wpy      可復(fù)用的WePY組件a
    |   |   └── com_b.wpy      可復(fù)用的WePY組件b
    |   ├── pages              WePY頁面目錄(屬于完整頁面)
    |   |   ├── index.wpy      index頁面(經(jīng)build后,會(huì)在dist目錄下的pages目錄生成index.js、index.json、index.wxml和index.wxss文件)
    |   |   └── other.wpy      other頁面(經(jīng)build后,會(huì)在dist目錄下的pages目錄生成other.js、other.json、other.wxml和other.wxss文件)
    |   └── app.wpy            小程序配置項(xiàng)(全局?jǐn)?shù)據(jù)、樣式、聲明鉤子等;經(jīng)build后,會(huì)在dist目錄下生成app.js、app.json和app.wxss文件)
    └── package.json           項(xiàng)目的package配置
    
  3. 重要提醒

    1. 微信開發(fā)者工具添加dist目錄
    2. 微信開發(fā)者工具關(guān)閉ES6轉(zhuǎn)ES5
    3. 運(yùn)行 wepy build --watch 實(shí)時(shí)編譯
    。。。
    
  4. 代碼高亮和代碼規(guī)范

  5. over

主要功能特性
  1. 開發(fā)模式轉(zhuǎn)換

    原生代碼
    //index.js
    
    //獲取應(yīng)用實(shí)例
    var app = getApp()
    
    //通過Page構(gòu)造函數(shù)創(chuàng)建頁面邏輯
    Page({
        //可用于頁面模板綁定的數(shù)據(jù)
        data: {
            motto: 'Hello World',
            userInfo: {}
        },
    
        //事件處理函數(shù)
        bindViewTap: function() {
            console.log('button clicked')
        },
    
        //頁面的生命周期函數(shù)
        onLoad: function () {
            console.log('onLoad')
        }
    

    基于wepy的代碼

    //index.wpy中的<script>部分
    
    import wepy from 'wepy';
    
    //通過繼承自wepy.page的類創(chuàng)建頁面邏輯
    export default class Index extends wepy.page {
        //可用于頁面模板綁定的數(shù)據(jù)
        data = {
            motto: 'Hello World',
            userInfo: {}
        };
    
        //事件處理函數(shù)(集中保存在methods對(duì)象中)
        methods = {
            bindViewTap () {
                console.log('button clicked');
            }
        };
    
        //頁面的生命周期函數(shù)
        onLoad() {
            console.log('onLoad');
        };
    }
    
  2. 支持組件式開發(fā)

    // index.wpy
    
    <template>
        <view>
            <panel>
                <h1 slot="title"></h1>
            </panel>
            <counter1 :num="myNum"></counter1>
            <counter2 :num.sync="syncNum"></counter2>
            <list :item="items"></list>
        </view>
    </template>
    
    <script>
    import wepy from 'wepy';
    //引入List、Panel和Counter組件
    import List from '../components/list';
    import Panel from '../components/panel';
    import Counter from '../components/counter';
    
    export default class Index extends wepy.page {
        //頁面配置
        config = {
            "navigationBarTitleText": "test"
        };
    
        //聲明頁面中將要使用到的組件
        components = {
            panel: Panel,
            counter1: Counter,
            counter2: Counter,
            list: List
        };
    
        //可用于頁面模板中綁定的數(shù)據(jù)
        data = {
            myNum: 50,
            syncNum: 100,
            items: [1, 2, 3, 4]
        }
    }
    </script>
    

    ?

  3. 支持加載外部npm包

  4. 單文件模式,目錄結(jié)構(gòu)更加清晰,開發(fā)方便

  5. WePY中則使用了單文件模式,將原生小程序app實(shí)例的3個(gè)文件統(tǒng)一為app.wpy,page頁面的4個(gè)文件統(tǒng)一為page.wpy

  6. 默認(rèn)babel編譯,支持ES7新特性

  7. 針對(duì)原生API進(jìn)行優(yōu)化,如wx.request的并發(fā)問題等。

  8. over

進(jìn)階介紹
  1. wepy.config.js配置文件

    執(zhí)行wepy new demo 后,會(huì)生成類似下面的配置文件

    let prod = process.env.NODE_ENV === 'production';
    module.exports = {
        'output': 'dist',
        'source': 'src',
        'wpyExt': '.wpy',
        'compilers': {
            less: {
                'compress': true
            },
            /*sass: {
                'outputStyle': 'compressed'
            },*/
            babel: {
                'presets': [
                    'es2015',
                    'stage-1'
                ],
                'plugins': [
                    'transform-export-extensions',
                    'syntax-export-extensions',
                    'transform-runtime'
                ]
            }
        },
        'plugins': {
        }
    };
    
    if (prod) {
        // 壓縮sass
        module.exports.compilers['sass'] = {'outputStyle': 'compressed'};
    
        // 壓縮less
        module.exports.compilers['less'] = {'compress': true};
    
        // 壓縮js
        module.exports.plugins = {
            'uglifyjs': {
                filter: /\.js$/,
                config: {
                }
            },
            'imagemin': {
                filter: /\.(jpg|png|jpeg)$/,
                config: {
                    'jpg': {
                        quality: 80
                    },
                    'png': {
                        quality: 80
                    }
                }
            }
        };
    }
    
    wpyExt: 默認(rèn)值為.wpy
    compilers: sass\less\stylus\babel\typscript
    plugins
    
    

    ?

  2. .wepy文件說明

    .wepy 文件編譯過程:

    圖片

    .wpy文件分為三個(gè)部分

    • 腳本部分,即<script></script>標(biāo)簽中的內(nèi)容,又可分為兩個(gè)部分:

    邏輯部分,除了config對(duì)象之外的部分,對(duì)應(yīng)于原生的.js文件;

    配置部分,即config對(duì)象,對(duì)應(yīng)于原生的.json文件。

    • 結(jié)構(gòu)部分,即<template></template>模板部分,對(duì)應(yīng)于原生的.wxml文件。
  • 樣式部分,即<style></style>樣式部分,對(duì)應(yīng)于原生的.wxss文件。

  • .wpy文件中的scripttemplatestyle這三個(gè)標(biāo)簽都支持langsrc屬性,lang決定了其代碼編譯過程,src決定是否外聯(lián)代碼,存在src屬性且有效時(shí),會(huì)忽略內(nèi)聯(lián)代碼。

  • 各標(biāo)簽對(duì)應(yīng)的lang值如下表所示:

    標(biāo)簽 lang默認(rèn)值 lang支持值
    style css csslessscssstylus
    template wxml wxmlxmlpug(原jade)
    script babel babelTypeScript
  1. over

  2. over

腳本部分介紹
  1. 小程序入口app.wpy

    <script>
    import wepy from 'wepy';
    export default class extends wepy.app {
        config = {
            "pages":[
                "pages/index/index"
            ],
            "window":{
                "backgroundTextStyle": "light",
                "navigationBarBackgroundColor": "#fff",
                "navigationBarTitleText": "WeChat",
                "navigationBarTextStyle": "black"
            }
        };
        onLaunch() {
            console.log(this);
        }
    }
    </script>
    
    <style lang="less">
    /** less **/
    </style>
    入口文件app.wpy中所聲明的小程序?qū)嵗^承自wepy.app類,包含一個(gè)config屬性和其它全局屬性、方法、事件。其中config屬性對(duì)應(yīng)原生的app.json文件,build編譯時(shí)會(huì)根據(jù)config屬性自動(dòng)生成app.json文件,如果需要修改config中的內(nèi)容,請(qǐng)使用微信提供的相關(guān)API。
    
  2. 頁面page.wpy

    <script>
    import wepy from 'wepy';
    import Counter from '../components/counter';
    
    export default class Page extends wepy.page {
        config = {};
        components = {counter1: Counter};
    
        data = {};
        methods = {};
    
        events = {};
        onLoad() {};
        // Other properties
    }
    </script>
    
    <template lang="wxml">
        <view>
        </view>
        <counter1></counter1>
    </template>
    
    <style lang="less">
    /** less **/
    </style>
    
    屬性 說明
    config 頁面配置對(duì)象,對(duì)應(yīng)于原生的page.json文件,類似于app.wpy中的config
    components 頁面組件列表對(duì)象,聲明頁面所引入的組件列表
    data 頁面渲染數(shù)據(jù)對(duì)象,存放可用于頁面模板綁定的渲染數(shù)據(jù)
    methods wxml事件處理函數(shù)對(duì)象,存放響應(yīng)wxml中所捕獲到的事件的函數(shù),如bindtapbindchange
    events WePY組件事件處理函數(shù)對(duì)象,存放響應(yīng)組件之間通過$broadcast$emit$invoke所傳遞的事件的函數(shù)
    其它 小程序頁面生命周期函數(shù),如onLoadonReady等,以及其它自定義的方法與屬性
  3. 組件com.wpy

    <template lang="wxml">
        <view>  </view>
    </template>
    
    <script>
    import wepy from 'wepy';
    export default class Com extends wepy.component {
        components = {};
    
        data = {};
        methods = {};
    
        events = {};
        // Other properties
    }
    </script>
    
    <style lang="less">
    /** less **/
    </style>
    組件文件com.wpy中所聲明的組件實(shí)例繼承自wepy.component類,除了不需要config配置以及頁面特有的一些生命周期函數(shù)之外,其屬性與頁面屬性大致相同。
    
  4. over

實(shí)例
  1. 實(shí)例

    wepy中,小程序被分為三個(gè)實(shí)例:

    import wepy from 'wepy';
    
    // 聲明一個(gè)App小程序?qū)嵗?export default class MyAPP extends wepy.app {
    }
    
    // 聲明一個(gè)Page頁面實(shí)例
    export default class IndexPage extends wepy.page {
    }
    
    // 聲明一個(gè)Component組件實(shí)例
    export default class MyComponent extends wepy.component {
    }
    
  2. App小程序?qū)嵗?/p>

    在Page頁面實(shí)例中,可以通過this.$parent來訪問App實(shí)例。

  3. Page頁面實(shí)例和Component組件實(shí)例

    Page實(shí)際上繼承自Component組件,即Page也是組建。

    import wepy from 'wepy';
    
    // export default class MyPage extends wepy.page {
    export default class MyComponent extends wepy.component {
        customData = {}  // 自定義數(shù)據(jù)
    
        customFunction () {}  //自定義方法
    
        onLoad () {}  // 在Page和Component共用的生命周期函數(shù)
    
        onShow () {}  // 只在Page中存在的頁面生命周期函數(shù)
    
        config = {};  // 只在Page實(shí)例中存在的配置數(shù)據(jù),對(duì)應(yīng)于原生的page.json文件
    
        data = {};  // 頁面所需數(shù)據(jù)均需在這里聲明,可用于模板數(shù)據(jù)綁定
    
        components = {};  // 聲明頁面中所引用的組件,或聲明組件中所引用的子組件
    
        mixins = [];  // 聲明頁面所引用的Mixin實(shí)例
    
        computed = {};  // 聲明計(jì)算屬性(詳見后文介紹)
    
        watch = {};  // 聲明數(shù)據(jù)watcher(詳見后文介紹)
    
        methods = {};  // 聲明頁面wxml中標(biāo)簽的事件處理函數(shù)。注意,此處只用于聲明頁面wxml中標(biāo)簽的bind、catch事件,自定義方法需以自定義方法的方式聲明
    
        events = {};  // 聲明組件之間的事件處理函數(shù)
    }
    
    WePY中的methods屬性只能聲明頁面wxml標(biāo)簽的bind、catch事件,不能聲明自定義方法,這與Vue中的用法是不一致的
    

    ?

  4. ?

組件
  1. WePY中實(shí)現(xiàn)了小程序的組件化開發(fā),組件的所有業(yè)務(wù)與功能在組件本身實(shí)現(xiàn),組件與組件之間彼此隔離

  2. 普通組件引用

    當(dāng)頁面需要引入子組件時(shí),

    必須 在.wpy文件的<script>腳本部分先import組件文件;

    然后 在components對(duì)象中給組件聲明唯一的組件ID;

    接著在<template>模板部分中添加以components對(duì)象中所聲明的組件ID進(jìn)行命名的自定義標(biāo)簽以插入組件;

    如下:

    /**
    project
    └── src
        ├── components
        |   └── child.wpy
        ├── pages
        |   ├── index.wpy    index 頁面配置、結(jié)構(gòu)、樣式、邏輯
        |   └── log.wpy      log 頁面配置、結(jié)構(gòu)、樣式、邏輯
        └──app.wpy           小程序配置項(xiàng)(全局公共配置、公共樣式、聲明鉤子等)
    **/
    
    // index.wpy
    
    <template>
        <!-- 以`<script>`腳本部分中所聲明的組件ID為名命名自定義標(biāo)簽,從而在`<template>`模板部分中插入組件 -->
        <child></child>
    </template>
    
    <script>
        import wepy from 'wepy';
        //引入組件文件
        import Child from '../components/child';
    
        export default class Index extends wepy.component {
            //聲明組件,分配組件id為child
            components = {
                child: Child
            };
        }
    </script>
    
  3. 組件的循環(huán)渲染

    當(dāng)需要循環(huán)渲染W(wǎng)ePY組件時(shí)(類似于通過wx:for循環(huán)渲染原生的wxml標(biāo)簽),必須使用WePY定義的輔助標(biāo)簽<repeat>

    
    // index.wpy
    
    <template>
        <!-- 注意,使用for屬性,而不是使用wx:for屬性 -->
        <repeat for="{{list}}" key="index" index="index" item="item">
            <!-- 插入<script>腳本部分所聲明的child組件,同時(shí)傳入item -->
            <child :item="item"></child>
        </repeat>
    </template>
    
    <script>
        import wepy from 'wepy';
        // 引入child組件文件
        import Child from '../components/child';
    
        export default class Index extends wepy.component {
            components = {
                // 聲明頁面中要使用到的Child組件的ID為child
                child: Child
            }
    
            data = {
                list: [{id: 1, title: 'title1'}, {id: 2, title: 'title2'}]
            }
        }
    </script>
    
  4. computed計(jì)算屬性

    computed計(jì)算屬性,是一個(gè)有返回值的函數(shù),可直接被當(dāng)做綁定數(shù)據(jù)來使用。需要注意的是,只要是組件中有任何數(shù)據(jù)發(fā)生了改變,那么所有計(jì)算屬性就都會(huì)被重新計(jì)算

    data = {
          a: 1
      }
    
      // 計(jì)算屬性aPlus,在腳本中可通過this.aPlus來引用,在模板中可通過{{ aPlus }}來插值
      computed = {
          aPlus () {
              return this.a + 1
          }
      }
    
  5. watcher監(jiān)聽器

    通過監(jiān)聽器watcher能夠監(jiān)聽到任何屬性的更新。監(jiān)聽器在watch對(duì)象中聲明,類型為函數(shù),函數(shù)名與需要被監(jiān)聽的data對(duì)象中的屬性同名,每當(dāng)被監(jiān)聽的屬性改變一次,監(jiān)聽器函數(shù)就會(huì)被自動(dòng)調(diào)用執(zhí)行一次

    data = {
          num: 1
      }
    
      // 監(jiān)聽器函數(shù)名必須跟需要被監(jiān)聽的data對(duì)象中的屬性num同名,
      // 其參數(shù)中的newValue為屬性改變后的新值,oldValue為改變前的舊值
      watch = {
          num (newValue, oldValue) {
              console.log(`num value: ${oldValue} -> ${newValue}`)
          }
      }
    
      // 每當(dāng)被監(jiān)聽的屬性num改變一次,對(duì)應(yīng)的同名監(jiān)聽器函數(shù)num()就被自動(dòng)調(diào)用執(zhí)行一次
      onLoad () {
          setInterval(() => {
              this.num++;
              this.$apply();
          }, 1000)
      }
    
  6. props傳值

    傳值包括三種:父組件向子組件傳值,子組件向父組件傳值,雙向傳值

    props傳值在WePY中屬于父子組件之間傳值的一種機(jī)制,包括靜態(tài)傳值與動(dòng)態(tài)傳值。

    <child title="mytitle"></child>
    
    // child.wpy
    props = {
        title: String
    };
    
    onLoad () {
        console.log(this.title); // mytitle
    }
    

    動(dòng)態(tài)傳值,雙向綁定

    動(dòng)態(tài)傳值是指父組件向子組件傳遞動(dòng)態(tài)數(shù)據(jù)內(nèi)容,父子組件數(shù)據(jù)完全獨(dú)立互不干擾。但可以通過使用.sync修飾符來達(dá)到父組件數(shù)據(jù)綁定至子組件的效果,也可以通過設(shè)置子組件props的twoWay: true來達(dá)到子組件數(shù)據(jù)綁定至父組件的效果。那如果既使用.sync修飾符,同時(shí)子組件props中添加的twoWay: true時(shí),就可以實(shí)現(xiàn)數(shù)據(jù)的雙向綁定了。

    // parent.wpy
    
    <child :title="parentTitle" :syncTitle.sync="parentTitle" :twoWayTitle="parentTitle"></child>
    
    data = {
        parentTitle: 'p-title'
    };
    

// child.wpy

props = {
// 靜態(tài)傳值
title: String,

   // 父向子單向動(dòng)態(tài)傳值
   syncTitle: {
       type: String,
       default: 'null'
   },

   twoWayTitle: {
       type: Number,
       default: 'nothing',
       twoWay: true
   }

};

onLoad () {
console.log(this.title); // p-title
console.log(this.syncTitle); // p-title
console.log(this.twoWayTitle); // p-title

   this.title = 'c-title';
   console.log(this.$parent.parentTitle); // p-title.
   this.twoWayTitle = 'two-way-title';
   this.$apply();
   console.log(this.$parent.parentTitle); // two-way-title.  --- twoWay為true時(shí),子組件props中的屬性值改變時(shí),會(huì)同時(shí)改變父組件對(duì)應(yīng)的值
   this.$parent.parentTitle = 'p-title-changed';
   this.$parent.$apply();
   console.log(this.title); // 'c-title';
   console.log(this.syncTitle); // 'p-title-changed' --- 有.sync修飾符的props屬性值,當(dāng)在父組件中改變時(shí),會(huì)同時(shí)改變子組件對(duì)應(yīng)的值。

}


?

7. 組件通信與交互

`wepy.component`基類提供`$broadcast`、`$emit`、`$invoke`三個(gè)方法用于組件之間的通信和交互,如:

```js
this.$emit('some-event', 1, 2, 3, 4);

用于監(jiān)聽組件之間的通信與交互事件的事件處理函數(shù)需要寫在組件和頁面的events對(duì)象中,如:

import wepy from 'wepy'

export default class Com extends wepy.component {
    components = {};

    data = {};

    methods = {};

    // events對(duì)象中所聲明的函數(shù)為用于監(jiān)聽組件之間的通信與交互事件的事件處理函數(shù)
    events = {
        'some-event': (p1, p2, p3, $event) => {
               console.log(`${this.$name} receive ${$event.name} from ${$event.source.$name}`);
        }
    };
    // Other properties
}

$broadcast 廣播

$emit 出發(fā)

$invoke 直接調(diào)用

?

  1. 組件自定義事件處理函數(shù)

    可以通過使用.user修飾符為自定義組件綁定事件,如:@customEvent.user="myFn" 其中,@表示事件修飾符,customEvent 表示事件名稱,.user表示事件后綴。

    目前總共有三種事件后綴:

    • .default: 綁定小程序冒泡型事件,如bindtap.default后綴可省略不寫;
    • .stop: 綁定小程序捕獲型事件,如catchtap
    • .user: 綁定用戶自定義組件事件,通過$emit觸發(fā)。注意,如果用了自定義事件,則events中對(duì)應(yīng)的監(jiān)聽函數(shù)不會(huì)再執(zhí)行。
    // index.wpy
    
    <template>
        <child @childFn.user="parentFn"></child>
    </template>
    
    <script>
        import wepy from 'wepy'
        import Child from '../components/child'
    
        export default class Index extends wepy.page {
            components = {
                child: Child
            }
    
            methods = {
                parentFn (num, evt) {
                    console.log('parent received emit event, number is: ' + num)
                }
            }
        }
    </script>
    // child.wpy
    
    <template>
        <view @tap="tap">Click me</view>
    </template>
    
    <script>
        import wepy from 'wepy'
    
        export default class Child extends wepy.component {
            methods = {
                tap () {
                    console.log('child is clicked')
                    this.$emit('childFn', 100)
                }
            }
        }
    </script>
    

    ?

  2. slot組件內(nèi)容分發(fā)插槽

    相當(dāng)于占位符

    在Panel組件中有以下模板
    <view class="panel">
        <slot name="title">默認(rèn)標(biāo)題</slot>
        <slot name="content">默認(rèn)內(nèi)容</slot>
    </view>
    在父組件中使用Pannel子組件時(shí),可以這樣使用:
    <panel>
        <view slot="title">新的標(biāo)題</view>
        <view slot="content">
            <text>新的內(nèi)容</text>
        </view>
    </panel>
    

    ?

  3. over

第三方組件

WePY允許使用基于WePY開發(fā)的第三方組件,開發(fā)第三方組件規(guī)范請(qǐng)參考wepy-com-toast

Mixin混合

混合可以將組之間的可復(fù)用部分抽離,從而在組件中使用混合時(shí),可以將混合的數(shù)據(jù),事件以及方法注入到組件之中。混合分分為兩種:

  • 默認(rèn)式混合
  • 兼容式混合
  1. 默認(rèn)式混合
  2. 兼容式混合
WXS
interceptor攔截器

over

數(shù)據(jù)綁定
  1. 原生小程序數(shù)據(jù)綁定方式

    this.setData({title: 'this is title'});
    
  2. wepy數(shù)據(jù)綁定方式

    WePY使用臟數(shù)據(jù)檢查對(duì)setData進(jìn)行封裝,在函數(shù)運(yùn)行周期結(jié)束時(shí)執(zhí)行臟數(shù)據(jù)檢查,一來可以不用關(guān)心頁面多次setData是否會(huì)有性能上的問題,二來可以更加簡潔去修改數(shù)據(jù)實(shí)現(xiàn)綁定,不用重復(fù)去寫setData方法

    this.title = 'this is title';
    

    需注意的是,在異步函數(shù)中更新數(shù)據(jù)的時(shí),必須手動(dòng)調(diào)用$apply方法,才會(huì)觸發(fā)臟數(shù)據(jù)檢查流程的運(yùn)行

    setTimeout(() => {
        this.title = 'this is title';
        this.$apply();
    }, 3000);
    

    ?

  3. wepy臟數(shù)據(jù)檢查流程

    ?

  4. over

其他優(yōu)化細(xì)節(jié)
  1. wx.request 接受參數(shù)修改
  2. 優(yōu)化事件參數(shù)傳遞
  3. 改變數(shù)據(jù)綁定方式
  4. 組件地帶模板和模塊

實(shí)戰(zhàn)開發(fā)

文件結(jié)構(gòu)
  1. src/components/config 文件夾結(jié)構(gòu)

    api.js 存放借口給
    config.js存放全局、服務(wù)器地址等常量
    utils.js 存放 toast、網(wǎng)絡(luò)請(qǐng)求等方法
    
  2. src/pages/diary文件夾結(jié)構(gòu)

暫無


  1. 微信開發(fā)者工具自定義編譯

    0.查看Network列表(在Console旁邊),該列表為當(dāng)前頁面所有接口,查看info發(fā)現(xiàn),Response返回值
    1.打開微信開發(fā)者工具
    2.在上方編譯處選擇 添加編譯模式
    3.自定義編譯條件
    模式名稱:便于記錄 日記詳情頁
    啟動(dòng)頁面:打開相應(yīng)頁面,會(huì)自動(dòng)生成 pages/diary/DiaryInfo
    啟動(dòng)參數(shù) catDiaryId=1513
    進(jìn)入場(chǎng)景 
    
  2. 頁面導(dǎo)航

  3. over

開發(fā)流程
  1. 熟悉目錄結(jié)構(gòu)
  2. 熟悉服務(wù)端接口流程
  3. 先開發(fā)網(wǎng)絡(luò)請(qǐng)求
  4. 構(gòu)造數(shù)據(jù)
  5. 拆解sketch原型,開始template頁面開發(fā)
布局

參考文獻(xiàn):http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html

  1. 盒子模型
  2. Flex布局

wepy API
  1. wepy.app Class

    $wxapp:Object: this.$wxapp等同于getApp()。
    
    $pages:List<Page>: 所有頁面列表
    
    $interceptors:List<Object>:所有攔截器列表
    
    use(middleWare:String|Function):使用中間件。
    
    
  2. wepy.component Class

    屬性
    
    $name:String: 組件名稱。
    $isComponent:Boolean:是否是組件,如果是頁面,此值為false。
    $wxpage:Object: 小程序原生page。
    $parent:Page|App:組件的父組件,如果當(dāng)前是組件是Page對(duì)象,那么$parent的值為App對(duì)象。
    $root:Page: 組件所在的Page對(duì)象,如果當(dāng)前組件是Page對(duì)象,那么$root的值就是自己本身。
    $coms:List<Component>:組件的子組件列表。
    $mixins:Array[Mixin]:組件所注入的Mixin對(duì)象。
    data:Object: 組件需要綁定的數(shù)據(jù)。
    methods:List<Function>:組件需要響應(yīng)的事件列表。
    props:List<Props>:組件允許傳遞的props列表。
    events:List<Function>:組件通信時(shí)所需要的事件表現(xiàn)。
    
    方法
    getCurrentPages():相當(dāng)于全局方法getCurrentPages()。
    $getComponent(com:String):通過組件名稱路徑查找組件對(duì)象。
    $invoke(com:String|Component):調(diào)用另一組件的方法。
     // coma.js
      this.$invoke('./ComB', 'func1', 'p1', 'p2');
      this.$invoke('./ComB', 'func2', 'p1', 'p2');
    
      // comb.js
      export class ComB extends wepy.component {
          methods = {
              func1 (p1, p2, evt) {}
          },
          func2 (p1, p2) {}
      }
      
      $broadcast(eventName:String, [args]):組件發(fā)起一個(gè)廣播事件。
      // page1.js
      components = { ComA };
      this.$broadcast('broadcast-event', 'p1', 'p2');
    
      // coma.js
      events = {
          'broadcast-event': (p1, p2, event) {}
      }
      
      $emit(eventName:String, [args]):組件發(fā)起一個(gè)冒泡事件。
       // coma.js
      this.$emit('emit-event', 'p1', 'p2');
    
      // page1.js
      components = { ComA };
      events = {
          'emit-event': (p1, p2, event) => {}
      }
    
    $apply([func:Function]):組件發(fā)起臟檢查。
    正常流程下,改變數(shù)據(jù)后,組件會(huì)在流程結(jié)束時(shí)自動(dòng)觸發(fā)臟檢查。 在異步或者回調(diào)流程中改變數(shù)據(jù)時(shí),需要手動(dòng)調(diào)用$apply方法。
    
    $nextTick([func:Function]):組件數(shù)據(jù)綁定完成后的回調(diào)事件,v1.6.1以上可用。
    
  3. wepy.page Class

    頁面類,繼承自wepy.component,擁有頁面所有的屬性與方法。
    $preload(key:String|Object, [value:Object]):給頁面加載preload數(shù)據(jù)
    $redirect(url:String|Object, [params:Object]):wx.redirectTo的封裝方法。
    this.$redirect('./page2', {a: 1, b: 2});
      this.$redirect({
          url: './pages?a=1&b=2'
      });
    

    ?

  4. wepy.event Class

  5. wepy.mixin Class

    Mixin基類,用于復(fù)用不同組件中的相同功能。
    // mymixn.js
    export class MyMixin extends wepy.mixin {
        // my logic here
    }
    
    // mycom.js
    import MyMixin from './mymixin';
    export class MyCom extends wepy.component {
        mixins = [MyMixin];
    }
    
  6. over

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容