原生小程序开发-基本目录结构介绍与基础语法

217 阅读8分钟

一、创建小程序项目

1. 点击➕新建小程序项目

2.jpg

2.填写项目名称、项目存放目录、AppID、选择开发模式等信息,点击确定就可以进行项目开发了。AppID官网注册登录后,点击开发-开发管理,即可看到开发者ID中的AppID

3.jpg

4.jpg

二、基本目录结构介绍

5.jpg

小程序页面文件夹(每个页面分成4类文件):

  1. js业务逻辑文件(在该文件中调用Page()方法注册页面,指定页面的初始数据data:{}、生命周期回调、事件处理函数等)

  2. wxml页面结构 类似html

  3. wxss页面样式(rpx适配单位、@import ""; 外联样式导入) 类似css(rem适配单位)

  4. json 配置文件(页面配置,进行组件注册)

页面配置属性详见:developers.weixin.qq.com/miniprogram…

注:当小程序页面配置与全局配置冲突时根据就近原则以页面配置为准

小程序全局配置

  1. app.js小程序执行的入口文件(在该文件中调用APP()方法注册一个小程序应用,小程序启动后会加载app.json配置文件中”pages”项的第一个注册的页面)

  2. app.wxss小程序全局样式文件

  3. app.json小程序应用全局配置文件(对微信小程序进行全局配置,决定页面文件的路径、窗口表现、设置网络超时时间、设置多 tab 等)

全局配置属性详见: developers.weixin.qq.com/miniprogram…

6.png

  • pages:记录小程序所有页面存放路径,tabbar页面在pages中要往前提

  • windows:全局设置小程序窗口外观(窗口分为导航栏区域navigationbar、背景区域background(下拉显示)、页面主体区域(展示wxml中的布局))

可以配置导航栏标题、标题颜色(黑白)、背景色(十六进制颜色值)、下拉刷新、下拉刷新背景色(十六进制颜色值)、loading样式(黑白)、上拉触底距离等

  • tabbar:设置小程序tabbar效果,实现多页面快速切换(底部tabbar、顶部tabbar)

可以配置tabbar背景色、上边框颜色、选中和未选中时的文本颜色、页面路径、文本、选中和未选中时的图标路径

注意:只能配置2-5个tab页签;顶部tabbar不显示icon,只显示文本

  • style:"v2"是否启用新版的组件样式

三、语法

快速创建小程序页面:

找到app.json文件,在pages选项中增加页面路径,保存,微信开发者工具会自动创建对应的页面文件。

小程序官方文档developers.weixin.qq.com/miniprogram…

1.组件(小程序内置组件在官方文档--组件中可查看)

例:

view视图容器,类似div标签

scroll-view可滚动的视图容器,滚动列表效果

swiper轮播图容器组件,swiper-item轮播图item

text文本组件,类似span标签,不会换行,selectable属性实现长按选中文本内容效果

rich-text富文本组件,nodes属性支持把html字符串渲染为wxml结构(nodes="<h1>标题</h1>")

navigator url=“”超链接,类似a href=“”标签

image图片组件,mode属性指定图片裁剪缩放模式(scaleToFill默认不保持横纵比缩放)

button按钮组件,open-type属性可以调用微信提供的各种功能(客服、转发、获取用户授权、信息等)

2. 样式

app.wxss中定义全局样式,可以在所有页面直接用

页面文件夹中的wxss文件定义页面样式,在该页面直接用

3. 数据显示

模板插值{{}}

4. 数据处理
4.1动态绑定数据

js文件data中定义数据:data: {title: "首页"}

wxml文件中使用数据:<text>{{title}}</text>

4.2动态绑定属性

data: {src: "www.baidu.com"}

<navigator url=“{{src}}”></navigator>

(vue中绑定属性用v-bind)

4.3获取、更改数据

获取:this.data.title

更改:this.setData({title})(同react)

5. 事件(常用事件:tap手指触屏后马上离开,类似click、input文本框输入事件、change复选框状态改变时触发)

bind:tap=""或者bindtap=""手指触屏后马上离开(vue中v-on:click=””或者@click=””点击事件)

bind:longpress=””手指触屏后超过350ms在离开,长按事件

bind:touchmove=””手指触摸后移动

bind:touchstart=””手指触摸动作开始

bind:touchend=””手指触摸动作结束

bind:touchcancel=””手指触摸动作被打断,比如来电提醒

bind:input=""文本框输入事件

 

5.1事件回调触发,会收到一个事件对象event,其属性有:

type:事件类型

timeStamp:页面打开到触发事件所经过的毫秒数

target:触发事件的源头组件的一些属性值集合

currentTarget:当前正在触发事件组件的一些属性值集合

detail:额外的参数信息

touches:触摸事件,当前停留在屏幕中的触摸点信息的数组

changedTouches:触摸事件,当前变化的触摸点信息的数组

5.2事件冒泡(当触发一个事件时,事件会从事件源向上冒泡,直到window对象结束)bind:tap=""

除 bind 外,也可以用 catch 来绑定事件, catch 会阻止事件向上冒泡。

阻止事件冒泡catch:tap=""

 

5.3事件捕获capture-bind:tap=””

阻止事件捕获capture-catch:tap=””

应用场景:自定义组件时

6、事件传参

bind:tap="onDelete" data-id="{{100}}"({{100}}传的是数字,100传的是字符串)

通过data-传参,id为参数名,100为参数值(vue中 通过事件括号传参)

e.target.dataset获取参数

7、条件渲染

wx:if/wx:elif/wx:else=”{{online}}”(vue中v-if/v-else=”online”)

结合block使用,使用block标签将多个组件包装起来,一次性控制多个组件的展示隐藏:

block包裹不会在页面中渲染,view包裹会在页面中渲染

<block wx:if="{{true}}">

<view>1</view>

<view>2</view>

</block>

控制元素显示隐藏:<view hidden=“{{true}}”>1</view>

wx:if和hidden对比:

wx:if以动态创建和移除元素的方式,实现元素的展示隐藏。控制条件比较复杂时使用

hidden以切换样式的方式,控制元素的展示隐藏(display:none/block)。频繁切换时使用

8、列表渲染

wx:for=”{{list}}”  wx:key=”id”(vue中v-for=”list” :key=”id”)

列表项默认为item,索引号默认为index

wx:for-item=”user” wx:for-index=”id”

列表项修改为user,索引号修改为id

9、表单数据双向绑定

value=””  bind:input=””/model:value=”{{}}” 通过e.detail.value获取输入框的值

(vue中 :value="" @input=""/v-model 通过event.target.value获取输入框的值)

10、屏幕适配单位rpx

小程序特有的适配单位,可以根据屏幕宽度自适应

rpx把所有设备的屏幕宽度等分为750份(即当前屏幕总宽度为750rpx),小程序在不同设备上运行的时候,会自动把rpx 的样式单位换算成对应的像素单位来渲染,从而实现屏幕适配

换算:  rpx换px(屏幕宽度/750)

iphone6  屏幕宽度375px,750个物理像素,等分为750rpx

1rpx = 0.5px  1px = 2rpx

示例代码

wxml文件

<view class="container">

   <view>-- 数据显示 --</view>

   <text>{{title}}</text>

 

   <view>-- 触屏事件 --</view>

   <button bind:tap="onTap">确定</button>

   <!-- <button bindtap="onTap">确定</button> -->

 

   <view>-- 条件渲染 --</view>

   <view>

       <text wx:if="{{online === 0}}">在线状态</text>

       <text wx:elif="{{online === 1}}" >离线状态</text>

       <text wx:else>隐身状态</text>

   </view>

 

   <view>-- 列表渲染 --</view>

   <view>

       <view wx:for="{{list}}" wx:key="index">

            <text>{{item.name}}-{{item.age}}</text>

       </view>

       //修改列表项和索引号

       <view wx:for="{{list}}" wx:for-item="user" wx:for-index="id" wx:key="id">

          <text>{{id}}-{{user.name}}-{{user.age}}</text>

       </view>

   </view>

 

   <view>-- 表单双向数据绑定 --</view>

   <view>

       <text>{{inputValue}}</text>

       <!-- <input class="m-input" type="text" value="{{inputValue}}" bind:input="onInput" placeholder="请输入内容"/> -->

       <input class="m-input"  type="text" model:value="{{inputValue}}"/>

   </view>

 

   <view>-- 事件传参 --</view>

   <view>

      <button bind:tap="onDelete" data-id="100" data-price="88.98">删除</button>

   </view>

   

   <view>-- rpx 屏幕适配单位 --</view>

   <view>

       <view class="g-wrapper">rpx单位</view>

   </view>

</view>

js文件

Page({

  data: {

    title"首页",

    online2,

    list: [

      { name"jack"age21 },

      { name"rose"age20 },

      { name"tom"age21 },

    ],

    inputValue"hello",

  },

  // 触屏事件

  onTap() {

    console.log("onTap >>> ");

    // this.data.title = '修改后的首页'

    //更改数据

    this.setData({title:'修改后的首页'})

    

  },

  /**

   * 输入事件

   *  e.detail.value

   */

  onInput(e) {
    // this.setData({ inputValue:e.detail.value });

    const inputValue = e.detail.value;

    console.log("onInput >>> ", inputValue);

    this.setData({ inputValue });

  },

  // 删除

  onDelete(e) {

      console.log("onDelete >>> ", e);

      console.log('id  ',e.target.dataset.id);

      console.log('price  ',e.target.dataset.price);

  },

});

wxss文件

.m-input{

  border1px solid gray;

}

 

.g-wrapper{

   /* width: 100px;

   height: 100px; */

   width200rpx;

   height200rpx;

   background-color: skyblue;

}
11、wxs小程序独有的脚本语言(结合wxml构建页面结构)

wxml中无法调用在页面的.js 中定义的function函数,但是,wxml中可以调用 wxs 中定义的函数。当作过滤器使用。

wxs语法:

① wxs 有自己的数据类型(number、string、boolean、object、function、array、date日期类型、regexp正则)

② wxs 不支持ES6及以上的语法形式

不支持:let、const、解构赋值、展开运算符、箭头函数、对象属性简写、etc..

支持:var 定义变量、普通 function 函数等,类似于 ES5 的语法

③ wxs 遵循 Commonjs 规范

module 对象、require()函数、module.exports 对象

④ wxs语法类似于javascript(wxml文件中使用<wxs>标签,<wxs>标签必须提供 module 属性,用来指定当前 wxs 的模块名称。就像html中使用<script>标签)

wxs特点:

  1. 隔离性( wxs 的运行环境和其他JavaScript 代码是隔离的)

① wxs 不能调用js 中定义的函数

② wxs 不能调用小程序提供的 API

2.性能好

① 在 i0s 设备上,小程序内的 WXS 会比JavaScript 代码快 2~20 倍

② 在 android 设备上,二者的运行效率无差异

示例代码1(内联)

wxml文件

<wxs module="eg">
  module.exports.filterUrl = function(url){
    if(url && url.indexOf('http') === -1){
      return 'https://10.7.163.165:8089'+url
    }
    return url
  }
</wxs>
<view>
  <!-- 菜品列表 -->
  <block wx:for="{{goodsList}}" wx:key="*this">
    <van-card num="0" price="{{item.price}}" desc="{{item.desc}}" title="{{item.product}}" thumb="{{ eg.filterUrl(item.picture) }}">
      <view slot="footer">
        <van-button round icon="plus" type="warning" size="mini"></van-button>
      </view>
    </van-card>
  </block>

</view>

js文件

// pages/goods/index.js
import { RequestGoodsList } from '../../api/goods'
Page({

  /**
   * 页面的初始数据
   */
  data: {
    goodsList: [], // 菜品列表
  },
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad(options) {
    this.getGoodsList()
  },
  /**
   * 获取菜品列表
   */
  async getGoodsList() {
    const data = await RequestGoodsList()
    const { resultCode, resultInfo } = data
    if (resultCode === 1) {
      const list = resultInfo.list // 当前页列表
      this.setData({ goodsList: list })
    }
  }
})
示例代码2(外联)

编写在以wxs为后缀的文件中,就像javascript编写在以js为后缀的文件中

在util文件夹中创建一个util.wxs文件

function filterUrl(url){
  if(url && url.indexOf('http') === -1){
      return 'http://10.7.163.165:8089'+url
  }
  return url
}

module.exports = {
  filterUrl:filterUrl//属性:值
}

wxml文件

<wxs src="../../utils/utils.wxs" module="util"></wxs>
<view>
  <!-- 菜品列表 -->
  <block wx:for="{{goodsList}}" wx:key="*this">
    <van-card num="0" price="{{item.price}}" desc="{{item.desc}}" title="{{item.product}}" thumb="{{ util.filterUrl(item.picture) }}">
      <view slot="footer">
        <van-button round icon="plus" type="warning" size="mini"></van-button>
      </view>
    </van-card>
  </block>

</view>

js文件

// pages/goods/index.js
import { RequestGoodsList } from '../../api/goods'
Page({

  /**
   * 页面的初始数据
   */
  data: {
    goodsList: [], // 菜品列表
  },
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad(options) {
    this.getGoodsList()
  },
  /**
   * 获取菜品列表
   */
  async getGoodsList() {
    const data = await RequestGoodsList()
    const { resultCode, resultInfo } = data
    if (resultCode === 1) {
      const list = resultInfo.list // 当前页列表
      this.setData({ goodsList: list })
    }
  }
})