微信小程序

本文详细介绍了微信小程序的目录结构,包括配置文件、页面文件夹、自定义组件和资源文件。还涵盖了wxml、wxss与js的区别,以及组件的生命周期管理、数据绑定、行为共享、MobX数据共享和API的Promise化等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

小程序的基本组成结构

微信小程序的目录结构通常包括以下主要部分:

  1. app.json: 整个小程序的全局配置文件,用于配置小程序的一些基本信息,如页面路径、窗口样式、tabBar、网络超时等。

  2. pages 文件夹: 用于存放小程序的页面文件,每个页面通常包括 .wxml(模板文件)、.wxss(样式文件)、.js(逻辑文件)、.json(页面配置文件)四个文件。例如,pages/index 文件夹包含小程序的首页。

  3. utils 文件夹: 可选的文件夹,用于存放一些工具类、通用函数或者封装的功能模块,以便在不同页面中复用。

  4. components 文件夹: 可选的文件夹,用于存放自定义组件,以便在不同页面中引用和复用。每个组件也包括 .wxml.wxss.js.json 四个文件。

  5. images 文件夹: 用于存放小程序中使用的图片资源,如图标、背景图等。

  6. app.js: 小程序的全局逻辑文件,通常包含小程序的生命周期函数、全局变量和全局函数。

  7. app.wxss: 小程序的全局样式文件,用于设置全局的样式、主题色等。

  8. project.config.json: 小程序项目的配置文件,包含一些项目配置信息,如开发者工具配置、插件配置等。

  9. sitemap.json: 用于配置小程序的页面索引,以便搜索引擎收录。

  10. 其他文件: 除了上述主要部分,还可以根据需要添加其他文件,如音频文件、视频文件、第三方库等。

小程序的目录结构可以根据项目的需求进行调整和扩展,但通常遵循上述的基本结构。在开发小程序时,合理的目录结构可以使代码更有组织性,便于团队协作和维护。

wxml和html的区别

html:div,  span, img,   a
对应
wxml:view, text, image, navigator
html:<a href=“#”>超链接</a>
wxml:<navigator url=" /pages/home/home"></navigator>

wxss和css区别

  1. 新增rpx尺寸单位
  2. 提供了全局样式和局部样式
  3. wxss仅支持部分css选择器
    .class和#idelement
    并集选择器、后代选择器
    ::after和::before等伪类选择器

js文件的分类

小程序中的JS文件分为三大类,分别是:

  1. app.js
    是整个小程序项目的入口文件,通过调用App()函数来启动整个小程序
  2. 页面的.js 文件
    是页面的入口文件,通过调用Page()函数来创建并运行页面
  3. 普通的.js文件
    是普通的功能模块文件,用来封装公共的函数或属性供页面使用

宿主环境

宿主环境( host environment)指的是程序运行所必须的依赖环境。例如:
Android 系统和iOS 系统是两个不同的宿主环境。Android是安卓软件的宿主环境,脱离了宿主环境的软件是没有任何意义的!

小程序的宿主环境

就是微信

小程序的启动过程

  1. 把小程序的代码包下载到本地
  2. 解析app.json 全局配置文件
  3. 执行app.js小程序入口文件,调用App()创建小程序实例
  4. 渲染小程序首页
  5. 小程序启动完成

页面的渲染过程

  1. 加载解析页面的.json配置文件
  2. 加载页面的.wxml模板和.wxss样式
  3. 执行页面的.js文件,调用Page()创建页面实例
  4. 页面渲染完成

常用的视图容器类组件

  1. view
    普通视图区域
    类似于HTML中的div,是一个块级元素常用来实现页面的布局效果
  2. scroll-view
    可滚动的视图区域
    常用来实现滚动列表效果
  3. swiper 和swiper-item
    轮播图容器组件和轮播图item组件

小程序官方把API分为了3类

  1. 事件监听API
  2. 同步API
  3. 异步API

数据绑定

使用mustach语法,跟vue很像:{{ }}

target和currentTarget区别

在这里插入图片描述
总结就是target是源头组件,
而currentTarget是触发事件的组件

事件传参

切记小程序中事件传递参数不能够直接写在方法的后面
像这种:<button bindtap="handleButtonClick(2)">点击按钮</button> 的用法就是错误的

  1. 添加一个data-*属性
<button data-num="2" bindtap="handleButtonClick">点击按钮</button>
  1. 方法中通过事件对象 e 来获取传递的值
Page({
  handleButtonClick: function(e) {
    const num = e.currentTarget.dataset.num; // 通过事件对象获取data-num的值
    console.log('传递的值是:', num); // 输出传递的值
  }
});

inputHandler可以用来处理实时接受input中的值

<input id="Add2Input" type="number" placeholder="输入数字" bindinput="inputhandler"/>

Page({
  inputhandler: function(e) {
    console.log("hello");
    console.log(e.detail.value); // 打印用户输入的内容
  },
});

页面配置和全局配置的关系

小程序中,app.json中的window节点,可以全局配置小程序中的每一个页面的窗口表现。

实现页面导航的两种方式

  1. 声明式导航
    使用<navigator>导航组件,通过点击<navigator>组件实现页面跳转
  2. 编程式导航
    调用小程序导航API,实现页面跳转

⭐️声明式导航跳转到tabBar界面

  1. 路径必须/开头
  2. open-type表示跳转的方式,必须为switchTab
<!-- 在WXML中使用switchTab实现声明式导航到TabBar页面 -->
<navigator url="/pages/index/index" open-type="switchTab">
  <view class="link">点击跳转到首页(TabBar页面)</view>
</navigator>

⭐️声明式导航跳转到非tabBar界面

  1. 路径必须/开头
  2. open-type值为navigate,可以不写
<!-- 在WXML中定义一个跳转链接 -->
<navigator url="/pages/about/about">
  <view class="link">点击跳转到关于页面</view>
</navigator>

声明式导航还可以实现后退导航

编程式导航导航跳转到tabBar界面

使用wx.switchTab()方法

// 假设你要导航到底部 TabBar 中的某个页面,例如 "pages/index/index"
wx.switchTab({
  url: '/pages/index/index' // 替换成你要跳转的页面路径
})

编程式导航跳转到非tabBar界面

使用wx.navigateTo()方法

// 在某个事件处理函数或方法中执行导航操作
wx.navigateTo({
  url: '/pages/other-page/other-page' // 替换成你要跳转的页面路径
})

开发中更推荐使用编程式导航实现后退效果

使用wx.navigateBack()方法

<view>
  <button bindtap="goBack">返回</button>
</view>

// 在页面的 JavaScript 中
goBack: function () {
  wx.navigateBack({
    delta: 1, // 返回上一个页面
  });
}

导航传参

  1. 声明式导航传参
<navigator url=“/pages/info/info?name=zs&age=20”>跳转到info页面</navigator>
  1. 编程式导航传参

使用we.navigateTo()方法跳转到其他页面的时候,也可以携带参数

wx.navigateTo({
  url: '/pages/info/info?name=zs&age=20'
});

在onLoad中接收导航参数

通过声明式或者是编程式导航传递过来的参数,都可以直接在onLoad事件中直接获取到

Page({
  onLoad: function (options) {
    // options 包含了通过 URL 传递的参数
    const param1 = options.param1;
    const param2 = options.param2;
    
    // 在这里可以使用参数进行逻辑操作
  },
  // ...
});

下拉刷新

  1. 全局开启下拉刷新
    在app.json的window节点中,将enablePullDownRefresh设置为true
  2. 局部下拉刷新
    在页面的.json配置文件中,将enablePullDownRefresh设置为true
  3. 配置下拉刷新窗口的样式
    在页面的.json配置文件中,通过backgroundColorbackgroundTextStyle来配置下拉刷新窗口的样式
  4. 监听页面的下拉刷新事件
    onPullDownRefresh()函数
  5. 停止下拉刷新的效果

下拉刷新不会自动停止

调用Wx.stopPullDownRefresh()可以实现停止刷新

上拉触底

上拉触底实现要求:组件需要足够的高

  1. 监听上拉触底
    在页面的.js文件中,通过onReachBottom()函数实现

通过在当前的.json配置文件中配置onReachBottomDistance属性来配置上拉触底的距离

展示loading效果

使用wx.showLoading({})展示loading效果
使用wx.hideLoading({})隐藏loading效果

对上拉触底进行节流处理

自定义编译模式

可以快速定位到编译后的地方,并且可以携带参数

小程序的生命周期

  1. 生命周期的分类
    应用生命周期
    页面生命周期
  2. 生命周期函数的分类
    应用生命周期函数
    onLaunch()只会全局触发一次
    onShow()小程序从后台进入前台时调用
    onHide()
    页面生命周期函数
    onLoad只调用一次
    onShow
    onReady只调用一次
    onHide
    onUnload只调用一次

wxs

wxs是微信独有的script

wxs和javascript的区别

  1. wxs有自己的数据类型

  2. wxs不支持类似于ES6及以上的语法
    不支持: let、const、解构赋值、展开运算符、箭头函数、对象属性简写、et…
    支持: var定义变量、普通function函数等类似于ES5的语法

  3. wxs遵循CommonJS语法规范

内嵌wxs脚本

wxs代码可以编写在wxml文件中的<wxs>标签内,就像Javascript 代码可以编写在html文件中的<script>标签内一样。

每一个wxs标签中都需要提供module属性,用来指定当前wxs模块名称

<!-- pages/index/index.wxml -->

<view>
  <text>{{ 2 + 3 }}</text> <!-- 内嵌JavaScript表达式 -->
  
  <wxs module="math">
    // 定义一个WXS函数
    var add = function (a, b) {
      return a + b;
    }
    
    // 导出函数
    module.exports = {
      add: add
    }
  </wxs>

  <text>{{ math.add(2, 3) }}</text> <!-- 调用内嵌WXS函数 -->
</view>

外联wxs脚本

写在以.wxs结尾的文件之中
.wxs文件一般放在utils文件夹中

<!-- pages/index/index.wxml -->

<view>
  <text>{{ utils.add(2, 3) }}</text>
</view>

定义外联wxs脚本

// utils.wxs

// 定义一个加法函数
var add = function (a, b) {
  return a + b;
}

// 导出函数,以便在WXML中使用
module.exports = {
  add: add//微信中不支持简写形式
}

引入外联wxs脚本

<!-- pages/index/index.wxml -->

<view>
  <wxs src="/path/to/external.wxs" module="externalModule"></wxs>

  <text>{{ externalModule.add(2, 3) }}</text> <!-- 调用外部WXS函数 -->
</view>

wxs的优点

  1. wxs典型的应用场景就是“过滤器”,经常配合Mustache语法进行使用
  2. 特别注意wxs中定义的函数不能作为组件的事件回调函数
  3. 还有就是wxs不能调用js中定义的函数,不能调用小程序提供的API
  4. 在IOS设备上,小程序内的WXS会比JavaScript代码快2~20倍。android设备上就差不多
<view>{{m2.toLower(country)}}</view>

自定义小组件

各个组件都应该放在根目录下的componets文件夹下

  1. 创建组件:在components文件夹下新建文件夹test,表示test组件存放位置,在test文件夹下右键选择新建componets就会自动生成所需要的文件
  2. 组件引用:分为“全局引用”和“局部引用”

局部引用:

// pages/myPage/myPage.json
{
  "usingComponents": {
    "my-component": "/components/myComponent/myComponent"
  }
}

全局引入:

// app.json
{
  "usingComponents": {
    "my-component": "/components/myComponent/myComponent"
  }
}

组件和页面的区别

  1. 组件的.json文件中需要声明“component”:true属性
  2. 组件的.js文件中调用的是Component()函数,页面调用的是Page()函数
  3. 组件的事件处理函数需要定义到methods节点中,页面直接写在Page()函数中

组件的样式隔离

  1. 默认情况下,自定义组件的样式只会对当前的组件有效
  2. 并且像app.wxss中的全局样式对自定义组件是无效的
  3. 只有class选择器才会有样式隔离,所以在组件和引用组件的页面中建议使用class选择器,不要使用id、属性、标签选择器

修改组件的样式隔离选项

在.js文件中新增如下配置:

Component({
  options: {
    styleIsolation: 'apply-shared' // 可以选择 "isolated", "apply-shared", 或 "shared"
  },
  // 组件的其他定义
})

通过styleIsolation修改组件的样式隔离选项
可选值:
"isolated"(默认值):组件样式和外部页面样式相互隔离,组件内部样式不会影响外部页面,外部页面样式也不会影响组件。
"apply-shared":组件样式会受到外部页面的影响,但外部页面样式不会受到组件的影响。
"shared":组件样式和外部页面样式会相互影响,即组件内的样式可以影响外部页面,外部页面的样式也可以影响组件。

自定义组件的数据、方法和属性

  1. data数据
    用于渲染组件模板的私有数据
  2. methids方法
    事件处理函数和自定义方法
  3. properties属性
    用来接受外界传过来的数据

data和properties没有什么太大的区别,同样可以使用setData改变properties中的值

数据监听

observers

Component({
  properties: {
    inputValue: {
      type: String,
      value: ''
    }
  },
  observers: {
    'inputValue': function (newVal, oldVal) {
      // 当 inputValue 发生变化时,会触发这个函数
      console.log('输入框的值变化了:', newVal);
      
      // 在这里可以执行其他逻辑,例如根据输入内容做搜索等操作
    }
  },
  // 组件的其他定义
})

纯数据字段

就是不用于界面渲染的data的字段

定义纯数据字段

在 Component 构造器的 options 节点中,指定 pureDataPattern 为一个正则表达式,字段名符合这个正则
表达式的字段将成为纯数据字段

Component({
  options: {
    // 指定_开头的数据字段为纯数据字段
    pureDataPattern: /^_/
  }
  data: {
  	a:true,//非纯数据字段
  	_a:true//纯数据字段
  }
})

自定义组件的生命周期

与Page()不一样,组件的生命周期需要被定义到lifetimes

created: 组件实例被创建时触发,此时组件数据 data 尚未初始化。

attached: 组件实例被附加到页面节点树时触发,可以在这里访问组件的属性和数据。

ready: 组件布局完成,可以在这里执行一些初始化工作,如请求数据、更新界面等。

moved: 组件被移动到另一个节点时触发,一般很少使用。

detached: 组件实例被销毁时触发,可以在这里释放资源、取消订阅等清理工作。

Component({
  data: {
    message: 'Hello from component!'
  },
  lifetimes: {
    created() {
      console.log('组件被创建');
    },
    attached() {
      console.log('组件被附加到页面');
    },
    ready() {
      console.log('组件已经准备就绪');
    },
    moved() {
      console.log('组件被移动');
    },
    detached() {
      console.log('组件被销毁');
    }
  }
})

组件所在页面的生命周期

show
hide
resize

这些生命周期函数需要包含在pageLifetimes节点中

插槽

<!-- custom-component.wxml -->
<view class="custom-component">
  <slot name="header"></slot>
  <view class="content">
    <!-- 默认内容 -->
    <slot></slot>
  </view>
</view>

定义了两个插槽:一个是具名插槽 “header”,另一个是默认插槽,没有指定名称。

<!-- 使用自定义组件的页面 -->
<custom-component>
  <!-- 将内容传递给名为 "header" 的插槽 -->
  <view slot="header">这是自定义头部</view>

  <!-- 默认内容会填充到默认插槽中 -->
  <view>这是默认内容</view>
</custom-component>

子组件项父组件传递信息

在子组件的代码中,可以使用 this.triggerEvent 方法触发一个自定义事件,并传递需要传递的数据

在子组件.js文件中

Component({
  methods: {
    sendDataToParent() {
      const data = { message: 'Hello from child' };
      this.triggerEvent('customEventName', data);
    }
  }
})

父组件的wxml

<child-component bind:customEventName="handleCustomEvent"></child-component>

父组件的.js文件中

Page({
  handleCustomEvent(event) {
    console.log('Received data from child:', event.detail);
    // 在这里处理子组件传递的数据
  }
})

父组件中获取子组件的实例

可在父组件里调用 this.selectComponent("id或class选择器") ,获取子组件的实例对象,从而直接访问子组
件的任意数据和方法

<!-- 子组件的 .wxml 文件 -->
<view id="child-component">
  <!-- 子组件的内容 -->
</view>

// 父组件的 .js 文件
Page({
  onReady: function () {
    // 获取子组件的实例
    const childComponent = this.selectComponent('#child-component');
    console.log(childComponent);
  }
})

小程序组件中behaviors使用

  1. behaviors 是小程序中,用于实现组件间代码共享的特性,类似于 Vue.js 中的 “mixins”
  2. 每个 behavior 可以包含一组属性、数据、生命周期函数和方法。组件引用它时,它的属性、数据和方法会被合并到组件中。
  3. 每个组件可以引用多个 behavior,behavior 也可以引用其它 behavior

创建behavior

调用Behavior(Object object)方法即可创建一个共享的 behavior 实例对象,供所有的组件使用

创建一个独立的 Behavior 文件,它通常以 .js 后缀为扩展名。在这个文件中定义你想要复用的属性、数据和方法

// myBehavior.js
const myBehavior = Behavior({
  properties: {
    myProperty: String, // 用于接收父组件传递的数据
  },
  data: {
    count: 0, // 组件内部的数据
  },
  methods: {
    increment() {
      this.setData({ count: this.data.count + 1 });
    },
  },
});

module.exports = myBehavior;

导入并使用behavior

// myComponent.js
const myBehavior = require('../../behaviors/myBehavior');

Component({
  behaviors: [myBehavior], // 引用上面创建的 Behavior
  properties: {
    // 组件的属性
  },
  data: {
    // 组件的数据
  },
  methods: {
    // 组件的方法
  },
});

安装和配置vant-weapp组件库

使用MobX实现全局数据共享

1.安装

在小程序中,使用mobx-miniprogrammobx-miniprogram-bindings实现全局数据共享
mobx-miniprogram用来创建store实例对象
mobx-miniprogram-bindings把store中的共享数据或方法,绑定到组件或页面中

注意安装mobx的相关包之后,需要删除miniprogram_npm目录,重新构建npm

2.创建 mobx的Store实例

store//根目录下新建文件夹
	store.js//新建js文件
//store.js
import {observable,action} from 'mobx-miniprogram'
export const store=observable({
	//数据字段
	numA:1,
	numB:2,
	//计算属性
	get sum(){
		return this.sumA + this.sumB
	}
	//action方法,用来修改store中的数据
	updataNum1:action(function(step){
		this.numA+=step
	})
	updataNum2:action(function(step){
		this.numB+=step
	})
})

3.将Store中的成员绑定到页面中

import {createStoreBindings} from 'mobx-miniprogram-bindings'
import {store} from '../../store/store'
Page({
	onLoad:function(){
		this.storeBindings=createStoreBindings(this,{
			store,
			fields:['numA','numB','sum'],
			action:['updateNum1']
		})
	}
	onUnload:function(){
		this.storeBindings.destroyStoreBindings()
	}
})

4.将Store中的成员绑定到组件中

import {createStoreBindings} from 'mobx-miniprogram-bindings'
import {store} from '../../store/store'
Component({
	behaviors:[storeBindingBehaviors],//通过storeBindingBehaviors来实现自动绑定
	storeBindings:{
		store,//指定要绑定的store
		fields:{
			numA:()=>store.numA,//绑定字段的第一种方式
			numB:(store)=>store.numB,//绑定字段的第二种方式
			sum:'sum'//绑定字段的第三种方式
		},
		action:{//指定要绑定的方法
			updateNum2:updateNum2
		}
	}
})

对小程序的API进行Promise化

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值