小程序基础示例

小程序基础

基础视图组件

view

<view
  hover-class="hoverClass"
  hover-start-time="{{ 1000 }}"
  hover-stay-time="{{ 1000 }}"
  hover-stop-propagation
></view>

text

<text user-select space="nbsp" decode>\nt  ext&gt;</text>

icon

<icon type="success" size="46" color="#000" />
<!-- https://www.iconfont.cn/ -->

button

<button
  type="primary"
  size="mini"
  plain
  loading
  bindtap="onSayHello"
  open-type="feedback"
></button>

input

<input
  type="text" confirm-type="send"
  password
  placeholder="请输入"
  placeholder-style="font-weight: bold"
  placeholder-class=""
  model:value="{{ inputVlaue }}"
/>

radio

<radio-group bindchange="">
  <radio value="1" checked color="red" disabled> true </radio>
  <radio value="2"color="blue"> false </radio>
</radio-group>

checkbox

<checkbox-group bindchange="">
  <checkbox value="1" checked color="red" disabled>篮球</checkbox>
  <checkbox value="2">乒乓球</checkbox>
  <checkbox value="3">羽毛球</checkbox>
</checkbox-group>

textarea

<textarea
  class="textarea" 
  placeholder="请输入您的兴趣爱好" 
  placeholder-class="plClass"
  placeholder-style="font-weight: bold"
  disabled="{{ false }}"
  confirm-type="send"
  model:value="{{ value }}"
/>

switch

<switch 
  checked 
  type="switch" 
  color="#FF0000" 
  disabled="{{ false }}"
  bindchange="" 
/>

form

<form bindsubmit="handleSubmit" bindreset="handleReset">
  <input 
    name="userName" 
    class="input" 
    type="text" 
    placeholder="请输入您的姓名"
  />
  <radio-group name="userGender">
    <radio value="1"/><radio value="2"/></radio-group>
  <button form-type="submit" type="primary">Submit</button>
  <!-- 直接清空 form-type="reset" -->
  <!-- 复杂逻辑 handleReset -->
  <button form-type="reset" >Reset</button>
</form>

template

<!-- 声明 template -->
<template name="line">
  <view>Line 1</view>
  <view>Line 2</view>
  <view>Line 3</view>
  <view>{{ name }}</view>
</template>

<!-- 使用 template -->
<template is="line" data="{{ name }}" />
<!-- 声明外部的 template -->
<!-- /templete/header.wxml -->
<template name="header">
  <view>我是 header</view>
</template>
<view>
  我是 header template 之外的所有的内容
</view>

<!-- 引用外部的 template -->
<import src="./template/header"/>
<import src="./template/footer"/>

<template is="header" />
Content
<template is="footer"/>
<include src="./template/header" />
<!-- 组件公共属性 -->
<view id class style hidden data-* bind*/catch*></view>

跳转

1 标签 2 api
navigate eventChannel | uni 全局事件监听(主要)

<!-- url: 页面路径 相对/绝对路径 -->
<!-- open-type: navigate 默认值 -->
<navigator url="/pages/index/index" open-type="navigate">
  跳转到 index
</navigator>
wx.navigateTo({
  url: '/pages/index/index?name=coderMonkey&age=18',
  events: {
    sayHello(name, age) {
      console.log('hello', name, age)
    }
  },
  success: (result) => {
    // off 用于取消一个事件的监听
    result.eventChannel.off('sayHello')

    result.eventChannel.emit('sayWorld', 'codercoder', '20')
  },
  fail: (res) => {},
  complete: (res) => {},
})
// 目标页面
onLoad(options) {
  console.log('onLoad', options)
  // uni:
  // import { getCurrentInstance } from 'vue'}
  // const eventChannel = getCurrentInstance().ctx.getOpenerEventChannel()
  const eventChannel = this.getOpenerEventChannel()
  // emit 触发一个事件
  eventChannel.emit('sayHello', 'coderMonkey', 18)

  // on 监听方法 once 只监听一次
  eventChannel.on('sayWorld', (name, age) => {
    console.log('world', name, age)
  })
},
uni.$on/once('aaa', (a, b) => console.log('aaa', a, b))
// 在任何页面中监听
uni.$emit('aaa', 1, 2)
uni.$off('aaa')

返回

<!-- delta="999" 回到首页 -->
<navigator open-type="navigateBack" delta="1">返回上一页</navigator>
wx.navigateBack({
  delta: 1,
  success: (res) => {},
  fail: (res) => {},
  complete: (res) => {},
})
// 查看页面栈中的页面
console.log(getCurrentPages())

redirectTo

<!-- 会销毁起始页面 -->
<navigator url="/pages/pageThree/pageThree" open-type="redirect">
  跳转到 pageThree
</navigator>
  wx.redirectTo({
    url: '/pages/pageTwo/pageTwo?name=coderMonkey&age=99',
    success: (res) => {},
    fail: (res) => {},
    complete: (res) => {},
  })

switchTab

<!-- 不能传递参数 -->
<!-- open-type="redirect": 模拟器上效果是有问题的 真机查看  -->
<navigator url="/pages/profile/profile"open-type="switchTab">
 跳转到 home
</navigator>
// 只可以跳转到 tabbar 的页面 并且 url 不能传递参数
wx.switchTab({
  url: '/pages/profile/profile',
  success: (res) => {},
  fail: (res) => {},
  complete: (res) => {},
})

reLaunch

<!-- 会销毁所有页面 -->
<navigator url="/pages/home/home" open-type="reLaunch">
  跳转
</navigator>
wx.reLaunch({
  url: '/pages/pageTwo/pageTwo?name=coderMonkey&age=10000',
  success: (res) => {},
  fail: (res) => {},
  complete: (res) => {},
})

生命周期

页面

// uni:
// import { onLoad } from '@dcloudio/uni-app';
// onLaunch((options) => {
// 	console.log('onLaunch', options)
// })
Page({
  // 1. onLoad - 监听页面的加载 做一些初始化的操作
  onLoad(options) {
    console.log('onLoad', options)
  },
  // 2. onShow - 监听页面的显示 更新数据或者状态 重新执行一些方法
  onShow() {
    console.log('onShow')
  },
  // 3. onHide - 监听页面的隐藏 保存用户当前的状态 
  // 清除页面中多余的定时器
  onHide() {
    console.log('onHide')
  },
  // 4. onUnload - 监听页面的卸载 清空页面的状态和多余的操作
  onUnload() {
    console.log('onUnload')
  },
  // 5. onPullDownRefresh - 监听页面下拉
  onPullDownRefresh() {
    console.log('onPullDownRefresh')
  },
  // 6. onReachBottom - 上拉触底
  onReachBottom() {
    console.log('onReachBottom')
  },
  // 7. onPageScoll - 页面滚动
  onPageScroll(res) {
    console.log('res', res)
  }
})

应用

import { onLaunch, onShow, onHide, onError, onPageNotFound, onUnhandledRejection, onThemeChange } from '@dcloudio/uni-app';

事件交互

捕获和冒泡

<!-- 执行顺序 捕获-外 -> 捕获-内 -> 冒泡-内 -> 冒泡-外 -->
<view bindtap="冒泡-外" capture-bind:touchstart="捕获-外">
  outer
  <view bindtap="冒泡-内" capture-bind:touchstart="捕获-内">
    inner
  </view>
</view>

事件对象 event / e

<!-- type: 事件类型
timeStamp: 页面打开到触发事件所经历的毫秒数
target: 触发事件源组件
currentTarget: 触发事件当前组件
dataset: 用于获取自定义数据 (驼峰命名大写 转小写;中横线命名小写 转大写)
mark: 收集触发事件这条线上的自定义属性 (不会转化驼峰和中横线,同名属性子组件会覆盖父组件)
pageX pageY 距离文档左上角的距离
clientX clientY 距离页面可显示区域左上角的距离
detail: 通常用于在表单中获取最新 value 值 -->
<view
  mark:heightOut = "200"
  mark:width-out = "200"
  mark:height = "200"
  id="tapEvent2" 
  bind:tap="handleTap2"
 >
outter
  <view 
    class="view"
    mark:height="100"
    mark:width="100"
    data-userName="coderMonkey" 
    data-user-age="100" 
    id="tapEvent" 
    bind:tap="handleTap"
  >
    inner 我是一些内容
  </view>
</view>

交互反馈

onToast() {
  wx.showToast({
    title: '操作成功',
    duration: 100000, // 默认值 1500 ms
    // icon: "error",
    image: '/img/about.png',
    mask: true, // 透明遮罩,防止其他事件触发
    success: (res) => {
      console.log(res)
    },
    fail: (res) => {
      console.log(res)
    },
    complete: (res) => {
      console.log(res)
    },
  })

  // wx.hideToast({
  //   noConflict: 0,
  //   success: (res) => {},
  //   fail: (res) => {},
  //   complete: (res) => {},
  // })
},

onModal() {
  wx.showModal({
    cancelColor: '#00FF00',
    cancelText: '考虑一下',
    confirmColor: '#FF0000',
    confirmText: '确认',
    content: '确认之后就会提交哦!',
    editable: true,
    placeholderText: '请输入您的信息',
    showCancel: true,
    title: '确认操作',
    success: (result) => {
      // 如果说是可编辑的那么点击确定之后就可以在 result.content 中获取到结果
      console.log('result', result)
    },
    fail: (res) => {
      console.log(res)
    },
    complete: (res) => {
      console.log(res)
    }
  })
},

onLoading() {
  wx.showLoading({
    title: 'loading...',
    mask: true,
    success: (res) => {},
    fail: (res) => {},
    complete: (res) => {},
  })
  setTimeout(() => {
    wx.hideLoading({
      noConflict: true, // loading和toast不混用
      success: (res) => {},
      fail: (res) => {},
      complete: (res) => {},
    })
  }, 2000)
},
onActionSheet() {
  wx.showActionSheet({
    itemList: ['111', '222', '333', '444'], // string 最大 7 个
    alertText: '提醒',
    itemColor: '#FF0000',
    success: (result) => {
      console.log('result', result.tapIndex)
    },
    fail: (res) => {
      console.log(res)
    },
    complete: (res) => {},
  })
}

数据请求(案例)

<view>
  <view>表单实战</view>
  <!-- get -->
  <view>
    <view>获取用户信息</view>
    <view>姓名:{{ name || '-' }}</view>
    <view>身高:{{ height || '-' }}</view>
    <button type="primary" bind:tap="handleGetUserInfoById">GET</button>
  </view>
    <!-- post -->
  <view>
    <view>更新用户信息</view>
    <input 
      type="text" 
      placeholder="姓名" 
      bind:input="handleInputName"
    />
    <input 
      type="text" 
      placeholder="身高"
      bind:input="handleInputHeight"
    />
    <button type="primary" bind:tap="handleUpdateUserInfoById">POST</button>
  </view>
</view>
const { getUserInfoById, updateUserInfoById } = require('./api/index.js')

Page({
  onRequest() {
    // 原生
    // 获取用户列表
    wx.request({
      url: 'http://121.4.100.140:9091/info',
      // data: {},
      // method: 'GET',
      // timeout: 0,
      success: (result) => {
        console.log(result.data)
      },
      fail: (err) => {},
      complete: (res) => {},
    })
    // 修改用户信息
    wx.request({
      url: 'http://121.4.100.140:9091/info/15',
      data: {
        name: 'coderMonkey-1',
        height: 1001
      },
      method: 'POST',
      timeout: 60000,
      success: (result) => {
        console.log(result.data)
      },
      fail: (err) => {},
      complete: (res) => {},
    })
  },

  // 表单案例(封装的request)
  data: {
    name: '',
    height: '',
    currentName: '',
    currentHeight: ''
  },
  handleGetUserInfoById() {
    getUserInfoById(15).then(res => {
      if (res.code === 0) {
        this.setData({
          name: res.data.name,
          height: res.data.height
        })
      } else {
        wx.showToast({
          title: res.message,
          icon: 'none',
          mask: true
        })
      }
    }).catch(err => {
      console.log(err)
    })
  },
  handleUpdateUserInfoById() {
    const name = this.data.currentName
    const height = +this.data.currentHeight
    updateUserInfoById(15, { name, height }).then(res => {
      if (res.code === 0) {
        console.log('res.data', res.data)
      } else {
        wx.showToast({
          title: res.message,
          icon: 'none',
          mask: true
        })
      }
    }).catch(err => {
      console.log(err)
    })
  },
  handleInputName(e) {
    this.setData({
      currentName: e.detail.value
    })
  },
  handleInputHeight(e) {
    this.setData({
      currentHeight: e.detail.value
    })
  }
})

/http/index.js 封装 request 类

class Request {
  constructor(domain) {
    this.domain = domain
  }
  request(path, data, method) {
    wx.showLoading({ title: 'loading...' })
    return new Promise((resolve, reject) => {
      wx.request({
        url: `${this.domain}${path}`,
        method,
        data,
        timeout: 60000,
        success(res) {
          resolve(res.data)
        },
        fail(err) {
          reject(err)
        },
        complete () {
          wx.hideLoading()
        }
      })
    })
  }
  get(path, data) {
    return this.request(path, 'GET', data)
  }
  post(path, data) {
    return this.request(path, 'POST', data)
  }
}

const request = new Request('http://121.4.100.140:9091')

module.exports = {
  request
}

/api/user.js 封装接口请求

const { request } = require('../http/index.js')

const userApi = {
  // 获取所有的用户信息
  getUserInfoList() {
    return request.get('/info')
  },
  // 根据 id 获取用户信息
  getUserInfoById(id) {
    return request.get(`/info/${id}`)
  },
  // 根据 id 修改用户信息
  updateUserInfoById(id, data) {
    return request.post(`/info/${id}`, data)
  },
}

module.exports = userApi

/api/index.js

const userApi = require('./user.js')

module.exports = {
  ...userApi
}

数据存储

Page({
  // 同步缓存
  handleTap1() {
    wx.setStorageSync('token', '111')
    const token = wx.getStorageSync('token')
    wx.removeStorageSync('token')
    wx.clearStorageSync()
  },

  // 异步缓存
  handleTap2() {
    wx.setStorage({
      key: 'token',
      data: '222',
      encrypt: true,
      success(res) {
        console.log(res)
      },
      fail(res) {
        console.log(res)
      },
      complete(res) {
        console.log(res)
      }
    })

    wx.getStorage({
      key: 'token',
      encrypt: true,
      success(res) {
        console.log(res)
      },
      fail(res) {
        console.log(res)
      },
      complete(res) {
        console.log(res)
      }
    })
    wx.getStorageInfo({
      success(res) { console.log(res) }
    })

    wx.removeStorage({
      key: 'token',
      success(res) {
        console.log(res)
      },
      fail(res) {
        console.log(res)
      },
      complete(res) {
        console.log(res)
      }
    })

    wx.clearStorage({
      success(res) {
        console.log(res)
      },
      fail(res) {
        console.log(res)
      },
      complete(res) {
        console.log(res)
      }
    })
  }
})

app.js

/**
 * 生命周期
 * 全局数据、方法
 * 错误监听
 */
App({
  // 创建全局数据
  /**
   * 在其他页面使用
   * const app = getApp()
   * const userInfo = app.globalData.userInfo
   * app.globalData.userInfo.age = 999
   * app.updateUserAge(888)
   */
  globalData: {
    userInfo: wx.getStorageSync('userInfo') || null
  },
  updateUserAge(age) {
    this.globalData.userInfo.age = age
  },
  onLaunch(options) {
    console.log(this.globalData)
  }
})

app.json

{
  "entryPagePath": "pages/element/element",
  "pages": [
    "pages/element/element",
    "pages/navigate/navigate",
    "pages/request/request"
  ],
  "window": {
    "navigationBarTitleText": "learn-mp",
    "navigationBarTextStyle": "white",
    "navigationBarBackgroundColor": "#000",
    "navigationStyle": "default",
    "navigationStyle2": "custom"
  },
  "tabBar": {
    "color": "#aaa",
    "selectedColor": "#fff",
    "borderStyle": "black",
    "backgroundColor": "#000",
    "position": "bottom",
    "custom": false,
    "list": [
      {
        "pagePath": "pages/element/element",
        "text": "视图组件",
        "iconPath": "/img/index.png",
        "selectedIconPath": "/img/active-index.png"
      },
      {
        "pagePath": "pages/request/request",
        "text": "数据请求",
        "iconPath": "/img/profile.png",
        "selectedIconPath": "/img/active-profile.png"
      }
    ]
  },
  "style": "v2",
  "networkTimeout": {
    "request": 20000,
    "connectSocket": 20000,
    "downloadFile": 20000
  },
  "permission": {
    "scope.userLocation": {
      "desc": "用于给您提供更精确的服务"
    }
  },
  "sitemapLocation": "sitemap.json"
}

project.config.json | project.private.config.json

项目私有配置文件。此文件中的内容将覆盖 project.config.json 中的相同字段。项目的改动优先同步到此文件中。详见文档:https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html

sitemap.json

{
    "desc": "收录配置(关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html)",
    "rules": [
      {
        "page": "pages/index/index",
        "action": "disallow",
        "priority": 2
      },
      {
        "page": "pages/profile/profile",
        "action": "allow",
        "params": ["id"],
        "matching": "exact",
        "priority": 3
      },
      {
        "page": "*",
        "action": "allow"
      }
    ]
}
posted @   bulvbuting1  阅读(3)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示