微信小程序-基础篇
运行环境不同
小程序—微信环境
web—浏览器环境
API不同
微信小程序无法调用DOM和BOM,但是它可以调用微信提供的API,例如地理位置,扫码,支付等
开发模式不同
web=浏览器+编译器
微信小程序=微信开发者工具+各种和配置
他是小程序的全局配置文件,包括了所有页面的路径,窗口的外观,界面的表现,底部tab的配置等。
其中的几项基本的配置:
他是小程序的项目的配置文件,用来记录开发者对微信开发者工具做出的个性化配置
效果类似于PC网页的SEO,该配置文件用来配置小程序的页面是否允许被微信索引
注意:sitemap.json是默认开启的
如果想要关闭,则需要在project.config.json中设置checkSiteMap为false
对本页面的窗口界面、背景色等配置项进行设置
与app.json的区别就是只对当前页面生效并且如果全局与当前的json配置文件冲突,全局的配置会被覆盖
专为小程序设置的标签语言,用来构建小程序的页面结构,类似于网页开发中的HTML
| 与HTML的不同 | 例子 |
|---|---|
| 标签不同 | view、text,image,navigator |
| 属性节点不同 | url(导航) |
| 提供类似于Vue的模板语法 | 数据绑定,列表渲染、条件渲染 |
为小程序设计的一套样式语言,用来描述WXML样式,类似与网页开发中的CSS
| 与CSS的区别 | |
|---|---|
| 新增了rpx单位 | CSS中需要手动换算,而在WXSSS中rpx会被自动换算 |
| 提供了全局样式和局部样式 | app.wxss和局部页面的.wxss |
| 仅支持部分CSS选择器 | .class、#id、element、并集和后代选择器、::after 和::before |
提供页面的交互逻辑,响应用户的操作
一般小程序项目中有三类.js文件
宿主环境是程序运行必须的依赖的环境,脱离了宿主环境的软件是没有任何意义的
小程序的宿主环境就是微信,小程序借助宿主环境提供的能力,完成许多网页无法完成的功能,例如扫码支付、微信支付,微信登录等
- 通信模型
- 运行机制
- 组件
- API
通信主体
通信模型
分为两部分:
小程序的启动过程
页面渲染过程
小程序中的组件是由宿主环境提供的,开发者可以利用其组件快速开发出美观的页面
官方把组件分类9大类:
| 类别 | 代码 |
|---|---|
| 视图容器 | view、scroll-view、swiper、swiper-item |
| 基础内容 | text、rich-text(node属性)、image |
| 表单组件 | |
| 导航组件 | navigator |
| 媒体组件 | |
| map地图组件 | |
| canvas画布组件 | |
| 开放能力 | |
| 无障碍访问 |
小程序中的API是由宿主环境提供的
事件监听API
特点:以on开头,用来监听某些事件的触发
举例:wx.onWindowResize 监听窗口发生变化
同步API
特点1:以Sync结尾的API都是同步API
特点2:同步的API结果,可以直接通过函数获取,如果执行错误会抛出异常
举例:wx.setStorage(‘key’,‘value’)向本地存储中写入内容
异步API
特点:类似于Jquery中的$.ajax,需要通过success,fail,complete接收调用结果
举例:wx.request
在data中(页面的.js文件)定义数据
page({
data:{
num:1,
num2:2,
str:'demo',
imgSrc:'http://www.demo.com/1.png'
}
})
在WXML中使用数据(MustAche语法)
<view>{{num1}}</view>
<iamge src= "{{imgSrc}}" />
<view>{{num2>3?num2:num2+3}}</view>
MustAche的主要应用场景:
- 绑定内容
- 属性绑定
- 运算(三元、算术运算)
事件是渲染层到逻辑层的通讯方式,通过事件可以将用户在渲染层产生的行为,反馈到逻辑层进行业务的处理。
| 类型 | 绑定方式 | 事件描述 |
|---|---|---|
| tap | bindtap、bind:tap | 类似于click |
| input | bindinput、bind:input | 文本框输入事件 |
| change | bindchange、bind:change | 状态改变时触发 |
当事件回调触发的时候,会接收到一个Event对象,他的详细属性如下:
| 属性 | 类型 | 说明 |
|---|---|---|
| type | String | 事件类型 |
| timeStamp | Integer | 页面打开到触发事件所经过的毫秒数 |
| target | Object | 触发事件的组件的一些属性值集合 |
| currentTarget | Object | 当前组件的一些属性值集合 |
| detail | Object | 额外的信息 |
| touches | Array | 触摸事件,当前停留在屏幕中的触摸点信息的数组 |
| changedTouches | Array | 触摸事件,当前变化的触摸点信息的数组 |
重要区别:
- e.target 指向的是触发事件的源头组件,因此,e.target 是内部的按钮组件
- e.currentTarget 指向的是当前正在触发事件的那个组件,因此,e.currentTarget 是当前的 view 组件
addCount(step){
this.setData({
count:this.data.count+step
})
}
错误的传参方式
<button type="primary" bindtap="add(1)">+1</button>
事件函数无法接收到参数
正确的传参方式
<button type="primary" bindtap="add" data-step="{{1}}">+1</button>
//js
add(e){
//dataset 是一个对象 包含了所有通过data-*传递过来的参数
console.log(e.target.dataset) //1
}
需要注意的时表单事件
<input bindinput='inputHandler' />
inputHandler(e){
e.detail.value //是变换后的值
}
通过wx:if判断该元素是否显示
<image src="./1.png" wx:if="{{flag}}" />
多条件组合 wx:elif 、wx:else
<image src="./1.png" wx:if="{{flag===1}}" />
<image src="./1.png" wx:elif="{{flag===2}}" />
<image src="./1.png" wx:else />
结合block使用wx:if
block可以一次控制多个元素的隐藏和显示、他不是一个组件,而是一个包裹用途的容器,类似于template,不会在页面上做任何渲染
<block wx:if="{{flag}}">
<view>1</view>
<view>2</view>
<view>3</view>
</block>
hidden控制元素的显示和隐藏
<view hidden="{{flag}}">2</view>
wx:if于hidden相比较
使用建议:
使用wx:for指定数组进行渲染
类似于 Vue 列表渲染中的 :key,小程序在实现列表渲染时,也建议为渲染出来的列表项指定唯一的 key 值,
从而提高渲染的效率
wxss具有css的大部分特性,并且做出了一些扩充,以适应小程序的开发
wxss扩展的特性:
定义在app.wxss中的样式,作用于每个页面
作用于当前页面
注意:
- 当局部样式和全局样式冲突时,根据就近原则,局部样式会覆盖全局样式
- 当局部样式的权重大于或等于全局样式的权重时,才会覆盖全局的样式
pages
window
| 属性名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| navigationBarTitleText | String | 字符串 | 导航栏标题文字内容 |
| navigationBarBackgroundColor | HexColor | #000000 | 导航栏背景颜色,如 #000000 |
| navigationBarTextStyle | String | white | 导航栏标题颜色,仅支持 black / white |
| backgroundColor | HexColor | #ffffff | 窗口的背景色 |
| backgroundTextStyle | String | dark | 下拉 loading 的样式,仅支持 dark / light |
| enablePullDownRefresh | Boolean | false | 是否全局开启下拉刷新 |
| onReachBottomDistance | Number | 50 | 页面上拉触底事件触发时距页面底部距离,单位为px |
tabBar
style
类似于全局配置app.json
当页面配置与全局配置冲突时,根据就近原则,最终的效果以页面配置为准
出于安全性的考虑,小程序对数据的接口做了如下两个限制
wx.request({
url:'http://www.demo.cn/api/get',//请求的地址 也就是API接口
method:'GET', //请求的方式
data:{ name:'zs' }, //发送到服务器的数据
success:(res)=>{}, //请求成功后的回调函数
fail:(error)=>{}, //请求失败的回调函数
complete:()=>{}
})
wx.request({
url:'http://www.demo.cn/api/get',//请求的地址 也就是API接口
method:'POST', //请求的方式
data:{ name:'zs' }, //发送到服务器的数据
success:(res)=>{}, //请求成功后的回调函数
fail:(error)=>{}, //请求失败的回调函数
complete:()=>{}
})
页面导航是指页面之间跳转
在微信中实现页面导航的两种方式
声明式导航
利用标签,通过点击进行页面的跳转
编程式导航
调用微信小程序的导航API,进行页面的跳转
使用navigator标签
- url:设置导航的路径 需要以 / 开头
- open-type:设置跳转的方式 跳转到tabBar页面必须为:switchTab
<navigator url="/pages/contact/contact" open-type="switchTab">联系</navigator>
使用navigator标签
- url:设置导航的路径 需要以 / 开头
- open-type:设置跳转的方式 跳转到tabBar页面必须为:navigate 这一项通常是可以忽略的
<navigator url="/pages/contact/contact" open-type="navigate">联系</navigator>
使用navigator标签
- delta:必须为数字,表示需要后退的层级 默认为1
- open-type:设置跳转的方式 跳转到tabBar页面必须为:navigateBack
<navigator url="/pages/contact/contact" open-type="navigate">联系</navigator>
wx.navigateBack()方法 参数:
- delta:返回页面数,如果不设置,则默认为1
- success:成功的回调函数
- fail:失败的回调函数
- complete:结束的回调函数
wx.switchTab({
delta:1
success:()=>{},
fail:()=>{},
complete:()=>{}
})
wx.switchTab()方法 参数:
- url:路径,后面不能带参数
- success:成功的回调函数
- fail:失败的回调函数
- complete:结束的回调函数
wx.switchTab({
url:'/pages/messages/messages',
success:()=>{},
fail:()=>{},
complete:()=>{}
})
wx.navigateTo()方法 参数:
- url:路径,后面可以带参数
- success:成功的回调函数
- fail:失败的回调函数
- complete:结束的回调函数
wx.navigateTo({
url:'/pages/messages/messages',
success:()=>{},
fail:()=>{},
complete:()=>{}
})
类似于web的url传参
<navigator url="/pages/info/info?a=10&b=20"></navigator>
在navigateTo中的url,可以携带参数
wx.navigateTo({
url:'/pages/info/info?a=10&b=20'
})
通过声明式导航和编程式导航传递参数,可以直接在onLoad事件中直接获取到
//生命周期函数
onLoad:function(options){
console.log(options) //options 就是传递过来的参数对象
}
定义:指的是通过手指在屏幕上的下拉滑动操作,从而重新加载页面数据的行为
js文件中的onPullDownRefresh()函数即可监听
onPullDownRefresh:function(){
//业务逻辑
}
当下拉刷新后,加载效果会一直显示,需要手动关闭 wx.stopPullDownRefresh()
getList(spdr){
//拉取数据
//停止刷新动画
spdr&&spdr()
}
onPullDownRefresh:function(){
//业务逻辑
this.getList(wx.stopPullDownRefresh())
}
通过手指在屏幕上的上拉滑动操作,从而加载更多数据的行为
onReachBottom()
onReachBottom:function(){
console.log('上拉触底')
}
可以在全局或页面的.json文件中配置 onReachBottomDistance:50 默认是50
分类:
- 应用生命周期 特指小程序从启动 -> 运行 -> 销毁的过程
- 页面生命周期 特指小程序中,每个页面的加载 -> 渲染 -> 销毁的过程
生命周期函数:是由小程序框架提供的内置函数,会伴随着生命周期自动按次序执行
生命周期函数的作用:允许程序员在特定的时间点,执行某些特定的操作。例如,页面刚加载的时候,可以在
onLoad 生命周期函数中初始化页面的数据。
注意:生命周期强调的是时间段,生命周期函数强调的是时间点。
App({
//小程序初始化完成时,执行此函数,全局只触发一次,可以做一些初始化工作
onLaunch:function(options){},
//小程序启动,或者从后台进入前台显示时触发
onShow:function(options){},
//小程序从前台进入后台时触发
onHide:function(){}
})
Page({
//页面加载,一个页面只调用一次
onLoad:function(optins){},
//监听页面显示
onShow:function(){},
//监听页面初次渲染完成 一个页面只调用一次
onReady:function(){},
//监听页面隐藏
onHide:function(){},
//监听页面卸载,一个页面只调用一次
onUnload:function(){}
})
wxml 中无法调用在页面的 .js 中定义的函数,但是,wxml 中可以调用 wxs 中定义的函数。因此,小程序中
wxs 的典型应用场景就是“过滤器”。类似与javascript 但又有区别
wxs有自己的数据类型
number 数值类型、string 字符串类型、boolean 布尔类型、object 对象类型、
function 函数类型、array 数组类型、 date 日期类型、
regexp 正则
wxs不支持es6及以上的语法形式
不支持:let、const、解构赋值、展开运算符、箭头函数、对象属性简写、etc…
支持:var 定义变量、普通 function 函数等类似于 ES5 的语法
wxs遵循这个commJS规范
module 对象
require() 函数
module.exports 对象
<view>{{m1.add()}}</view>
<wxs module='m1'>
module.exports.add=function(){
return 1
}
</wxs>
书写外联的wxs index.wxs:
function add(){
return 1
}
module.exports={
add:add
}
在页面导入 index.wxml:
<view>{{m2.add()}}</view>
<wxs module='m2' src="../../utils/index.wxs"></wxs>
全局应引用:在小小程序的每个页面都可以使用
在app.json文件中的usingComponents下配置组件的导入(key:value)
局部引用:只能在引入的页面使用
在页面的.json文件中的usingComponents下配置组件的导入(key:value)
全局引用与局部引用
需要根据组件的使用频率和范围分析:
- 如果某组件在多个页面经常使用到,则建议“全局引用”
- 如果仅在特定的页面被用到,则建议“局部引用”
表面上都是由wxml、json、wxss、json构成的,但是页面的.js和.json文件有明显的不同
默认情况下,自定义组件的样式只对当前的组件生效
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DCWgbdkE-1660228899378)(C:\Users\13658\AppData\Roaming\Typora\typora-user-images\image-20220811101013616.png)]
好处:
默认情况下,自定义组件的样式隔离特性能够防止组件内外样式互相干扰的问题。但有时,我们希望在外界能够控制组件内部的样式,此时,可以通过 styleIsolation 修改组件的样式隔离选项。
Component({
options:{
styleIsolation:'isolated'
//三个可选值
//isolated:默认值 启用样式隔离
//apply-shared:页面的WXSS会受到组件的影响
//shared:组件的WXSS会受到页面的影响,自定义组件的WXSS也会影响页面或者设置了apply-shared或shared的组件 ****
}
})
data和properties的区别:
- data更倾向于存储组件的私有数据
- properties更倾向于存储外界传递到组件内的数据
数据监听器用于监听和响应任何属性和数据字段的变化,从而执行特定的操作
Component({
observers:{
'字段A,字段B':function(A,B){
//do
}
}
})
Component({
observers:{
'对象.属性A,对象.属性B':function(A,B){
//do
}
}
})
| 生命周期函数 | 参数 | 描述说明 |
|---|---|---|
| created | 无 | 在组件实例刚刚被创建时执行 |
| attached | 无 | 在组件实例进入页面节点树时执行 |
| ready | 无 | 在组件在视图层布局完成后执行 |
| moved | 无 | 在组件实例被移动到节点树另一个位置时执行 |
| detached | 无 | 在组件实例被从页面节点树移除时执行 |
| error | Object Error | 每当组件方法抛出错误时执行 |
其中最重要的生命周期韩式有三个:created、attached、detached
created:
通常在这个生命周期函数中,只应该用于给组件的 this 添加一些自定义的属性字段
attached:
this.setData初始化完毕
这个生命周期很有用,绝大多数初始化的工作可以在这个时机进行(例如发请求获取初始数据)
detached:
此时适合做一些清理性质的工作
此外,定义 生命周期函数现在推荐在lifetimes中声明,且优先级最高
有时,自定义组件的行为依赖于页面状态的变化,此时就需要用到组件所在页面的生命周期。
| 生命周期函数 | 参数 | 描述 |
|---|---|---|
| show | 无 | 组件所在的页面被展示时执行 |
| hide | 无 | 组件所在的页面被隐藏时执行 |
| resize | Object Size | 组件所在的页面尺寸变化时执行 |
Component({
pageLifetimes:{
show:function(){},
hide:function(){},
resize:function(){}
}
})
在自定义组件的 wxml 结构中,可以提供一个 节点(插槽),用于承载组件使用者提供的 wxml 结构
//组件使用者
<test>
<view>我是插槽位置的数据</view>
</test>
/组件封装者
<view>
<slot></slot>
</view>
首先需要在js文件中的options中定义multipleSlots为true
//组件使用者
<test>
<view slot="s1">我是插槽位置的数据111</view>
<view slot="s2">我是插槽位置的数据222</view>
<view slot="s3">我是插槽位置的数据333</view>
</test>
/组件封装者
<view>
<slot name="s1"></slot>
<slot name="s2"></slot>
<slot name="s3"></slot>
</view>
三种方式
属性绑定
用于父组件向子组件传输数据,仅能设置JSON兼容的数据
事件绑定
用于子组件向父组件传递书数据,支持任意数据
获取组件实例
通过this.selectComponent() 获取子组件实例对象,这样可以获取子组件的任意数据和方法
//父组件
data:{
count:0
}
<view>
<test count="{{count}}"></test>
</view>
//子组件
properties:{
count:{
type:Number,
default:1
}
}
<view>{{count}}</view>
基本步骤:
在父组件的js文件中定义一个函数,这个函数将会通过自定义事件的形式,传递给子组件
syncCount(e){
console.log('syncCount')
}
在父组件的wxml中,通过自定义函数的形式,将1中的函数传递给子组件
<view>
<test bind:sync="syncCount"></test>
</view>
在子组件的js中,通过调用this.triggerEvent(‘自定义事件名称’, { /* 参数对象 */ }) ,将数据发送到父组件
methods:{
addCount(){
this.setData({
count:this.properties.count+1
})
this.triggerEvent('sync',{value:this.properties.count})
}
}
在父组件的js中,通过e.detail获取到子组件传递过来的值
syncCount(e){
this.setData({
count:e.detail.value
})
}
在父子间调用this.(‘id或class选择器’)
<my-test class="com" />
getChild(){
const child = this.selectComponent('.com')
//调用setData方法
child.setData({
count:child.properties.count+1
})
//调用子组件的方法
child.addCount()
}
behaviors 是小程序中,用于实现组件间代码共享的特性,类似于 Vue.js 中的 “mixins”
工作方式:
每个 behavior 可以包含一组属性、数据、生命周期函数和方法。组件引用它时,它的属性、数据和方法会被
合并到组件中
创建js文件:
module.exports=Behavior({
//属性节点
peoperties:{},
//私有数据
data:{},
//事件处理函数和自定义事件
methods:{}
//其他节点...
})
在组件中,使用 require() 方法导入需要的 behavior,挂载后即可访问 behavior 中的数据或方法
const comBehavior = require('../../my-behaviors')
Component({
behaviors:[comBehavior]
})
组件和它引用的 behavior 中可以包含同名的字段,此时可以参考如下 3 种同名时的处理规则
引用者 behavior > 被引用的 behavior 、 靠后的 behavior > 靠前的 behavior。(优先级高的覆盖优先级低的,最大的为优先级最高)behavior 中的同名属性或方法;behaviors 字段中定义靠后的 behavior 的属性或方法会覆盖靠前的同名属性或方法;behavior 的情况,则规则为:引用者 behavior 覆盖 被引用的 behavior 中的同名属性或方法behavior 被一个组件多次引用,它定义的生命周期函数和 observers 不会重复执行。behavior 优先于组件执行;被引用的 behavior 优先于 引用者 behavior 执行;靠前的 behavior 优先于 靠后的 behavior 执行;纯数据字段指的是那些不用于界面渲染的 data 字段。
纯数据字段有助于提升页面更新的性能
使用方法:
Components({
options:{
pureDataPattern:/^_/
},
data:{
_count:0 //纯数据字段 使用正则进行匹配
}
})
小程序已经支持使用npm安装第三方包,从而提高开发效率
但是在小程序中使用npm包有如下限制:
- 不支持依赖于 Node.js 内置库的包
- 不支持依赖于浏览器内置对象的包
- 不支持依赖于 C++ 插件的包
npm init -y 或者 yarn init //初始化生成packcage.json
npm install xxx 或者 yarn add xxx //下载包
在小程序开发工具中构建npm包
由于小程序官方提供的异步函数都是基于回调函数的,容易出现回调地狱问题,比如网络请求wx.request,并且可维护性、和可读性差
具体代码: (前提是下载安装好npm包)
import {promisifyAll} from 'miniprogram-api-promise'
const wxp = wx.p = {}
promisifyAll(wx,wxp)
发起请求具体代码:
async getList(){
const res = await wx.p.request({
url:'xxxxxxx'
method:'GET',
data:{
name:'as'
}
})
}
类似于vue中的vuex
全局数据共享(又叫做:状态管理)是为了解决组件之间数据共享的问题。
开发中常用的全局数据共享方案有:Vuex、Redux、MobX 等
创建Store实例
import {observable,action} from 'mobx-miniprogram'
export const store = observable({
//数据字段
num:1,
sum:2,
//计算属性
get sum(){
return this.num + this.sum
},
//action方法用于修改store中的数据
updateNum:action(function(step){
this.num+=step
})
})
将store绑定到页面或组件中
import {createStoreBindings} from 'mobx-miniprogram-bindings'
import {store} from '../../store/store.js'
//页面中
Page({
onLoad:function(){
this.storeBindings = createStoreBindings(this,{
fields:['num','sum'],
actions:['updataSum']
})
}
onUnload:functon(){
this.storeBindings.destoryStoreBindings()
}
})
//组件中
Component({
behaviors:[createStoreBindings],
storeBindings:{
store,
fields:{
num:'num',
sum:'sum'
}
actions:{
updateNum:'updateNum'
}
}
})
在页面或组件中使用
<view>
<text>{{num}}</text>
<button bindtap='handler'></button>
</view>
//js
handler(){
this.updateNum(1)
}
分包指的是把一个完整的小程序项目,按照需求划分为不同的子包,在构建时打包成不同的分包,用户在使用时按需进行加载。
优点:
分包前,小程序项目中所有的页面和资源都被打包到了一起,导致整个项目体积过大,影响小程序首次启动的
下载时间
包后,小程序项目由 1 个主包 + 多个分包组成:
主包
一般只包含项目的启动页面或 TabBar 页面、以及所有分包都需要用到的一些公共资源
分包
只包含和当前分包有关的页面和私有资源
在小程序启动时,默认会下载主包并启动主包内页面,tabBar 页面需要放到主包中
当用户进入分包内某个页面时,客户端会把对应分包下载下来,下载完成后再进行展示
非 tabBar 页面可以按照功能的不同,划分为不同的分包之后,进行按需下载
app.json的subpackages节点中声明分包结构
"subpackages":[
{
"root":'packageA', //分包的根目录
"name":'p1', //分包的别名
"pages":[
"pages/cat", //当前分包下,所有页面对应的根目录
"pages/dog"
]
}
]
独立分包本质上也是分包,只不过它比较特殊,可以独立于主包和其他分包而单独运行。
和其他普通包最主要的区别:是否依赖于主包才能运行
独立分包的应用场景
开发者可以按需,将某些具有一定功能独立性的页面配置到独立分包中。原因如下:
如何使用?
添加independent属性为true即可
引用原则
*特别注意:独立分包中不能引用主包内的公共资源
分包预下载指的是:在进入小程序的某个页面时,由框架自动预下载可能需要的分包,从而提升进入后续分包页面时的启动速度。
如何使用:
app.json中配置
"preloadRule":{
"pages/contact/contact":{ //触发分包预下载的路径
"network":"all", //network 在指定的网络状态下 下载 all 和 wifi
"package":['p1'] //指定下载哪些包 可以是root 也可以是name别名
}
}
注意:分包预下载的限制,同一个分包中的页面享有共同的预下载大小限额 2M
1.postman介绍Postman一款非常流行的API调试工具。其实,开发人员用的更多。因为测试人员做接口测试会有更多选择,例如Jmeter、soapUI等。不过,对于开发过程中去调试接口,Postman确实足够的简单方便,而且功能强大。2.下载安装官网地址:https://www.postman.com/下载完成后双击安装吧,安装过程极其简单,无需任何操作3.使用教程这里以百度为例,工具使用简单,填写URL地址即可发送请求,在下方查看响应结果和响应状态码常用方法都有支持请求方法:getpostputdeleteGet、Post、Put与Delete的作用get:请求方法一般是用于数据查询,
Ⅰ软件测试基础一、软件测试基础理论1、软件测试的必要性所有的产品或者服务上线都需要测试2、测试的发展过程3、什么是软件测试找bug,发现缺陷4、测试的定义使用人工或自动的手段来运行或者测试某个系统的过程。目的在于检测它是否满足规定的需求。弄清预期结果和实际结果的差别。5、测试的目的以最小的人力、物力和时间找出软件中潜在的错误和缺陷6、测试的原则28原则:20%的主要功能要重点测(eg:支付宝的支付功能,其他功能都是次要的)80%的错误存在于20%的代码中7、测试标准8、测试的基本要求功能测试性能测试安全性测试兼容性测试易用性测试外观界面测试可靠性测试二、质量模型衡量一个优秀软件的维度①功能性功
SPI接收数据左移一位问题目录SPI接收数据左移一位问题一、问题描述二、问题分析三、探究原理四、经验总结最近在工作在学习调试SPI的过程中遇到一个问题——接收数据整体向左移了一位(1bit)。SPI数据收发是数据交换,因此接收数据时从第二个字节开始才是有效数据,也就是数据整体向右移一个字节(1byte)。请教前辈之后也没有得到解决,通过在网上查阅前人经验终于解决问题,所以写一个避坑经验总结。实际背景:MCU与一款芯片使用spi通信,MCU作为主机,芯片作为从机。这款芯片采用的是它规定的六线SPI,多了两根线:RDY和INT,这样从机就可以主动请求主机给主机发送数据了。一、问题描述根据从机芯片手
前言一般来说,前端根据后台返回code码展示对应内容只需要在前台判断code值展示对应的内容即可,但要是匹配的code码比较多或者多个页面用到时,为了便于后期维护,后台就会使用字典表让前端匹配,下面我将在微信小程序中通过wxs的方法实现这个操作。为什么要使用wxs?{{method(a,b)}}可以看到,上述代码是一个调用方法传值的操作,在vue中很常见,多用于数据之间的转换,但由于微信小程序诸多限制的原因,你并不能优雅的这样操作,可能有人会说,为什么不用if判断实现呢?但是if判断的局限性在于如果存在数据量过大时,大量重复性操作和if判断会让你的代码显得异常冗余。wxswxs相当于是一个独立
项目介绍随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱小学生兴趣延时班预约小程序的设计与开发被用户普遍使用,为方便用户能够可以随时进行小学生兴趣延时班预约小程序的设计与开发的数据信息管理,特开发了小程序的设计与开发的管理系统。小学生兴趣延时班预约小程序的设计与开发的开发利用现有的成熟技术参考,以源代码为模板,分析功能调整与小学生兴趣延时班预约小程序的设计与开发的实际需求相结合,讨论了小学生兴趣延时班预约小程序的设计与开发的使用。开发环境开发说明:前端使用微信微信小程序开发工具:后端使用ssm:VU
@作者:SYFStrive @博客首页:HomePage📜:微信小程序📌:个人社区(欢迎大佬们加入)👉:社区链接🔗📌:觉得文章不错可以点点关注👉:专栏连接🔗💃:感谢支持,学累了可以先看小段由小胖给大家带来的街舞👉微信小程序(🔥)目录自定义组件-behaviors 1、什么是behaviors 2、behaviors的工作方式 3、创建behavior 4、导入并使用behavior 5、behavior中所有可用的节点 6、同名字段的覆盖和组合规则总结最后自定义组件-behaviors 1、什么是behaviorsbehaviors是小程序中,用于实现
ES一、简介1、ElasticStackES技术栈:ElasticSearch:存数据+搜索;QL;Kibana:Web可视化平台,分析。LogStash:日志收集,Log4j:产生日志;log.info(xxx)。。。。使用场景:metrics:指标监控…2、基本概念Index(索引)动词:保存(插入)名词:类似MySQL数据库,给数据Type(类型)已废弃,以前类似MySQL的表现在用索引对数据分类Document(文档)真正要保存的一个JSON数据{name:"tcx"}二、入门实战{"name":"DESKTOP-1TSVGKG","cluster_name":"elasticsear
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭9年前。我最近开始学习Ruby,这是我的第一门编程语言。我对语法感到满意,并且我已经完成了许多只教授相同基础知识的教程。我已经写了一些小程序(包括我自己的数组排序方法,在有人告诉我谷歌“冒泡排序”之前我认为它非常聪明),但我觉得我需要尝试更大更难的东西来理解更多关于Ruby.关于如何执行此操作的任何想法?
(本文是网络的宏观的概念铺垫)目录计算机网络背景网络发展认识"协议"网络协议初识协议分层OSI七层模型TCP/IP五层(或四层)模型报头以太网碰撞路由器IP地址和MAC地址IP地址与MAC地址总结IP地址MAC地址计算机网络背景网络发展 是最开始先有的计算机,计算机后来因为多项技术的水平升高,逐渐的计算机变的小型化、高效化。后来因为计算机其本身的计算能力比较的快速:独立模式:计算机之间相互独立。 如:有三个人,每个人做的不同的事物,但是是需要协作的完成。 而这三个人所做的事是需要进行协作的,然而刚开始因为每一台计算机之间都是互相独立的。所以前面的人处理完了就需要将数据
文章目录一、项目场景二、基本模块原理与调试方法分析——信源部分:三、信号处理部分和显示部分:四、基本的通信链路搭建:四、特殊模块:interpretedMATLABfunction:五、总结和坑点提醒一、项目场景 最近一个任务是使用simulink搭建一个MIMO串扰消除的链路,并用实际收到的数据进行测试,在搭建的过程中也遇到了不少的问题(当然这比vivado里面的debug好不知道多少倍)。准备趁着这个机会,先以一个很基本的通信链路对simulink基础和相关的debug方法进行总结。 在本篇中,主要记录simulink的基本原理和基本的SISO通信传输链路(QPSK方式),计划在下篇记