微信小程序开发

文章目录

    • 微信小程序
    • 1、项目目录
    • 2、tabBar配置
    • 3、配置页面
    • 4、页面文件介绍
    • 5、数据绑定
    • 6、双向数据绑定
    • 7、 列表循环的基础用法
    • 8、显示与隐藏
    • 9、事件汇总
    • 10、使用模板
    • 11、WXS 模块
    • 12、组件化开发
    • 13、组件传值
    • 14、全局变量globalData
    • 15、路由跳转
    • 16、小程序生命周期

微信小程序

1、项目目录

微信小程序开发_第1张图片

2、tabBar配置

在 app.json 中,windows 同级的位置,写入:

{
  "windows": {
    ...
  },
  "tabBar": {
    "color": "#909192",
    "selectedColor": "#0600B8",
    "list": [{
      "pagePath": "pages/home/home",
      "text": "首页",
      "iconPath": "images/bar/bar1_1.png",
      "selectedIconPath": "images/bar/bar1.png"
    },{
      "pagePath": "pages/menu/menu",
      "text": "菜单",
      "iconPath": "images/bar/bar2_2.png",
      "selectedIconPath": "images/bar/bar2.png"
    },{
      "pagePath": "pages/new/new",
      "text": "新品",
      "iconPath": "images/bar/bar3_3.png",
      "selectedIconPath": "images/bar/bar3.png"
    },{
      "pagePath": "pages/kefu/kefu",
      "text": "小二",
      "iconPath": "images/bar/bar4_4.png",
      "selectedIconPath": "images/bar/bar4.png"
    }]
  }
}

#pagePath  页面路径
#text      tabBar文字信息
#iconPath  tabBar图片路径
#selectedIconPath   tabBar选中的图片路径

在pages的同级目录下新建images文件,在里面新建bar文件放图片

微信小程序开发_第2张图片

3、配置页面

在app.json:

{
	"pages": [
		"pages/home/home"
    ],
    ...
}

微信小程序开发_第3张图片

4、页面文件介绍

pages 目录下,每个页面就是一个文件夹,一个页面包含wxml、wxss、js和json文件,其中:

wxml:相当于html文件
wxss:相当于css文件
#1、标签
标签分单双标签,书写格式与html完全一样,但在微信小程序里,没有div、span、p、h1-h6这些标签,它只有非常简单的两个最基本的标签:view(即:div) 与 text(即:span)。当然,还有其他经过封装的组件,我们后面会再做介绍。

#2、JavaScript
微信小程序与vue.js框架用法大致相同,同属MVVM框架,都是由数据驱动视图更新。因此,js事件和变量的书写,也会与原生JS稍有差异。

5、数据绑定

在 home.wxml 页面写入:

<view>{{msg}}view>

在 home.js 写入:

Page({
  data: {
    msg: '你好,世界'
  }
})

如此,便完成了数据绑定。

可以看到,动态变化的数据,我们统一放在data里面。这里跟vue做个区别,vue中规定组件内data必须是函数,而小程序不用,使用一个对象表示即可。

小程序中,我们要记住,凡是调用data中的数据,在wxml文件使用时,就需要加 {{}},这语法便是著名的:mustache语法,也称胡子语法。

6、双向数据绑定

#1、修改data中的数据
小程序中,使用 this.setData() 来修改data中的数据。

#2、方法绑定
一个标签需要调用一个函数(或称:方法),需要在标签上绑定事件,如绑定触摸事件(即:pc上的点击事件):

<button bindtap="tapFn">按钮</button>

然后在js中:

Page({
  data: {
    ...
  },
  tapFn(){
    // do something...
  }
})

#3、实现双向数据绑定
我们来实现双向数据绑定:

在 home.wxml 中:

<input value="{{msg}}" bindinput="iptFn"></input>
<view>{{msg}}</view>

在js中:

Page({
  data: {
    msg: '你好,世界'
  },
  // input值被修改时触发的函数
  iptFn(e){
    this.setData({
      msg: e.detail.value
    })
  }
})

7、 列表循环的基础用法

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

wx:key可以不写,但会报警告

wx:key 的值有三种写法

1、wx:key=“property” ,其中property是代表在 for 循环的 array 中 item 的某个 property,该 property 的值需要是列表中唯一的字符串或数字,且不能动态改变。类似于字典的key值

2、wx:key=“*this”, 保留关键字 *this 代表在 for 循环中的 item 本身,这种表示需要 item 本身是一个唯一的字符串或者数字

3、wx:key=“index”,代表每一项的索引

比较推荐*this

当有多个循环时,可以写wx:for-index=“inx”,wx:for-item=“items”,来区分每一个循环。

<view>
<view wx:for="{{list}}" wx:key="*this" wx:for-item="items" wx:for-index="ind">{{ind}} {{items}}
view>
view>

其中的ind为索引,items为数组每一项

8、显示与隐藏

wx:if 有更高的切换消耗,hidden有更高的初始渲染消耗

<view hidden="{{isShow}}">显示与隐藏view>

hidden与if相反,isShow的值为false的时候上面的view才会显示

  data: {
    isShow:false
  }

9、事件汇总

bindtap 点击事件
bindinput 键盘输入事件
bindconfirm 回车事件
bindfocus 输入框聚焦事件
bindblur 输入框失焦事件
bindchange 值改变事件

触摸事件
bindtouchstart 动作开始
bindtouchend 动作结束
bindtouchmove 触摸移动
bindtouchcancel 触摸动作被打断

表单重置事件

<form  bindreset="formReset" >
<button type="warn" form-type="reset">重置button>
form>

表单提交事件

<form  bindsubmit="formSubmit"" >
<button type="primary" form-type="submit"">提交button>
form>

10、使用模板

类似于vue的插槽
在pages > home 下新建文件夹 templates ,然后在里面新建test.wxml :


<template name="box1">
<view bindtap="btnFn">box1 :{{content}}view>
template>

<template name="box2">
<view bindtap="btnFn">box2 :{{content}}view>
template>

<template name="box3">
<view bindtap="btnFn">box3 :{{content}}view>
template>

在 home.wxml中:

<import src="./templates/test"  />
<template is="box3" data="{{content: txt}}">template>

这里通过import标签引入模板,template标签使用模板,is属性指定对应的模板,data属性传值

在 home.js中:

Page({
  data: {
    txt: 999
  },
  btnFn() {
    console.log('打印');
  }
})

以上在需要使用模板的 home.js 里面定义了内容txt 和方法btnFn

11、WXS 模块

WXS 代码可以编写在 wxml 文件中的 标签内,或以 .wxs 为后缀名的文件内。

模块
每一个 .wxs 文件和 标签都是一个单独的模块。

每个模块都有自己独立的作用域。即在一个模块里面定义的变量与函数,默认为私有的,对其他模块不可见。

一个模块要想对外暴露其内部的私有变量与函数,只能通过 module.exports 实现。

wxs写法1:
在 pages > home 文件夹下新建 tools.wxs 文件,并定义方法fn,通过module.exports 导出

function fn (a,b){
  return a+b
}
module.exports ={
  fn:fn
}

home.wxml 中 通过src属性引入模块,module属性定义当前模块名称

<wxs src="./tools.wxs" module="foo">wxs>
<view>{{foo.fn(1,4)}}view>

写法二:
在home.wxml 中:

<wxs module="koo">
function add (val){
  var a = val + 1
  return a
}
module.exports={
  add:add
}
wxs>

<view >{{koo.add(0)}}view>

12、组件化开发

  1. 在app.json 中创建组件

和创建页面一样,只是把pages改成components
新增 “components/product/product”

{
    "pages": [
        "pages/home/home",
        "components/product/product"
    ],
    .....
 }
  1. 组件中写入结构样式,并声明

在product.wxml中:
写好页面结构

<view class="product_list">
  <view wx:for="{{showArr}}" wx:key="*this" class="product_list_box">
    <image class="img"  src="{{item.imgSrc}}">image>
    <view class="txt">{{item.imgTxt}}view>
  view>
view>

在product.js中:
写好数据,图片我放在images文件下的home文件

// 注意注意:这里的Page()方法改成了Component()方法
Component({
  data: {
    showArr: [{
        imgTxt: "卡布奇诺",
        imgSrc:"../../images/home/logo1.jpg"
      },
      {
        imgTxt: "白咖啡",
        imgSrc:"../../images/home/logo2.jpeg"
      },   
      {
        imgTxt: "拿铁咖啡",
        imgSrc:"../../images/home/logo3.jpeg"
      }  
    ]
  },
})

在product.wxss中:
写好样式


.product_list{
  display: flex;
  padding: 20rpx 2%;
  justify-content: space-between;
  flex-wrap: wrap;
}

.product_list_box{
  width: 49%;
  box-shadow: 0 0 6rpx #ccc;
  border-radius: 10rpx;
  overflow: hidden;
  margin-bottom: 20rpx;
}

.product_list_box .img{
  width: 100%;
  display: block;
  height: 280rpx;
}

.product_list_box .txt{
  height: 50rpx;
  line-height: 50rpx;
  text-align: center;
  background-color: #eee;
}

在product.json中:
声明组件 “component”: true

{
  "usingComponents": {},
  "component": true
}
  1. 调用组件

在home.json 中:
注册组件

{
  "usingComponents": {
    "product-block": "/components/product/product"
  }
}

在home.wxml 中 :
引入组件

<product-block />
或:
<product-block>product-block>

13、组件传值

考虑到组件需要复用,那么数据应该在父组件传过来。

父传子
我们将该组件的数据迁移到父组件 Home.js 中,然后通过父传子传过来:
父组件
在home.wxml :

<product-block  showArr="{{showArr}}" >product-block>

在home.js :

Page({
  data: {
    showArr: [{
        imgTxt: "卡布奇诺",
        imgSrc: "../../images/home/logo1.jpg"
      },
      {
        imgTxt: "白咖啡",
        imgSrc: "../../images/home/logo2.jpeg"
      },
      {
        imgTxt: "拿铁咖啡",
        imgSrc: "../../images/home/logo3.jpeg"
      }

    ]
  }
  })

子组件

在product.js :

Component({
//通过properties接收父组件传过来的值,类似于vue的props
  properties:{
    showArr:{
      //定义数据类型
      type:Array,
      //定义数据的初始值
      value:[]
    }
  }
})

子传父
我们可以通过子组件的自定义事件this.triggerEvent ,点击product 组件中的任意一项,来触发父组件的事件。
子组件
在product.wxml :

<view class="product_list">
  <view wx:for="{{showArr}}" wx:key="*this" class="product_list_box" bindtap="productFn">
    <image class="img"  src="{{item.imgSrc}}">image>
    <view class="ve">{{item.imgTxt}}view>
  view>
view>

在product.js :

Component({
//组件中写方法需要写上methods
   methods:{
     productFn(){
     //子传父通过triggerEvent, 类似vue的$emit
       this.triggerEvent('eventFn','触发了事件')
     }
    }
  })

父组件
在home.wxml :


<product-block  showArr="{{showArr}}" bind:eventFn="homeEvent">product-block>

在home.js :

Page({
  ...,
  // 页面无需写methods
  homeEvent(val) {
    console.log(val.detail);
  }
})

点击之后,控制台打印了 :触发了事件。

14、全局变量globalData

定义全局变量globalData,在app.js中:

// app.js
App({
  globalData: {
    name: '张三'
  }
})

调用的方法有:

【方法一(推荐)】通过调用app获取,需要在第一行声明app的实例

const app = getApp()
Page({
  onLoad: function () {
    console.log(app.globalData.name);
  },
})

【方法二】直接通过getApp().globalData获取,不需要写const app = getApp()实例

Page({
  onLoad: function () {
      console.log(getApp().globalData.name);
  },
})

修改global的方法【借助方法一】:

app.globalData.name = "李四";

15、路由跳转

1、跳转到非tabBar 的页面(js)

wx.navigateTo({
    url: '/pages/nav/nav'
})

// url携带参数的形式:
wx.navigateTo({
    url: '/pages/nav/nav?pid=123',
})

// 如何获取参数?
onLoad: function (options) {
    console.log(options.pid)		// 123
},
    
// 携带复杂参数的形式
 wx.navigateTo({
      url: '/pages/nav/nav?pid=123',
      //跳转成功,通过eventChannel向被打开页面传送数据
      success:function(res){
          res.eventChannel.emit('pageInfo',{name:'用户'})
      }
    })

// 接收复杂参数的形式
onLoad: function (options) {
    console.log(options.pid); //123
    const channel = this.getOpenerEventChannel() 
    //使用getOpenerEventChannel()方法,通过.on方法获取
    channel.on('pageInfo',function(data){
      console.log(data); //{name: "用户"}
    })
},
    
// 当前页反向发射数据到上一页
onLoad: function (options) {
     const channel = this.getOpenerEventChannel() 
     //使用getOpenerEventChannel()方法,通过.emit方法触发
     channel.emit('fanxiang',{arr:[11,22,33]})
},
    
// 上一页接收反向发射的数据
wx.navigateTo({
  url: '/pages/nav/nav?pid=123',
      // events中写反向发射的函数
  events:{
        fanxiang(res){
          console.log(res.arr); //[11,22,33]
        }
      }
})

2、跳转到非tabbar页面(wxml)

<navigator url="/pages/logs/logs">navigator>

3、跳转到tabbar页面(js)

wx.switchTab({
    url: '/pages/user/user'
})

16、小程序生命周期

页面生命周期
onLoad > onShow > onReady >onHide > onShow > onUnload
组件生命周期

Component({
  lifetimes: {
    created	: function() {
      // 在组件实例刚刚被创建时执行	1.6.3版本以上
    },
    attached: function() {
      // 在组件实例进入页面节点树时执行  1.6.3版本以上
    },
    detached: function() {
      // 在组件实例被从页面节点树移除时执行  1.6.3版本以上
    },
    ready: function() {
      // 在组件在视图层布局完成后执行	1.6.3版本以上
    },
    moved: function() {
      // 在在组件实例被移动到节点树另一个位置时执行	 1.6.3版本以上
    }
   
    
  },
   // 以下是旧式的定义方式,可以保持对 <2.2.3 版本基础库的兼容
  attached: function() {
    // 在组件实例进入页面节点树时执行
  },
  detached: function() {
    // 在组件实例被从页面节点树移除时执行
  },
  // ...
})

组件所在页面的生命周期:

Component({
  pageLifetimes: {
    show: function() {
      // 页面被展示  2.2.3版本以上
    },
    hide: function() {
      // 页面被隐藏  2.2.3版本以上
    },
    resize: function(size) {
      // 页面尺寸变化  2.4.0版本以上
    }
  }
})

你可能感兴趣的:(微信小程序,小程序,前端)