首页 > 其他分享 >17、移动端

17、移动端

时间:2023-05-18 15:44:50浏览次数:37  
标签:git 17 res 程序 事件 移动 data 页面

前端:
客户前端,客户将数据发给后台,后台将数据存到数据库
管理前端,管理向后台索要数据,后台从数据库查找数据

五、AI编程助手
1、codeium,https://codeium.com/playground
2、codegeex,https://codegeex.cn/zh-CN/playground
3、chatGPT,http://chat.178le.net/index
(1)2022年11月30日,美国OpenAI发布的聊天机器人程序
(2)全名:Chat Generative Pre-trained Transformer
(3)汉译:人工智能技术驱动的自然语言处理工具
(4)直译:聊天生成的、经过训练的、改革者
(5)Copilot Hub:基于ChatGPT创建个人的知识库AI,app.copilothub.co
  
 









一、移动端基础
1、移动端的长度单位
(1)%,相对于父元素的尺寸
(2)em,相对于父字体大小
(3)rem,相对于根字体大小
(4)vw,viewpoint width,视窗宽度,1vw等于视窗宽度的1%,如width: calc(100vw - 260px);font-size: 5vw;
(5)vh,viewpoint height,视窗高度,1vh等于视窗高度的1%,如height: calc(100vh - 260px);font-size: 5vh;
(6)vmin:vw和vh中较小的那个。做移动页面开发时,如果使用 vw、wh 设置字体大小(比如 font-size: 5vw),在竖屏和横屏状态下显示的字体大小是不一样的。
(7)vmax:vw和vh中较大的那个。vmin或vmax,是当前vw和vh中,较小或较大的那个,用vmin或vmax,使得文字大小在横竖屏下保持一致
附、媒体查询
  @media screen and (min-width: 360px) and (max-width: 700px){
    padding-left: 15%;
  }
2、接到新(或别人的)项目时,从以下几个方面入手,
(1)根据全图,把握项目整体布局,background、margin、padding及1,2,3层,font-family、font-size1,2,3种
(2)根据全图,把握项目整体逻辑,比如跳转、本地存储的方式(vuex或localStorage)、静态数据的来源(设计稿或后台)
(3)代码过程,单图主体-写代码-单图注释-完善代码,重复此步骤
(4)联调
附、左右居中(换行也可以)
  <div class="center">
    <div><img src=""/></div>
    <div></div>
    <div></div>
    <div></div>
  </div>
  .center{
    display: flex;
    flex-direction: column;
    //align-item: center;//换行不居中
    text-align: center;//换行居中
  }
3、问题与解决
(1)iPhone12pro max,跳到新网页,新网页的位置没到顶,
原因:跳转前的网页没到顶,浏览器把前网页的位置用在后网页上;
解决:document.body.scrollTop=0;document.documentElement.scrollTop=0;


三、uniapp跨端框架 
来源,https://gitee.com/dcloud/uni-app/tags?page=60
来源,https://uniapp.dcloud.net.cn/history.html
1、uniapp的产生背景
(1)2012年,DCloud开始研发小程序技术,推出了HBuilder开发工具
(2)2015年,DCloud商用了小程序技术,命名“流应用”,并将该技术标准捐给工信部,同时推进各家流量巨头接入该标准,众多开发者用该标准为“流应用”平台提供应用,供用户下载
(3)2015年9月,DCloud推进微信团队开展小程序业务
(4)2016年初,微信团队决定上线微信小程序业务,订制了自己的标准,随后包括手机厂商在内的各大流量巨头,陆续上线类似微信小程序的业务
(5)DCloud用自己的开发工具HBuilder、自己的开发框架uni-app为开发者抹平“各平台”的差异,让“一套代码”在“各APP”的客户端运行,由标准的提供者转向标准的汇总者
(6)微信开发工具开发的小程序只能在微信上运行,HBuilder用uni-app开发的小程序能在所有应用上运行,https://uniapp.dcloud.net.cn/
2、uni-app的版本发布
(1)2018年8月,uni-app1.0.0 版本发布,
(2)2021年9月,uni-app2.0.0 版本发布,
(3)2023年1月,uni-app3.0.0 版本发布,
3、uni-app的相关内容
(1)uni小程序SDK,是DCloud开发的原生SDK,提供Android、iOS两个版本,需要集成到原生工程中,使APP的服务端能运行用uni-app框架开发的小程序
(2)uniCloud,基于serverless的云开发平台,为开发者提供免费服务器,由DCloud、阿里云、腾讯云三者联合实现
(3)Uni,统一的,读you ni
(4)SDK,软件开发工具包 
4、与“uniapp跨端框架”相似内容,混合类解决方案(Hybrid、RN、 flutter等)



四、vant-ui相关
1、<input type="value">
(1)button,定义可点击按钮(多数情况下,用于通过 JavaScript 启动脚本)
(2)checkbox,定义复选框
(3)file,定义输入字段和 "浏览"按钮,供文件上传
(4)hidden,定义隐藏的输入字段
(5)image,定义图像形式的提交按钮
(6)password,定义密码字段,该字段中的字符被掩码
(7)radio,定义单选按钮
(8)reset,定义重置按钮,重置按钮会清除表单中的所有数据
(9)submit,定义提交按钮,提交按钮会把表单数据发送到服务器
(10)text,定义单行的输入字段,用户可在其中输入文本,默认宽度为 20 个字符
2、深度选择器
当<style scoped>只作用于当前组件中的元素,可采用下列方式影响到子组件
(1)全局样式
<style>
  .wrap .child {
    color: red;
  }
</style>
(2)本页样式 >>> 
<style scoped>
  .wrap >>> .child {
    color: red;
  }
</style>
(3)本页样式 /deep/
<style scoped>
  .wrap /deep/ .child {
    color: red;
  }
</style>
3、vant-ui动态内容
(1)toast 轻提示,没有遮罩,页面居中显示,无样式变化,3秒后自动消失
(2)notify 消息提示,没有遮罩,页面顶部显示,有样式变化,3秒后自动消失
(3)NoticeBar 通知栏,没有遮罩,固定位置显示,有样式变化,不消失
(4)Popover 气泡弹出框,没有遮罩,常用于点击处显示,常用于下拉选项
(5)overlay 遮罩层,全屏罩住
(6)popup 弹出层,有遮罩,常用触底显示,确认后消失,常用于省市县、日期选择
(7)dialog 弹出框,有遮罩,常用居中显示,确认后消失
4、van-field
(1)输入框,正常
(2)文本框,type="textarea"
(3)下拉框的逻辑
  输入框禁用,右侧添加三角,
  点击事件让下方气泡出现、传出序号、计算-从总数据中找出的相关数据-成下拉选项,
  点击事件从自身数据中找出的相关数据-成为下拉选项,气泡出现
  点击确定时,给对应的v-model赋值,气泡消失
(4)其它,用插槽input,
  自定义输入框,使用此插槽后,与输入框相关的属性和事件将失效
  在Form组件进行表单校验时,会使用input插槽中子组件的value,而不是Field组件的value
(5)<van-uploader/>的部分属性
  capture,图片选取模式,可选值为camera,直接调起摄像头
  after-read,文件读取完成后的回调函数
  before-read,文件读取前的回调函数,返回false可终止文件读取,支持返回Promise
4、Rule数据结构,只有一个对象项的数组
(1)required,是否为必选字段,boolean
(2)message,错误提示文案
(3)trigger,本项规则的触发时机,可选值为onChange、onBlur
(4)formatter,格式化函数,将表单项的值转换后,再用“pattern”或“validator”进行校验
(5)pattern,通过正则表达式进行校验,返回值为false时,红色的message出现在输入框的下方
(6)validator,通过函数进行校验,返回值为false时,机制让红色的message出现在输入框的下方;
  返回值为promise实例时,机制向其注入resolve、reject,在reject里让红色的message出现在输入框的下方
  validator:function(rule, val, callback) {
    return new Promise(function(resolve, reject) {
      setTimeout(function() {
        const dataNum = Date.now()
        if (dataNum % 2 === 0) {
          resolve('成功')
        } else {
          reject('失败')
        }
      }, 2000)
    })
  }
5、插槽input示例
(1)html部分
  <van-form @submit="beforeSubmit" ref="form">
    <template v-for="(item,idx) in formList">
      <div class="sign-form" :key="idx" v-if="item.inputType == 0">
        <van-field name="name" :rules="[{ validator: valiFormData, message: '请输入正确内容',index:idx }]" show-word-limit
              :label="item.topicName" v-model="formData[idx]" :placeholder="'请输入'+item.topicName" :maxlength="item.numLimit" />
      </div>
      <div class="sign-form" :key="idx" v-if="item.inputType == 1">
        <van-field rows="4" :rules="[{ validator: valiFormData, message: '请输入正确内容',index:idx }]" autosize
              v-model="formData[idx]" :label="item.topicName" type="textarea" show-word-limit />
      </div>
      <div class="sign-form" :key="idx" v-if="item.inputType == 2">
        <van-field :label="item.topicName" v-model="formData[idx]" right-icon="arrow-down" readonly placeholder="请选择"
              :rules="[{ validator: valiFormData, message: '请输入正确内容',index:idx }]" @click="changeCol(idx)" />
      </div>
      <div class="sign-form" :key="idx" v-if="item.inputType == 3 && item.isCheckbox == 0">
        <van-field :label="item.topicName" :rules="[{ validator: valiFormData, message: '请输入正确内容',index:idx }]">
          <template #input>
            <van-radio-group v-model="formData[idx]" direction="horizontal" class="hor-style">
              <van-radio v-for="(v,k) in JSON.parse(item.optionInfo)" :name="v.option" :key="k">{{v.option}}</van-radio>
            </van-radio-group>
          </template>
        </van-field>
      </div>
      <div class="sign-form" :key="idx" v-if="item.inputType == 3 && item.isCheckbox == 1">
        <van-field :label="item.topicName" :rules="[{ validator: valiFormData, message: '请输入正确内容',index:idx }]">
          <template #input>
            <van-checkbox-group v-model="formData[idx]" :max="item.selectLimitMax ? item.selectLimitMax : 0" direction="horizontal">
              <van-checkbox v-for="(value,key) in JSON.parse(item.optionInfo)" :name="value.option" shape="square" :key="key">{{value.option}}</van-checkbox>
            </van-checkbox-group>
          </template>
        </van-field>
      </div>
      <div class="sign-form" :key="idx" v-if="item.inputType == 4">
        <div class="van-form_card">
          <div class="field__label">{{item.topicName}}</div>
          <div class="field__desc">支持“图片”扩展名:png、gif、jpeg、pcx、psd、tiff</div>
        </div>
        <van-field name="name" type="hidden" :rules="[{ validator: valiFormData, message: '请输入正确内容',index:idx }]" v-model="formData[idx]">
          <template #input>
            <div class="upload-preview">
              <van-image v-if="formData[idx]" width="4rem" height="3rem" fit="contain" :src="formData[idx]" />
              <van-uploader :before-read="uploadFile" accept="image/png,image/gif,image/jpeg,image/pcx,image/psd,image/tiff" :name="idx">
                <van-icon name="plus" />
              </van-uploader>
            </div>
          </template>
        </van-field>
      </div>
      <div class="sign-form" :key="idx" v-if="item.inputType == 5">
        <div class="van-form_card">
          <div class="field__label">{{item.topicName}}</div>
          <div class="field__desc">支持“视频”扩展名:avi、MP4、rmvb</div>
        </div>
        <van-field name="name" type="hidden" :rules="[{ validator: valiFormData, message: '请输入正确内容',index:idx }]" v-model="formData[idx]">
          <template #input>
            <div class="flex-col">
              <div class="video-upload" v-if="showUpload">
                <span>视频上传中...</span>
                <van-progress :show-pivot="false" :percentage="videoUploadPercent" />
              </div>
              <span class="link" v-if="formData[idx]" @click="href(idx)">{{videoName[idx]}}</span>
              <van-uploader :before-read="uploadVideo" accept="*" v-if="!showUpload" :name="idx">
                <van-button icon="plus" type="primary">上传视频</van-button>
              </van-uploader>
            </div>
          </template>
        </van-field>
      </div>
      <div class="sign-form" :key="idx" v-if="item.inputType == 6">
        <div class="van-form_card">
          <div class="field__label">{{item.topicName}}</div>
          <div class="field__desc">支持“文件”扩展名:doc、docx、txt、pdf、pptx、ppt、xlsx、xls</div>
        </div>
        <van-field name="name" type="hidden" :rules="[{ validator: valiFormData, message: '请选择',index:idx }]" v-model="formData[idx]">
          <template #input>
            <div class="flex-col">
              <span class="link" v-if="formData[idx]" @click="href(idx)">{{formData[idx]}}</span>
              <van-uploader :before-read="uploadFile" accept=".doc, .docx, .txt, .pdf, .pptx, .ppt, .xlsx, .xls" :name="idx">
                <van-button icon="plus" type="primary">上传文档</van-button>
              </van-uploader>
            </div>
          </template>
        </van-field>
      </div>
      <div class="sign-form" :key="idx" v-if="item.inputType == 7">
        <van-field readonly @click="clickDatePicker(idx)" name="name" :rules="[{ validator: valiFormData, message: '请选择日期',index:idx }]"
              :label="item.topicName" v-model="formData[idx]" :placeholder="'请选择'+item.topicName" />
        <van-popup v-model="showDatePicker" position="bottom">
          <van-picker
                show-toolbar
                title="选择日期"
                :columns="dateCol"
                @cancel="showDatePicker = false"
                @confirm="dateConfirm" />
        </van-popup>
        <!-- van-popup默认在兄级加蒙层van-overlay,若没有出现,可能有人在项目的全局给清除了 -->
      </div>
    </template>
    <div class="vt-foot ">
      <van-button :loading="loading" loading-text="保存中..." native-type="submit" block color="#fdb235">提交</van-button>
      <!-- native-type,原生button标签的type属性,表单内点击此按钮,自动触发表单的onsubmit事件 -->
      <!-- loading,设置按钮为加载状态,加载状态下默认会隐藏按钮文字 -->
      <!-- loading-text,设置加载状态下的文字 -->
      <!-- confirm函数会弹出一个带有确定和取消按钮的对话框,点击确定返回true,点击取消返回false -->
      <!-- alert函数只有一个确定按钮,点击确定后对话框消失,没有返回值 -->
    </div>
  </van-form>
(2)js部分
A、上传图片
  uploadFile(file, detail) {
    let formData = new FormData();
    formData.append('file', file);
    axios.post(this.$upload, formData, {
        'Content-Type': 'multipart/form-data'
      })
      .then(res => {
        if (res.data && res.data.code === 10000) {
          this.formData[detail.name] = res.data.data;
          let temp = res.data.data;
          this.formData.splice(detail.name, 1, temp);
        } else {
          this.$dialog.alert({
              title: '提示',
              message: '上传文件失败',
              theme: 'round-button',
            })
            .then(() => {
              // on close
            });
        }
      })
  },
B、上传视频
来源,https://help.aliyun.com/document_detail/383952.html
import OSS from "ali-oss";
// 开放存储服务(OpenStorageService,简称OSS),是阿里云对外提供的海量,安全,低成本,高可靠的云存储服务。
// 用户可以通过简单的API(REST方式的接口),在任何时间、任何地点、任何互联网设备上进行数据上传和下载。 
  <van-uploader accept="*" v-if="!showUpload"  :name="idx"  :before-read="uploadVideo">
    <van-button icon="plus" type="primary">上传视频</van-button>
  </van-uploader>
  uploadVideo(file, detail) {
    let type = file.name.substring(file.name.lastIndexOf(".") + 1)
      .toLowerCase()
    if (this.videoType.indexOf(type) < 0 || file.type.indexOf("video") < 0) {
      this.$dialog.alert({
        title: '提示',
        message: '仅支持 .avi, .mp4, .rmvb, .mov 格式的视频',
        theme: 'round-button',
      });
      return;
    }
    let max = 1024 * 1024 * 1024;
    if (file.size > max) {
      this.$dialog.alert({
          title: '提示',
          message: '上传视频大小不能超过 1G!',
          theme: 'round-button',
        })
        .then(() => {});
      return;
    }
    myRequest({
        tokenName: "ios",
      })
      .then(data => {
        let client = new OSS({
          region: "oss-cn-beijing",
          accessKeyId: data.data.data.accessKeyId,
          accessKeySecret: data.data.data.accessKeySecret,
          bucket: data.data.data.bucketName,
          stsToken: data.data.data.securityToken,
        });
        const suffix = file.name.substr(file.name.indexOf("."));
        let fileUrl = `test/${new Date().getTime()}${suffix}`;
        client
          .multipartUpload(fileUrl, file, {
            progress: (p) => {
              this.videoUploadPercent = Math.round(p * 100);
              this.showUpload = true;
            },
            partSize: 102400,
          })
          .then((res) => {
            this.showUpload = false;
            this.videoName[detail.name] = res.name;
            let url = res.res.requestUrls[0];
            this.formData[detail.name] = url.substring(0, url.indexOf("?"));
            let temp = this.formData[detail.name];
            this.formData.splice(detail.name, 1, temp);

          })
          .catch((err) => {
            this.showUpload = false;
            console.log(err);
            this.$dialog.alert({
              title: '提示',
              message: '上传失败',
              theme: 'round-button',
            })
          });
      })
  }

  
  








二、微信小程序-账号与代码管理
1、微信公众平台,https://mp.weixin.qq.com/
(1)账号分类(四种),服务号(解答用户提问,每月可群发4次)、订阅号(向用户提供资讯,每天可群发1次)、小程序(免关注,免订阅,扫码即用,用完即退)、企业微信(原企业号,用于企业办公管理)
(2)注册,小程序-测试号-游戏号&其它号的注册流程,公众平台-小程序图标(查看详情)-前往注册-立即申请-扫码(即可获得游戏号&其它号)
(3)注册,小程序-普通号-游戏号/其它号的注册流程,公众平台-小程序图标(查看详情)-前往注册-注册(账号信息)-邮箱激活-信息登记-添加类目-各种服务/工具/体育/游戏
(4)登录,APP扫描公众平台的二维码,选择其中一个账号登录
(5)开发,小程序-开发文档,https://developers.weixin.qq.com/miniprogram/dev/framework/
(6)开发,小程序-开发工具,https://developers.weixin.qq.com/miniprogram/dev/devtools/download.html
2、账号,
(1)小程序普通号
  AppID(小程序ID),wx209859
  原始ID,gh_9b058
(2)小程序git账户
  用户名:1371
  密码:4195
(3)小程序域名
  服务器域名(第三方数据库的数据)
  业务域名(自己数据库的数据)
(4)小程序测试号
  AppID(小程序ID),wxbdb0903
  AppSecret(小程序密钥),d0b0452d67d04
(5)小游戏测试号
  AppID(小程序ID),wxad135a
  AppSecret(小程序密钥),2fd7568502
3、项目,https://git.weixin.qq.com
(1)创建项目,项目(组)-创建项目(组),https://git.weixin.qq.com/138/xiau1.git    
(2)项目下载与上传,
  ====项目为空时,会有以下内容
  项目初始化git命令行
  ====以下,git全局设置
  git config --global user.name  "Z_北京码农_钱成"
  git config --global user.email "[email protected]"
  ====以下,创建一个新的版本库(用命令克隆-线上版本库的项目,进行开发,推送)
  git clone https://git.weixin.qq.com/138/xiau1.git(连接远程、克隆)
  cd xiangmuzu1
  touch README.md
  git add README.md
  git commit -m "add README"
  git push -u origin master(推送到远程master分支)
  ====以下,现有的文件夹或Git版本库(用现有的文件夹或下载的版本库文件夹-与-线上版本库的项目-关联,进行开发,推送。如现有的文件夹里没有分支,只能推送到master分支)
  cd existing_folder
  git init
  git remote add origin https://git.weixin.qq.com/138/xiau1.git(连接远程)
  git add .
  git commit -m "add README"
  git push -u origin master(推送到远程master分支)
(3)代码管理       
  开发文档,开发-工具-开发辅助-微信开发者·代码管理   
  开发工具,工具-微信开发者·代码管理
  删除仓库,管理后台(https://git.weixin.qq.com/)-项目-您的项目-XXXXX-设置-高级设置-仓库设置-删除项目
  删除仓库,管理后台(https://git.weixin.qq.com/13/path2)-设置-高级设置-仓库设置-删除项目
  删除项目组,管理后台(https://git.weixin.qq.com/)-项目组-XXXXX-设置-删除。内置的项目组无法删除
(4)版本管理,
  开发工具-上传
  微信公众平台-登录微信小程序-管理-版本管理-开发版本/发布

三、微信小程序-目录结构
来源,开发-指南-目录结构
来源,https://developers.weixin.qq.com/miniprogram/dev/framework/structure.html
1、一个小程序主体部分由三个文件组成,必须放在项目的根目录
(1)app.js,小程序全局逻辑
(2)app.json,小程序全局配置
(3)app.wxss,小程序全局样式表
2、一个小程序页面由四个文件组成
(1).js,页面逻辑
(2).wxml,页面结构
(3).json,页面配置
(4).wxss,页面样式表

四、微信小程序-框架
来源,开发-指南-小程序框架
来源,https://developers.weixin.qq.com/miniprogram/dev/framework/MINA.html
1、框架
(1)介绍
  框架,在视图层-与-逻辑层间提供了数据传输-和-事件系统,让开发者能够专注于数据与逻辑
  页面管理,框架管理页面路由,做到无缝切换,给以生命周期,开发者将页面的数据、方法、生命周期函数注册到框架中即可
  数据绑定,让数据与视图保持同步
  基础组件
  丰富的API
(2)场景值,描述用户进入小程序的路径
(3)逻辑层,介绍、注册小程序、注册页面、页面生命周期、页面路由(页面栈表现、触发时机)、模块化、API(事件监听、同步、异步、异步返回Promise、云开发)
(4)视图层,介绍、WXML、WXSS样式、WXS脚本语言、事件系统(介绍、WXS响应事件)、简易双向绑定、基础组件、获取界面上的节点信息、响应显示区域变化、分栏模式、动画、初始渲染缓存
2、事件系统,
(1)什么是事件
  事件是视图层到逻辑层的通讯方式
  事件可以将用户的行为反馈到逻辑层进行处理
  事件可以绑定在组件上,当达到触发事件,就会执行逻辑层中对应的事件处理函数
  事件对象可以携带额外信息,如id,dataset,touches
(2)事件的使用方式,在组件中绑定一个事件处理函数
  示例一:
  <view id="tapTest" data-hi="Weixin" bindtap="tapName"> Click me! </view>
  Page({
    tapName: function(event) {
      console.log(event)
    }
  })
  示例二:
  <wxs module="wxs" src="./test.wxs"></wxs>
  <view id="tapTest" data-hi="Weixin" bindtap="{{wxs.tapName}}"> 绑定的WXS函数必须用{{}}括起来 </view>
  以下test.wxs
  function tapName(event, ownerInstance) {
    console.log('tap Weixin', JSON.stringify(event))
  }
  module.exports = {
    tapName: tapName
  }
(3)事件捕获与冒泡,先捕获后冒泡
  冒泡从里向外
  bind,绑定事件,向上冒泡,后可以紧跟一个冒号,其含义不变,如bind:tap
  catch,绑定事件,阻止向上冒泡
  mut-bind,绑定事件,向上冒泡,与上级mut-bind“互斥”的,上级mut-bind不会被触发,上级的其它绑定依然会触发
  捕获从外向里
  capture-bind,捕获
  capture-catch,中断捕获、取消冒泡
  以下,冒泡与阻止冒泡,点击inner view会先后调用handleTap3和handleTap2
  <view id="outer" bindtap="handleTap1">
    outer view
    <view id="middle" catchtap="handleTap2">
      middle view
      <view id="inner" bindtap="handleTap3">
        inner view
      </view>
    </view>
  </view>
  以下,互斥事件,点击inner view会先后调用handleTap3和handleTap2,点击middle view会调用handleTap2和handleTap1
  <view id="outer" mut-bind:tap="handleTap1">
    outer view
    <view id="middle" bindtap="handleTap2">
      middle view
      <view id="inner" mut-bind:tap="handleTap3">
        inner view
      </view>
    </view>
  </view>
  以下,事件的捕获阶段,点击inner view会先后调用handleTap2、handleTap4、handleTap3、handleTap1
  <view id="outer" bind:touchstart="handleTap1" capture-bind:touchstart="handleTap2">
    outer view
    <view id="inner" bind:touchstart="handleTap3" capture-bind:touchstart="handleTap4">
      inner view
    </view>
  </view>
  如果将上面代码中的第一个capture-bind改为capture-catch,将只触发handleTap2
(4)事件对象,如无特殊说明,当组件触发事件时,逻辑层绑定该事件的处理函数会收到一个事件对象。
  BaseEvent 基础事件对象属性列表
    type,代表事件的类型
    timeStamp,页面打开到触发事件所经过的毫秒数
    target,触发事件的源组件
      id,事件源组件的id
      dataset,事件源组件上由data-开头的自定义属性组成的集合
    currentTarget,事件绑定的当前组件
      id,当前组件的id
      dataset,当前组件上由data-开头的自定义属性组成的集合
    mark,识别具体触发事件的target节点,承载一些自定义数据,类似于dataset
      <view mark:myMark="last" bindtap="bindViewTap">
        <button mark:anotherMark="leaf" bindtap="bindButtonTap">按钮</button>
      </view>
      在上述WXML中,如果按钮被点击,将触发bindViewTap和bindButtonTap两个事件,事件携带的event.mark将包含myMark和anotherMark两项
      Page({
        bindViewTap: function(e) {
          e.mark.myMark === "last" // true
          e.mark.anotherMark === "leaf" // true
        }
      })
    mark,会包含从触发事件的节点到根节点上所有的mark属性值
    dataset,仅包含一个节点的data-属性值。
  CustomEvent 自定义事件对象属性列表(继承 BaseEvent)
    detail,额外的信息
  TouchEvent 触摸事件对象属性列表(继承 BaseEvent)
    touches,触摸事件,当前停留在屏幕中的触摸点信息的数组,每个元素为一个Touch对象,表示当前停留在屏幕上的触摸点
      identifier,触摸点的标识符
      pageX/pageY,距离文档左上角的距离,文档的左上角为原点 ,横向为X轴,纵向为Y轴
      clientX/clientY,距离页面可显示区域(屏幕除去导航条)左上角距离,横向为X轴,纵向为Y轴
    changedTouches,触摸事件,当前变化的触摸点信息的数组
(5)WXS响应事件
  问题,有频繁用户交互的效果,产生了频繁的视图层与逻辑层交互,使小程序卡顿
  解决,用WXS函数响应小程序事件,目前只能响应内置组件的事件,不支持自定义组件事件
  以下,代码示例
  <wxs module="test" src="./test.wxs"></wxs>
  <view change:prop="{{test.propObserver}}" prop="{{propValue}}" bindtouchmove="{{test.touchmove}}" class="movable"></view>
  change:prop,prop属性被设置的时候触发WXS函数
  //test.wxs
  module.exports = {
    touchmove: function(event, instance) {},
    propObserver: function(newValue, oldValue, ownerInstance, instance) {}
    //以下参数的解释可能有问题
    //event.instance、ownerInstance,表示触发事件的组件的 ComponentDescriptor 实例
    //instance,表示触发事件的组件所在的组件的 ComponentDescriptor 实例,一般是页面实例
  }
  以下,ComponentDescriptor的属性示例,共有13个
  方法,selectComponent;参数,selector对象;描述,返回组件的ComponentDescriptor实例	
  方法,selectAllComponents;参数,selector对象数组;描述,返回组件的ComponentDescriptor实例数组
3、简易双向绑定,自定义组件将自身的myValue属性双向绑定到了组件内输入框的value属性上
  custom-component定义,<input model:value="{{myValue}}" />
  custom-component使用,<custom-component model:my-value="{{pageValue}}" />
4、基础组件
5、获取界面上的节点信息
(1)WXML节点信息
  const query = wx.createSelectorQuery()
  query.select('#the-id').boundingClientRect(function(res){
    res.top // #the-id 节点的上边界坐标(相对于显示区域)
  })
  query.selectViewport().scrollOffset(function(res){
    res.scrollTop // 显示区域的竖直滚动位置
  })
  query.exec()
(2)WXML节点布局相交状态
  以下,目标节点(用选择器 .target-class 指定)每次进入或离开页面显示区域时,触发回调函数
  Page({
    onl oad: function(){
      wx.createIntersectionObserver().relativeToViewport().observe('.target-class', (res) => {
        res.id // 目标节点 id
        res.dataset // 目标节点 dataset
        res.intersectionRatio // 相交区域占目标节点的布局区域的比例
        res.intersectionRect // 相交区域
        res.intersectionRect.left // 相交区域的左边界坐标
        res.intersectionRect.top // 相交区域的上边界坐标
        res.intersectionRect.width // 相交区域的宽度
        res.intersectionRect.height // 相交区域的高度
      })
    }
  })
  以下,目标节点(用选择器.target-class指定)与参照节点(用选择器.relative-class指定)在页面显示区域内相交或相离,且相交或相离程度达到目标节点布局区域的20%和50%时,触发回调函数
  Page({
    onl oad: function(){
      wx.createIntersectionObserver(this, {
        thresholds: [0.2, 0.5]
      }).relativeTo('.relative-class').relativeToViewport().observe('.target-class', (res) => {
        res.intersectionRatio // 相交区域占目标节点的布局区域的比例
        res.intersectionRect // 相交区域
        res.intersectionRect.left // 相交区域的左边界坐标
        res.intersectionRect.top // 相交区域的上边界坐标
        res.intersectionRect.width // 相交区域的宽度
        res.intersectionRect.height // 相交区域的高度
      })
    }
  })
6、响应显示区域变化
(1)one.json,手机单页面启用屏幕旋转支持
  {
    "pageOrientation": "auto",
  }
(2)app.json,iPad上启用屏幕旋转支持、 Windows/Mac 上启用大屏模式
  {
    "resizable": true,
  }
(3)Media Query媒体查询
  .my-class {
    width: 40px;
  }
  @media (min-width: 480px) {
    /* 仅在 480px 或更宽的屏幕上生效的样式规则 */
    .my-class {
      width: 200px;
    }
  }
(4)屏幕旋转事件
  Page({
    onResize(res) {
      res.size.windowWidth // 新的显示区域宽度
      res.size.windowHeight // 新的显示区域高度
    }
  })
  Component({
    pageLifetimes: {
      resize(res) {
        res.size.windowWidth // 新的显示区域宽度
        res.size.windowHeight // 新的显示区域高度
      }
    }
  })
7、分栏模式,启用分栏模式,在app.json中同时添加代码
  {
    "resizable": true,
    "frameset": true
  }
8、动画
(1)用法,this.animate(selector, keyframes, duration, callback)
(2)示例
  this.animate(
    '#container', 
    [
      { opacity: 1.0, rotate: 0, backgroundColor: '#FF0000' },
      { opacity: 0.5, rotate: 45, backgroundColor: '#00FF00'},
      { opacity: 0.0, rotate: 90, backgroundColor: '#FF0000' },
    ], 
    5000, 
    function(){
      this.clearAnimation('#container', { opacity: true, rotate: true }, function () {
        console.log("清除了#container上的opacity和rotate属性")
      })
    }.bind(this)
  )
9、初始渲染缓存
(1)初始渲染
  逻辑层初始化:载入必需的小程序代码、初始化页面this对象、将相关数据发送给视图层。
  视图层初始化:载入必需的小程序代码,然后等待逻辑层初始化完毕,接收逻辑层发送的数据,渲染页面
  在启动页面时,尤其是小程序冷启动、进入第一个页面时,逻辑层初始化的时间较长
(2)初始渲染缓存
  在小程序页面第一次被打开后,将页面初始数据渲染结果记录下来,写入一个持久化的缓存区域
  在这个页面被第二次打开时,检查缓存中是否还存有这个页面上一次初始数据的渲染结果,如果有,就直接将渲染结果展示出来
  如果展示了缓存中的渲染结果,这个页面暂时还不能响应用户事件,等到逻辑层初始化完毕后才能响应用户事件
  复杂组件不能被展示或不能响应交互
(3)初始渲染缓存的作用
  快速展示出页面中永远不会变的部分,如导航栏
  预先展示一个骨架页,提升用户体验
  展示自定义的加载提示
  提前展示广告
(4)静态初始渲染缓存示例
  以下,one.json,单页初始渲染缓存
  {
    "initialRenderingCache": "static"
  }
  以下,app.json,所有页初始渲染缓存
  {
    "window": {
      "initialRenderingCache": "static"
    }
  }
  以下,静态页面
  <view wx:if="{{loading}}">正在加载</view>
  以下,正确的做法
  Page({
    data: {
      loading: true
    }
  })
  以下,错误的做法
  Page({
    data: {},
    onl oad: function() {
      this.setData({
        loading: true
      })
    }
  })
(5)静态初始渲染缓存,慎用

  

标签:git,17,res,程序,事件,移动,data,页面
From: https://www.cnblogs.com/gushixianqiancheng/p/17412155.html

相关文章

  • 17.模式与模式匹配
    模式(patterns)是Rust中一种用来匹配类型结构的特殊语法。将模式与match表达式或其他工具配合使用可以更好地控制程序流程。一个模式匹配通常由以下组件构成:字面量解构地数组、枚举、结构体或元组变量通配符占位符模式被用来与某个特定地值进行匹配。如果模式与值匹配成功,那......
  • pc移动端适配问题
    TL;DR近期在做一个移动端的web网页,当中选用了vw自适应适配方案。然而从设计图标注的px转换到vw是个麻烦事,作为程序员的我很抗拒人工计算,因为那样做CSS代码的可读性会变低,而且编码效率也很低。经过实践我找出了以下几种解决方案,这里列举出来希望对同样患懒癌的你有些许帮助:0.Sas......
  • Vmware 17 创建 Debian 11 服务器
    第一步宿主机断网创建Debian虚拟服务器时,首先断开宿主机的网络,避免创建时自动更新软件导致长时间等待,无法进行后续操作第二步自定义创建虚拟服务器(最小化安装,之后缺什么安装什么,以便明确知道目标软件是否需要额外的依赖项)详细过程略。注意点:安装流程中倒数第二步,选择安装软件......
  • 「解题报告」P3703 [SDOI2017]树点涂色
    有趣题,代码超好写,而且思路超有趣!!!首先发现操作1的操作都是某个点到根,不难发现这样每种颜色一定对应着树上的一条链。那么操作2可以直接树上查分求答案,这样我们只需要考虑维护每个点到根的链的数量了。怎么维护链的数量?发现这个操作1长得和LCT的Access操作一模一样啊,所......
  • SSO2.0 7-20230517
                ......
  • 从桌面端到移动端,.NET MAUI为什么对WPF开发人员更简单?
    .NET多平台应用程序UI(.NETMAUI)的市场吸引力与日俱增,这是微软最新的开发平台,允许开发者使用单个代码库创建跨平台应用程序。尽管很多WPF开发人员还没有跟上.NETMAUI的潮流,但我们将在这篇文章中为大家展示他的潜力,具体来说想描述一下WPF和.NETMAUI之前的共性。PS:DevExpressWP......
  • 2023.5.17
    1题目描述:定义一个时间类,小时和分钟是其两个私有成员数据。输入一个起始时间和一个结束时间(起始时间早于结束时间),通过运算符重载-(减号),计算这两个时间相隔多少分钟。说明:这两个时间在同一天之内,且采用24小时计时分式,即从00:00-23:59。23输入格式:测试输入包含若干......
  • Weblogic < 10.3.6 'wls-wsat' XMLDecoder 反序列化漏洞(CVE-2017-10271)
    参考:https://github.com/vulhub/vulhub/blob/master/weblogic/CVE-2017-10271/README.md反弹shellEXP:POST/wls-wsat/CoordinatorPortTypeHTTP/1.1Host:172.31.14.123:7001Accept-Encoding:gzip,deflateAccept:*/*Accept-Language:enUser-Agent:Mozilla/5.0(com......
  • 5.17
    #include<iostream>usingnamespacestd;intmain(){      intx,y;      cin>>x>>y;      if(x<y)      {             inttmp=y;             y=x;             x=tmp;     ......
  • 5.17
    以圆类Circle及立体图形类Solid为基础设计圆锥类Cone Point类结构说明: Point类的数据成员包括:①私有数据成员:X坐标x(double型),Y坐标y(double型)。Point类成员函数包括:①有参构造函数Point(double,double)和拷贝构造函数Point(constPoint&),其中有参构造函数参数默认......