• 小程序开发 二 (王红元)


    九、wxss

    1、页面样式的三种写法

    1)行内样式

    2)页内样式 --> 通过类选择器在当前目录的 wxss文件中设置样式

    3)全局样式 --> 在全局 app.wxss 文件中设置样式

    优先级:行内 > 页内 > 全局

    2、wxss的扩展

    尺寸单位

    • rpx(responsive pixel):可以根据屏幕宽度进行自适应。规定屏幕宽度为750rpx
    • 比如在iphone6上,屏幕宽度为375px,共有750个物理像素,则750rpx = 350px = 750物理像素,1rpx= 0.5 px = 1物理像素

    样式导入

    1)为什么要使用样式导入

    在某些情况下,我们可能会将样式分布在多个wxss文件中,方便对样式进行管理

    这个时候,我们就可以使用样式导入,让单独的wxss文件生效

    2)我们可以在一个wxss文件中导入另一个wxss文件

    • 使用@import进行导入
    • @import后面跟需要导入的外联样式的相对路径(或者绝对路径),用分号表示结束

    官方样式库

    • 为了减少开发者样式开发的工作量,小程序提供了WeUI.wxss的基本样式库

    十、wxml语法

    wxml基本格式

    • 类似于 HTML的代码:可以写成单标签,可以写成多标签
    • 必须有严格的闭合,否则会编译报错
    • 大小写敏感:class 和 Class 是不同的属性

    1、Mustache语法(一)

    // pages/wxml/test.wxml
    
    {{message}}
    {{firstName + " " + lastName}}
    {{age>=18?"成年人":"未成年人"}}
    {{nowTime}}
    
    
    
    
    后晨好帅
    
    
    // pages/wxml/test.js
    Page({
    
      /**
       * 页面的初始数据
       */
      data: {
        message: "houchen",
        firstName: "kebi",
        lastName: "brant",
        age: 20,
        nowTime: new Date().toLocaleString(),
        isActive: false
      },
      switchFontColor() {
        this.setData({
          isActive: !this.data.isActive
        })
      },
    
      /**
       * 生命周期函数--监听页面加载
       */
      onLoad(options) {
        setInterval(() => {
          this.setData({
            nowTime: new Date().toLocaleString()
          })
        })
      }
    })
    

    2、条件判断

    wx:if - wx:elif - wx:else

    houchen haoshuai
    
    优秀
    良好
    合格
    较差
    

    hidden属性,当hidden属性为true的时候,该dom元素会被隐藏

    
    

    二者之间的区别

    • hidden将一个组件隐藏起来时,该组件依然是存在的,仅仅是将组件的display属性设置为none
    • 而 wx:if , 小程序在进行渲染时,组件根本就没有创建

    如何选择

    • 如何显示和隐藏切换的频率高,那么选择使用hidden

    3、列表渲染

    基本使用

    
    
    {{index}} {{item}}
    {{index}} {{item}}
    {}}语法 -->
    {{index}} {{item}}
    

    block标签

    • 并不是一个组件,它仅仅是一个包裹元素,不会在页面中做任何渲染,只接受控制属性(wx:if wx:for)

    • 使用block标签的两个好处

      • 1)将需要进行遍历或者判断的内容进行包裹
      • 2)将遍历和判断的属性放在block标签中,不影响普通属性的阅读,提高代码的可读性

    item、inidex起名字

    默认情况下,item- index的名字是固定的

    • 但是在某些情况下,我们可能想使用其他名称
    • 或者出现多层遍历的时,名字会重复时,我们希望取别名来进行区分
    
    {{movie}}
    

    key的作用 : 为了高效的更新虚拟dom

    • 使用key时,相当于向linkedList中插入一个节点
    • 没有使用key时,相当于向ArrayList中插入一个节点

    4、模板语法 template模板

    自从可以使用自定义组件时,模板语法就不经常使用了,但是你还是要知道有这么个东西

    wxml提供模板(template),可以在模板中定义代码判断,在不同的地方调用(是一种wxml的代码复用机制)

    • 使用name属性作为模板名称,然后在 定义代码片段
    • 模板中包含的内容在么有被使用时,是不会进行任何渲染的
    
    
    
    
    

    在这里插入图片描述

    5、wxml的引入

    小程序中提供了两种引入文件的方式:import和include

    • import可以将模板写在单独的一个wxml文件中,然后引入该文件
    • 【注意】 模板文件中不能导入模板
       //绝对路径
       //相对路径
    
    • include 将公共的wxml中的内容抽取到一个文件中
    • 特点:不能导入template,wxs,但是可以进行递归导入

    十一、wxs

    1、wxs简介

    wxs(weixin script)是小程序的一套的脚本语言,结合wxml,可以构建自己的页面

    • 官方:wxs 与 javascript是不同的语言,有自己的语法,和js并不一致

    为什么要设计wxs语言呢

    • 在wxml中是不能直接调用Page/Component中定义的函数的
    • 但是某些情况下,我们希望使用函数来处理wxml中的数据(类似于vue的过滤器,此时就需要使用wxs了)

    wxs使用的限制和特点
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Rnx3AyG0-1664082303941)(小程序开发(王红元).assets/image-20220924143600614.png)]

    2、wxs的两种写法

    第一种写法就是wxs直接写在 wxl文件中
    在这里插入图片描述

    第二种写法就是wxs单独写在一个wxs文件中,然后在wxml文件中通过 wxs标签导入该文件
    在这里插入图片描述

    十二、事件

    1、常用的事件类型

    某些组件会有自己特性的事件类型

    • input 有 bindinput / bindblur / bindfocus
    • scroll-view 有bindscrolltowpper
      在这里插入图片描述

    2、事件对象的解析

    当某个事件触发时,会产生一个事件对象,并且这个对象会被传入到回调函数中,事件对象有哪些常见的属性呢?加粗样式
    在这里插入图片描述在这里插入图片描述
    touches 和 changedTouches的区别
    touches:记录当前你有几根手指在小程序上进行触摸,以及这些触摸点的信息
    changedTouches: 记录变化的触摸点的信息(比如刚开始只有一根手指在屏幕上触摸,后来又加入了一根手指,则
    touches中元素的个数为2 ,但是changedTouches中元素的个数为1)

    target 和 currentTarget的区别
    在这里插入图片描述

    3、事件参数的传递

    
    
      
        {{item}}
      
    
    

    在这里插入图片描述

    4、事件冒泡和事件捕获和catch

    catch会阻止事件的进一步传递

    十三、组件化开发

    小程序在刚开始的时候,是不支持组件化的

    • 从v1.6.3开始,小程序开始支持自定义组件开发,也让我们更加方便的在程序中使用组件化
      在这里插入图片描述

    1、如何创建一个自定义组件

    • 在当前项目的component 文件夹定义自定义组件
      在这里插入图片描述
    • 在需要使用组件的页面,引入该组件
      key:你在当前页面中使用自定义组件的标签名 value:自定义组件的路径
      在这里插入图片描述
    • 在需要使用组件的页面,使用该组件
      在这里插入图片描述

    【注意细节】

    • 因为wxml节点标签只能是小写字母、中划线和下划线的组合,所以自定义组件的标签也只能是这些字符
    • 自定义组件可以去引用其他自定义组件
    • 自定义组件所在项目的根目录名不能以 "wx-"为前缀,否则会报错
    • 如果在ap.json中声明 {“usingComponents”: { “my-cpn”: “/components/my-cpn/my-cpn” } },则全局都可以使用该组件

    2、自定义组件的样式细节

    组件内的样式对外部样式的影响

    • 组件内的class样式,只对组件内的wxml的节点生效,对于引用组件的page页面不生效
    • 组件内不能使用id选择器、属性选择器、标签选择器

    组件外的样式对组件内部样式的影响

    • 外部使用class的样式,只对外部的wxml的class生效。对组件内是不生效的
    • 外部使用了id选择器、属性选择器不会对组件内产生影响
    • 外部使用了标签选择器,会对组件内产生影响

    如何让 class 可以相互影响:设置样式的隔离级别
    在这里插入图片描述

    3、自定义组件传递事件 - 自定义事件

    1)自定义组件内部需要将事件传递出来

    //param1: 发射出去的事件名称 param2: 传递出去的参数 param3:默认就是一个空对象
    this.triggerEvent('handIncrement',{},{})
    

    在这里插入图片描述

    2)在使用组件的页面中接收传递出来的事件,并进行处理

    <my-event bind:handIncrement="handIncrement">my-event>
    

    在这里插入图片描述

    4、自定义组件练习

    代码就不粘贴了: 实现tab的切换
    在这里插入图片描述

    5、获取组件对象的方式

    1)给自定义组件添加一个ID选择器
    在这里插入图片描述
    2)通过ID选择器,获取到自定义组件对象,然后调用自定义组件对象的方法
    2)通过ID选择器,获取到自定义组件对象,然后调用自定义组件对象的方法

    6、插槽

    组件的插槽

    • 组件的插槽是为了让我们封装的组件更具有扩展性
    • 让使用者可以决定组件内部的一些内容到底展示什么

    单个插槽的使用

    
    
      
    
    

    多个插槽的使用

    1)在自定义组件wxml中申明多个插槽及其名称
    在这里插入图片描述
    2)在自定义组件js中配置允许使用多个插槽
    在这里插入图片描述
    3)在使用自定组件的地方,向插槽中替换内容时,指定插槽的名称
    【注意】我故意将替换插槽1的内容写在了第二行,页面上显示在第一行,说明多个插槽确实生效了
    在这里插入图片描述

    7、component构造器

    Component({
      //组件的使用者可以给组件传入一些数据
      properties: {
    
      },
      //定义组件内部的初始化数据
      data: {
        counter: 0
      },
      //定义组件内部的函数
      methods: {
        btnClick() {
          this.setData({
            counter: this.data.counter+1
          })
        }
      },
      // 定义组件的一些配置选项(例如:允许多插槽,设置样式的隔离方式)
      options: {
    
      },
      //外部给组件传入的额外的样式
      externalClasses: [],
      //监听properties、data中数据的改变
      //只能监听到新的变化的值,newValue
      observers: {
        counter: function(newValue) {  
          console.info(newValue);
        }
      },
    
      // -----------组件中监听生命周期函数--------------------
      //1、监听组件所在页面的生命周期
      pageLifetimes: {
        show() {
          console.info("监听组件所在页面显示出来时")
        },
        hide() {
          console.info("监听组件所在页面隐藏时")
        },
        resize() {
          console.info("监听组件所在页面调整大小时---> 用的很少")
        }
      },
    
      //2、监听组件本身的声明周期
      lifetimes: {
        created() {
          console.info("当组件被创建时")
        },
        attached() {
          console.info("当组件被添加到页面时")
        },
        ready() {
          console.info("当组件在页面中渲染完成时")
        },
        moved() {
          console.info("当组件在页面中从一个地方被移动到另一个地方 ----> 用的比较少")
        },
        detached() {
          console.info("当组件从页面中被移除时")
        }
      }
    })
    
    

    十四、网络请求

    1、基本使用

    2、网络请求封装

    1)为什么要进行网络请求的封装

    • 降低网络请求和wx.requset 的耦合度
    • 使用Promise的方式获取返回结果
    export default function request(options) {
    
      return new Promise((resolve, reject) => {
        wx.request({
          url: options.url,
          method: options.method || 'get',
          data: options.data || {},
          success: function (res) {
            resolve(res)
          },
          fail: function (err) {
            reject(err)
          }
        })
      })
    }
    
    //使用
    //2、使用封装的request函数进行网络请求
        request({
          url: 'http://127.0.0.1:8083/sayHello',
          method: "get"
        }).then(res => {
          console.info(res)
        }).catch(err => {
          console.error(err)
        })
    

    十五、小程序中展示弹窗

    1、showToast

    https://developers.weixin.qq.com/miniprogram/dev/api/ui/interaction/wx.showToast.html

    wx.showToast({
          title: '你好啊',
        })
    

    在这里插入图片描述

    2、showModal

    https://developers.weixin.qq.com/miniprogram/dev/api/ui/interaction/wx.showModal.html

    wx.showModal({
          title: "hello",
          content: "后晨好帅"
        })
    

    在这里插入图片描述

    3、showLoading

    wx.showLoading 是一直处于loading状态的,需要显示的调用wx.hiddenLoading 来隐藏loading框

    4、showActionSheet

    在这里插入图片描述

    十六、小程序中使用分享

    分享是小程序扩散的一种重要方式,小程序中有两种分享方式:

    • 点击右上角的菜单按钮,之后点击转发
    • 点击自定义的某个按钮进行转发
    
    
    
    

    十七、小程序的登录流程

    在这里插入图片描述
    上图是官网给出的小程序登录流程图

    • 调用wx.loign获取code
    • 调用ex.request发送code到我们自己的服务器(我们自己的服务器会返回一个登录态的标识,比如token)
    • 将登录态的标识token进行存储,以便下次使用
    • 请求需要携带登录态表示的接口时,携带token

    小程序登录代码

     onLaunch: function () {
        //1、先从缓存中取出token
        const token = wx.getStorageSync(TOKEN)
        if (token && token.length !== 0) {
          //已经有token,则只需要验证token是否过期
          this.check_token()
        } else {
          //没有token,则进行登录
          this.login()
        }
      },
      check_token() {
        wx.request({
          url: 'http://localhost:8080/auth',
          method: 'post',
          header: {
            token
          },
          success: (res) => {
             if(!res.data.errCode){
                //错误码不存在的时候,代表校验token成功,更新token
                wx.setStorageSync(TOKEN, res.data.token)
             } else {
               //否则代表,校验token失败,重新走登录接口
                this.login()
             }
          },
          fail: (err) => {
    
          }
        })
      },
      login() {
        wx.login({
          success: (res) => {
            //1、获取code、code的有效期只有五分钟
            const code = res.code;
            //2、将code发送给我们的服务器
            wx.request({
              url: 'http://localhost:8080/login',
              method: 'post',
              data: {
                code: code
              },
              success: (res) => {
                console.info(res)
                //3、将token保存到全局的地方
                const token = res.data.token
                wx.setStorageSync('token', token)
              }
            })
    
          }
        })
      },
    

    十八、界面跳转

    页面跳转提供两种方式进行 跳转:

    • 通过navigator组件
    • 通过wx的api

    1、navigator

    navigator 组件主要是用于页面跳转的
    在这里插入图片描述
    在这里插入图片描述

    2、跳转时数据传递 - 传递方式分析

    在界面跳转过程中,我们需要传递一些参数,应该如何完成呢?

    • 首页 -> 详情页 : 使用url中的query字段
    1)在页面跳转时设置参数
    <navigator url="/pages/about/about?name=houchen&age=18">跳转到about页面navigator>
    
    2)在跳转页面的 page对象的onload方法中通过options参数接收路径参数
    
    • 详情页返回 -> 首页: 在详情页内部拿到首页的页面对象,直接修改数据
    1)在当前页面获取到首页的页面对象
    const pages = getCurrentPages()
    const home = pages[pages.length-2]
    
    2) 调用page对象的setData
    home.setData({
    	title: 'hehehe'
    })
    

    3、通过代码进行页面跳转

    Page({
      handleSkipToAboutPage() {
        wx.redirectTo({
          url: '/pages/about/about',
        })
    
        wx.navigateBack({
          delta: 2, //返回的层级
        })
      }
    })
    

    十九、项目实践

  • 相关阅读:
    PX4模块设计之十七:ModuleBase模块
    解决Jmeter 4.x 请求到elasticsearch 中文乱码的问题
    UE4 UltraDynamicSky 天气与水体交互
    Web 安全之 Permissions Policy(权限策略)详解
    【KingFusion】如何在3D场景实现流水效果
    NVIDIA 第七届 SkyHackathon(一)环境配置
    Android在XML和代码中,同时设置背景,导致背景叠加的问题
    css h5 端弹窗时禁止底部页面滚动
    Yarn模式部署Flink集群
    leetcode day12 相同的树
  • 原文地址:https://blog.csdn.net/hc1285653662/article/details/127036699