微信小程序01 -- 基础知识

2019-03-06  本文已影响1人  MickeyMcneil

特点

触手可及,用完即走。就是微信里的原生APP。

小程序示例

微信搜索“小程序示例”,可以获得 组件 接口 云开发 的示例。

注册

搭建开发环境

下载“微信web开发者工具”即可。


微信web开发者工具

项目结构

约定大于配置,页面放在pages文件夹下。

Quick Start项目结构
其中,app.json是全局的配置文件,project.config.json是整个项目的描述文件,类似于node中的package.json

页面组织结构

新建页面:

  1. app.json中添加对应页面
  2. 添加完毕后,pages文件夹中会自动生成对应的页面
  3. app.json中第一个页面对应初始页面

页面文件说明:

  1. demo.js
    页面逻辑文件,创建页面对象,处理页面生命周期,处理页面数据
  2. demo.wxml -- Wei Xin Markup Language
    定义页面元素结构,语法遵循XML
  3. demo.json(可选)
    设置当前页面工作时的window配置,会覆盖 app.json中的window设置
  4. demo.wxss -- Wei Xin Style Sheet(可选)
    定义页面样式,遵循css语法,在css基础上有扩展,例如rpx响应式像素

配置文件

页面配置文件优先于项目配置文件,即demo.json优先于app.json
页面的配置只能配置app.json中部分window配置项的内容


标签栏的配置

在小程序中,标签栏不是通过布局实现的,是通过配置实现的

app.json中tabBar的配置内容
注意:

  1. pages配置中对应的第一个页面,必须在tabBar中配置
  2. iconPath中的配置,不能使用相对路径,只能使用绝对路径。可在项目的根目录中设置assets文件夹放置图片
  "tabBar": {
    "list": [{
      "pagePath": "pages/foo/foo",
      "text": "foo",
      "iconPath": "assets/tabs/home.png",
      "selectedIconPath": "assets/tabs/home-active.png"
    },
    {
      "pagePath": "pages/demo/demo",
      "text": "demo",
      "iconPath": "assets/tabs/message.png",
      "selectedIconPath": "assets/tabs/message-active.png"
    }

逻辑与页面结构分离

视图层: WXML WXSS 展示逻辑层数据,接收用户输入
逻辑层:由js完成,处理生命周期事件

逻辑层的javaScript


应用的生命周期

应用的生命周期在app.js文件中

// 用于去创建一个应用实例对象
App({
  // 在整个应用启动时触发
  // 只会触发一次
  onLaunch: function () {
    console.log('应用启动')
  },
  // 应用程序显示到屏幕上
  // 每次成为焦点状态触发
  onShow: function (options) {
    console.log('应用前台显示')
    console.log(options)
  },
  onHide: function () {
    console.log('应用后台隐藏')
  },
  // 只能捕获到运行阶段的异常
  onError: function (msg) {
    console.log(msg)
  },
  // 除了生命周期的钩子函数,还可以定义其他成员
  // 定义的成员在其他页面中可共享
  foo: "bar",
  say () {
    console.log('hi~~~~')
  }
})

index.js可以使用app.js中定义的成员

  onLoad: function (options) {
    // 获取全局唯一的应用程序实例对象
    const app = getApp() 
    console.log(app.foo)
    app.say()
  },

页面的生命周期

页面的生命周期在页面对应的js文件中设置,例如index.js

// 创建一个页面实例对象
Page({
  data: {},
  // 页面加载
  // 适用于数据初始化
  onLoad () {
    console.log('index page on load')
    this.setData({ foo: 'hello yd'})
  },
  // 页面进入焦点状态(前台展示)
  onShow () {
    console.log('index page on show')
  },
  onHide () {
    console.log('index page on hide')
  },
  // 当前页面渲染完成
  onReady () {
    console.log('index page on ready')
    // 举例,只有页面加载完成,才可以设置标题
    wx.setNavigationBarTitle({
      title: 'foo',
    })
  },
  // 页面卸载 当前页面被销毁
  onUnload () {
    console.log('index page on unload')
  }
})

index.wxml

<text>{{ foo }}</text>

数据绑定 和 wxs

在小程序中,所有的数据都定义的逻辑文件,例如index.js中的data中
index.wxml

<view class='container'>
  <!-- mustache 小胡子语法 可用于输出逻辑层暴露的数据 -->
  <text>{{message}}</text>
  <!-- mustache 可以作用在元素的内容和属性上 -->
  <input value='{{message}}'></input>
  <!-- 字符串拼接 运算 逻辑判断 三元表达式 均可 -->
  <input value='{{message}}~~~'></input>
  <text>{{ 22 + 22 }}</text>
  <!-- wxml中属性的值如果在引号内部 它永远是字符串 如下,第一个勾选了,第二个没勾选 -->
  <checkbox checked='false'></checkbox>
  <checkbox checked='{{false}}'></checkbox>

  <text>{{foo.addFn(1)}}</text>
</view>

<!-- wxs 类似与html中的script标签 -->
<wxs module='foo'>
  // 此处导出的对象可直接在界面上使用
  // 此处代码必须遵循commonjs规范 
  // 报错 -- 暂未解决
  module.exports = {
    addFn: function (value) {
    return value + '1'
  }
</wxs>

index.js

Page({
  data: {
    // data对象里的所有属性都可以在界面中访问到
    message: "hello goudaner~"
  }
})

基本组件

小程序提供的常用标签组件

  1. view
    hover-class属性,指定按下去的效果,当值为none时,没有点击动态效果。

tag.wxml

<view hover-class="bg">
  点我试试
</view>

tag.wxss

.bg {
  background-color: yellow;
}
  1. text
    显示普通的文本,text里面只能嵌套text
    selectable 文本是否可选
    decode 是否解码

tag.wxml

<text selectable="{{true}}">
  长按我试试
</text>
<text decode="{{true}}">
  冯&nbsp;薪&lt;朵
</text>
  1. image
    web中图片标签和背景图片的结合,不支持背景图片的写法
    mode 裁切、缩放的模式
    lazy-load 懒加载,只针对pagescroll-view下的image有效
  2. swiper
    tag.wxml
<view>
  轮播
  <swiper indicator-dots="false" indicator-color="rgba(0,0,0,.3)" indicator-active-color="rgba(0,0,0,.8)" autoplay="true" interval="1000">
    <swiper-item>
      1
    </swiper-item>
    <swiper-item>
      2
    </swiper-item>
    <swiper-item>
      3
    </swiper-item>
  </swiper>
</view>

wxss

swiper-item {
  background-color: pink;
}
  1. navigator
    tag.wxml
<!-- target self/miniProgram -->
<!-- open-type 
navigate 保留当前页面,跳转到其他页面,不能跳转tabbar页面
redirect 关闭当前页面,跳转到其他页面,不能跳转tabbar页面
switchTap 跳转到tabbar页面,关闭其他页面
reLaunch 关闭所有页面,打开应用内的某个页面
navigateBack 返回上一页面
exit 退出小程序,target为miniProgram时生效
-->
<navigator target="self" url="../message/message" open-type="navigate">
  点击跳转
</navigator>

自定义组件

创建自定义组件,创建位置/components/Mytext

控制属性

条件渲染

condition.wxml

<view wx:if="{{ isLoading }}">
  <text>加载中……</text>
</view>
<!-- <view wx:elif=""></view> -->
<view wx:else>
  <text>加载完毕!!!</text>
</view>

<!-- 对于频繁切换的元素 不应使用wx:if 应使用hidden -->
<view hidden="{{ !isLoading }}">
  <text>加载中……</text>
</view>
<view hidden="{{ isLoading }}">
  <text>加载完毕!!!</text>
</view>

<!-- block是包装元素 不会对界面的结构造成影响 -->
<view>
  <block wx:if="{{ isLoading }}">
    <text>加载中</text>
    <text>……</text>
  </block>
  <text>嘤嘤嘤~别隐藏我~~~</text>
</view>

condition.js

Page({
  data: {
    isLoading: true
  },
  onReady () {
    setTimeout( () => {
      this.setData ({ isLoading: false})
    }, 3000)
  }
})

列表渲染

each.js中,提供要渲染的数据,和视图层的事件处理函数

Page({
  data: {
    snh: [
      { id: 1, name: 'fxd', age: 18 },
      { id: 2, name: 'htt', age: 16 },
      { id: 3, name: 'fqy', age: 17 },
      { id: 4, name: 'qyw', age: 19 },
    ]
  },
  // 页面上除了生命周期钩子外,可定义其他函数
  // 这些函数可作为视图层元素的事件处理函数
  addItemHandle () {
    const snh = [{ id: Math.floor(Math.random()), name: 'nc' + Math.floor(Math.random()), age: Math.floor(Math.random()) + 10}].concat(this.data.snh)
    this.setData({ snh })
  }
})

each.wxml

<view>
  <!-- 写法1 -->
  <!-- item index 是默认的  -->
  <!-- key值必须要配 详见写法3中的说明 -->
  <view wx:for="{{snh}}" wx:key="{{id}}">
    <text>{{index}}</text>
    <text>name: {{item.name}}</text>
  </view>
  <!-- 写法2 -->
  <!-- item改变 -->
  <view wx:for="{{snh}}" wx:for-item="jxl" wx:key="{{id}}">
    <text>{{index}}</text>
    <text>name: {{jxl.name}}</text>
  </view>
  <!-- 写法3 -->
  <!-- wx:key 绑定的是单项属性名称,属性名前不必加item -->
  <!-- 如果是纯数组,没有属性名称,那么可以使用*this去指定当前被遍历的元素 -->
  <view wx:for="{{snh}}" wx:key="id">
    <checkbox/>
    <text>{{item.name}}</text>
  </view>
  <!-- key值,每个数据的唯一标识,确定数据和界面内容的一一对应关系 -->
  <!-- 如果不加key值,这边新增内容后,勾选的项目会发生改变 -->
  <button bindtap="addItemHandle">add</button>
  <!-- 写法4 -->
  <!-- 循环内容为字符串时,会拆开字符串 -->
  <view wx:for="fxdd" wx:key="*this">--{{item}}--</view>
</view>

事件处理

dothings.js中定义事件处理函数

Page({
  // 定义应用于界面层的事件处理函数
  tapHandle (e) {
    console.log(e)
  }
})

dotings.wxml中调用事件处理函数

<button bindtap="tapHandle">点击</button>

当点击按钮时,控制台打印结果如下


打印结果
  1. timeStamp -- 触发事件的时间,与页面加载完成的时间差
  2. target -- 拿到当前被点击的元素
  3. detail -- 以屏幕左上角为原点,触发事件时点击的坐标

事件冒泡

在小程序中,绑定事件时,将bind改成catch就能阻止事件冒泡。
dotings.js

Page({
  // 定义应用于界面层的事件处理函数
  tapHandle (e) {
    console.log(e)
  },
  viewTapHandle (e) {
    console.log('冒泡', e)
  }
})

dothings.wxml

<view bindtap='viewTapHandle'>
  <!-- 使用bindtap会冒泡 -->
  <!-- <button bindtap="tapHandle">点击</button> -->
  <!-- 使用catchtap不会冒泡 -->
  <button catchtap="tapHandle">点击</button>
</view>

获取当前行的参数

可以通过data-xx属性,给事件处理函数传递额外的参数。
dothings.js

Page({
  removeHandle (e) {
    console.log(e)
  }
})

dothings.wxml

<view>
  <text>item 1</text>
  <button bindtap='removeHandle' data-id='1'>移除</button>
</view>
<view>
  <text>item 2</text>
  <button bindtap='removeHandle' data-id='2'>移除</button>
</view>
<view>
  <text>item 3</text>
  <button bindtap='removeHandle' data-id='3'>移除</button>
</view>

当点击第二个移除按钮时,控制台数据如下


单项数据流

小程序和react相似,都是单项数据流

单项数据流
需求:输入框中值改变时,上方显示的文字也发生变化

代码:
index.js
Page({
  data: {
    content: 'fxd is fdd'
  },
  inputChangeHandle (e) {
    // 1. 改变数据源
    // 2. 通知框架,重新渲染页面
    this.setData({content: e.detail.value})
  }
})

index.wxml

<text>{{content}}</text>
<input value='{{content}}' bindinput='inputChangeHandle'></input>

index.wxss

input {
  border: 1px solid pink;
  margin: 20px;
  padding: 10px;
}

小程序不同于vue,数据发生变化时,如果要在页面的其他位置展示变化后的数据,一定要在逻辑层使用setData

wxss和css的对比

  1. rpx
    rpx(responsive pixel):可以根据屏幕宽度进行自适应,规定屏幕宽度为750rpx。

百分比的缺点:
margin padding使用百分比时非常混乱
百分比涉及到父子盒子之间的传递

  1. weui
    微信小程序的ui框架,使用时可以在dist/example中找demo。
上一篇下一篇

猜你喜欢

热点阅读