1. 程式人生 > >開發微信小程式-目錄解析(二)

開發微信小程式-目錄解析(二)

文件:https://developers.weixin.qq.com/miniprogram/dev/quickstart/basic/file.html#js-互動邏輯

普通快速模板
在這裡插入圖片描述
開發目錄
├── app.js
├── app.json
├── app.wxss
├── pages
│ │── index
│ │ ├── index.wxml
│ │ ├── index.js
│ │ ├── index.json
│ │ └── index.wxss
│ └── logs
│ ├── logs.wxml
│ └── logs.js
└── utils

.json 字尾的 JSON 配置檔案
.wxml 字尾的 WXML 模板檔案
.wxss 字尾的 WXSS 樣式檔案
.js 字尾的 JS 指令碼邏輯檔案

分析圖片 從下往上 =>
project.config.json:整個專案的配置檔案。
app.js:整個應用程式入口檔案。
app.json:入口檔案配置資訊。
app.wxss:應用程式全域性樣式檔案。

wxss = WeiXin Style Sheet微信樣式表,類似於css檔案。

utils資料夾:工具包檔案所在目錄。自行封裝的模組。供其他小程式頁面使用。類似於vue中的過濾器概念,工具包中可以定義一些格式化的函式等。

pages資料夾:小程式各個頁面的檢視,業務邏輯,樣式,配置檔案所在目錄。特別注意:在小程式中每一個頁面都擁有獨立的檢視,業務邏輯,樣式,配置檔案。和vue的類比如下:
index/index.js相當於vue中的

wxml = WeiXian Markup Language微信標記語言,類似於html或xml。

各檔案之間的關聯關係:

pages資料夾下的每一個資料夾,如index,logs等,內部包含四個檔案,但四個檔案並不是必須的,如.json檔案就可以沒有。並且每個檔案的檔名稱(不包含字尾名稱)一般約定對應資料夾的名稱,如:index資料夾中四個檔案命名分別為:index.json,
index.js, index.wxss,
index.wxml。這是一種約定好的風格。每個資料夾相當於vue中定義的一個頁面級元件。和當前小程式的入口配置檔案app.json有對應(很重要的關聯),如:
“pages”: [ “pages/index/index”, “pages/logs/logs” ]
每個資料夾中的四個檔案之間的關聯關係,微信已幫我們做過封裝,不用開發者再引入。如index.json,index.js,index.wxml,index.wxss自去產生關係。在渲染檢視index.wxml時會自動使用index.wxss樣式檔案,自動使用index.js業務邏輯檔案及配置檔案index.json。

工具包檔案是自行封裝的模組包,要想在其他頁面中使用,必須引入。 引入方法如:const util =
require(’…/…/utils/util.js’) 類似於node.js中的引入模組包。


project.config.json - 專案配置檔案
應用程式啟動時候,會自動讀取配置檔案,約定一些規則
()裡面是解釋

{
	"description": "專案配置檔案(什麼專案,包含哪些功能)",  
	"packOptions(包選項)": {
		"ignore": []
	},
	"setting": {
		"urlCheck(是否校驗url地址)": true,
		"es6": true,
		"postcss(css格式化)": true,
		"minified(壓縮)": true,
		"newFeature(版本迭代新特性)": true
	},
	"compileType(編譯型別-定義的專案名稱)": "miniprogram",
	"libVersion": "2.0.4",
	"appid(開發和上線的AppID有可能不一樣)": "wx7acb670e00b40e5b",
	"projectname": "demo-%E6%99%AE%E9%80%9A%E6%A8%A1%E6%9D%BF",
	"debugOptions": {
		"hidedInDevtools(本地)": []
	},
	"isGameTourist(遊戲是true)": false,
	"condition": {
		"search": {
			"current": -1,
			"list": []
		},
		"conversation": {
			"current": -1,
			"list": []
		},
		"game": {
			"currentL": -1,
			"list": []
		},
		"miniprogram": {
			"current": -1,
			"list": []
		}
	}
}

執行時候最先執行的是
app.js(唯一的入口地址)

小程式裡面三大物件:1,應用程式App({ }) 2,頁面page({}) 3,元件component({})
元件開發
就一個App({ })
在其他頁面呼叫可以:
const app = getApp() 獲取

//app.js整個應用程式的入口檔案
//App()物件,是應用程式物件,在其他頁面可以通過getApp()方法獲取當前應用程式物件例項。
//如:index/index.js中const app = getApp()
 App({
  // 應用程式啟動時執行的鉤子事件。只執行一次。
  onLaunch: function () {
    // 展示本地儲存能力getStorageSync()是微信提供的兩步獲取快取的api,以後看到wx.開頭的都是微信的api,具體有檔案可參考。setStorageSync()用來設定快取。
    var logs = wx.getStorageSync('logs') || []
    logs.unshift(Date.now())
    wx.setStorageSync('logs', logs)

    // 登入
    wx.login({
      success: res => {
        // 傳送 res.code 到後臺換取 openId, sessionKey, unionId
        console.log(res)
      }
    })
    // 獲取使用者資訊
    wx.getSetting({
      success: res => {
        console.log(res)
        if (res.authSetting['scope.userInfo']) {
          // 已經授權,可以直接呼叫 getUserInfo 獲取頭像暱稱,不會彈框
          wx.getUserInfo({
            success: res => {
              // 可以將 res 傳送給後臺解碼出 unionId
              console.log(res)
              this.globalData.userInfo = res.userInfo

              // 由於 getUserInfo 是網路請求,可能會在 Page.onLoad 之後才返回
              // 所以此處加入 callback 以防止這種情況
              if (this.userInfoReadyCallback) {
                console.log('1234567890-')
                this.userInfoReadyCallback(res)
              }
            }
          })
        }
      }
    })
  },
  // 全域性資料,在app.js的配置項中定義的資料可以供所有的頁面使用,在其他頁面中通過const app = getApp()獲取當前應用程式例項後,就可以通過app.globalData.userInfo訪問此處定義的資料。
  globalData: {
    userInfo: null,
    person: {
      name: 'dsh2',
      age: 20
    }
  },
  //自定義的屬性也可以在其它頁面中訪問。一般不建議這樣使用,建議把資料放到globalData中。
  person: {
    name: 'dsh1',
    age: 19
  }
})

app.wxss全域性的樣式檔案–所有頁面共享

/**app.wxss**/
.container {
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-between;
  padding: 200rpx 0;
  box-sizing: border-box;
} 
 rpx 是微信小程式解決自適應螢幕尺寸的尺寸單位。微信小程式規定螢幕的寬度為750rpx。

app.json-當前應用程式的配置檔案

{
  "pages":[
    "pages/index/index",
    "pages/logs/logs"
  ],
  "window":{
    "backgroundTextStyle":"light",
    "navigationBarBackgroundColor": "#fff",
    "navigationBarTitleText": "WeChat",
    "navigationBarTextStyle":"black"
  }
}

配置各個項的含義:

pages欄位 —— 用於描述當前小程式所有頁面路徑,這是為了讓微信客戶端知道當前你的小程式頁面定義在哪個目錄。
window欄位 —— 定義小程式所有頁面的頂部背景顏色,文字顏色定義等。

project.config.json

{
	"description": "專案配置檔案",
	"packOptions": {
		"ignore": []
	},
	"setting": {
		"urlCheck": true,
		"es6": true,
		"postcss": true,
		"minified": true,
		"newFeature": true
	},
	"compileType": "miniprogram",
	"libVersion": "2.3.0",
	"appid": "wx671ce38d22d3c5ae",
	"projectname": "demo",
	"debugOptions": {
		"hidedInDevtools": []
	},
	"isGameTourist": false,
	"condition": {
		"search": {
			"current": -1,
			"list": []
		},
		"conversation": {
			"current": -1,
			"list": []
		},
		"game": {
			"currentL": -1,
			"list": []
		},
		"miniprogram": {
			"current": -1,
			"list": []
		}
	}
}
  • 開發文件

wxml 模板

在網頁的一般開發流程中,我們通常會通過 JS 操作 DOM (對應 HTML 的描述產生的樹),以引起介面的一些變化響應使用者的行為。

例如,使用者點選某個按鈕的時候,JS 會記錄一些狀態到 JS 變數裡邊,同時通過 DOM API 操控 DOM 的屬性或者行為,進而引起介面一些變化。當專案越來越大的時候,你的程式碼會充斥著非常多的介面互動邏輯和程式的各種狀態變數,顯然這不是一個很好的開發模式,

因此就有了 MVVM 的開發模式(例如 React, Vue),提倡把渲染和邏輯分離。簡單來說就是不要再讓 JS 直接操控 DOM,JS 只需要管理狀態即可,然後再通過一種模板語法來描述狀態和介面結構的關係即可。

需要把一個 Hello World 的字串顯示在介面上。

WXML 是這麼寫 :

<text>{{msg}}</text>

JS 只需要管理狀態即可:

this.setData({ msg: "Hello World" })

通過 {{ }} 的語法把一個變數繫結到介面上,我們稱為資料繫結。

完整的描述狀態和介面的關係,還需要 if/else, for等控制能力,在小程式裡邊,這些控制能力都用 wx: 開頭的屬性來表達。

js互動

在前邊的 QuickStart 例子中,在 pages/index/index.js 就呼叫了 wx.getUserInfo 獲取微信使用者的頭像和暱稱,最後通過 setData 把獲取到的資訊顯示到介面上

<view>{{ msg }}</view>
<button bindtap="clickMe">點選我</button>

點選 button 按鈕的時候,我們希望把介面上 msg 顯示成 "Hello World",於是
我們在 button 上宣告一個屬性: bindtap ,
在 JS 檔案裡邊聲明瞭 clickMe 方法來響應這次點選操作:

Page({
  clickMe: function() {
    this.setData({ msg: "Hello World" })
  }
})

小程式啟動

首先 把整個小程式的程式碼包下載到本地

緊接著通過 app.json 的 pages獲得所有頁面路徑

寫在 pages 欄位的第一個頁面就是這個小程式的首頁

微信客戶端就把首頁的程式碼裝載進來,通過小程式底層的一些機制,就可以渲染出這個首頁。

小程式啟動之後,在 app.js 定義的 App 例項的 onLaunch 回撥會被執行:

App({
  onLaunch: function () {
    // 小程式啟動之後 觸發
  }
})

舉個例子

<!-- This is our View -->
<view> Hello {{name}}! </view>
<button bindtap="changeName"> Click me! </button>
// This is our App Service.
// This is our data.
var helloData = {
  name: 'WeChat'
}

// Register a Page.
Page({
  data: helloData,
  changeName: function(e) {
    // sent data change to view
    this.setData({
      name: 'MINA'
    })
  }
})

開發者通過框架將邏輯層資料中的 name 與檢視層的 name 進行了繫結,所以在頁面一開啟的時候會顯示 Hello WeChat!;
點選按鈕的時候,檢視層會傳送 changeName 的事件給邏輯層,邏輯層找到並執行對應的事件處理函式
回撥函式觸發後,邏輯層執行 setData 的操作,將 data 中的 name 從 WeChat 變為 MINA,因為該資料和檢視層已經綁定了,從而檢視層會自動改變為 Hello MINA!。