微信小程序基础

1.小程序发展史

微信小程序之前,是使用weixin-sdk进行开发,调用视频,摄像头等。

微信小程序weixin up端,所以PC端的window这些没有,运行环境是IOS,安卓等,有一些特殊的调用录音功能,摄像头等

申请账号:开发账号+开发工具

2.小程序全局配置app.json

小程序根目录下的 app.json 文件用来对微信小程序进行全局配置。

  • pages 页面路径列表
  • window 全局的默认窗口表现
  • tabBar 底部 tab 栏的表现

window

  • navigationBarBackgroundColor 导航栏背景颜色,如 #000000
  • navigationBarTextStyle 导航栏标题颜色
  • navigationBarTitleText 导航栏标题文字内容
  • enablePullDownRefresh 是否开启全局的下拉刷新

tarBar

  • color tab 上的文字默认颜色,仅支持十六进制颜色
  • selectedColor tab 上的文字选中时的颜色,仅支持十六进制颜色
  • backgroundColor tab 的背景色,仅支持十六进制颜色
  • borderStyle tabbar 上边框的颜色, 仅支持 black / white
  • position tabBar 的位置,仅支持 bottom / top
  • custom 自定义 tabBar
  • list tab 的列表,详见 list 属性说明,最少 2 个、最多 5 个 tab

3.页面配置

页面配置高于全局配置。页面配置和全局配置相同时,页面配置会覆盖全局配置 

4.小程序生命周期

分为应用的生命周期、页面的生命周期、组件的生命周期

应用的声明周期:onLaunch()

App({/*** 当小程序初始化完成时,会触发 onLaunch(全局只触发一次)*/onLaunch: function () {console.log('onLaunch --- app')},/*** 当小程序启动,或从后台进入前台显示,会触发 onShow*/onShow: function (options) {console.log('onShow --- app')},/*** 当小程序从前台进入后台,会触发 onHide*/onHide: function () {console.log('onHide --- app')}
})

页面的生命周期:

onLoad()页面首次加载,可接受一个参数

Page({/*** 生命周期函数--监听页面加载*/onLoad: function (options) {console.log('onLoad --- page')},/*** 生命周期函数--监听页面初次渲染完成*/onReady: function () {console.log('onReady --- page')},/*** 生命周期函数--监听页面显示*/onShow: function () {console.log('onShow --- page')},/*** 生命周期函数--监听页面隐藏*/onHide: function () {console.log('onHide --- page')},/*** 生命周期函数--监听页面卸载*/onUnload: function () {console.log('onUnload --- page')}
})

组件的生命周期(包括组件本身生命周期和组件所在页面的生命周期)

组件移动,拖拽等

组件所在页面的生命周期(当小程序进入后台,后台进入前台进行操作时,调整屏幕尺寸等),如再次进入前台时,列表页数据展示的刷新,就是根据组件内页面的生命周期完成

Component({// 组件的生命周期lifetimes: {// 在组件实例刚刚被创建时执行created: function () {console.log('created --- component')},// 在组件实例进入页面节点树时执行attached: function () {console.log('attached --- component')},// 在组件在视图层布局完成后执行ready: function () {console.log('ready --- component')},// 在组件实例被移动到节点树另一个位置时执行moved: function () {console.log('moved --- component')},// 在组件实例被从页面节点树移除时执行detached: function () {console.log('detached --- component')}},// 组件所在页面的生命周期pageLifetimes: {// 组件所在的页面被展示时执行show: function () {console.log('show --- component')},// 组件所在的页面被隐藏时执行hide: function () {console.log('hide --- component')},// 组件所在的页面尺寸变化时执行resize: function () {console.log('resize --- component')}}
})

执行流程:

5.页面路由 

页面路由:在小程序中所有页面的路由全部由框架进行管理。

页面栈:

框架以栈的形式维护了当前的所有页面。 当发生路由切换的时候,可以使用 getCurrentPages() 函数获取当前页面栈

重加载:一般不用,小程序打开或者页面刷新时

测试:

使用wx.navigateTo()从index跳转到logs页面:

 

 使用wx.redirectTo()跳转

注意事项:

  • navigateToredirectTo 只能打开非 tabBar 页面。
  • switchTab 只能打开 tabBar 页面。
  • reLaunch 可以打开任意页面。
  • 页面底部的 tabBar 由页面决定,即只要是定义为 tabBar 的页面,底部都有 tabBar。
  • 调用页面路由带的参数可以在目标页面的onLoad中获取。

 6.API接口

API接口可以直接使用的方法:App(),Page(),Component()以及组件中的全局接口wx.navigateTo()等方法

App()

  • App()中可以监听onLaunch()等钩子函数;
  • 创建全局应用实例app(类似window):App()中定义在globalData属性中,在页面通过const app= getApp()获取,然后各种方法如onLoad()钩子函数中即可使用

Page()

获取页面栈方法:getCurrentPages()

数组中第一个元素为首页,最后一个元素为当前页面。

如订单支付后返回上级或者返回多级,即可通过getCurrentPages()获取当前页面栈信息。或替换成另一个页面

Router页面路由对象

可以通过 this.pageRouter 或 this.router 获得当前页面或自定义组件的路由器对象。

页面路由器有 switchTab reLaunch redirectTo navigateTo navigateBack 五个方法,与 wx 对象向同名的五个方法 switchTab reLaunch redirectTo navigateTo navigateBack 功能相同

页面路由器Router对象和wx对象区别:

  • 页面路由器中的方法调用时,相对路径永远相对于 this 指代的页面或自定义组件。
  • this.pageRouter 获得的路由器对象具有更好的基路径稳定性。通常情况下,使用 this.pageRouter.navigateTo 代替 wx.navigateTo 是更优的。
  • wx对象方法跳转的新路径是绝对路径,this.pageRouter.navigateTo 跳转后的新路径是相对路径,相对于当前this页面

this.pageRouter 和 this.router 在页面中将获得同样的页面路由器对象。但如果在自定义组件中调用, this.pageRouter 将相对于自定义组件所在的页面来进行路由跳转,而 this.router 相对于自定义组件自身的路径

Component()

相对比较复杂,页面中如果需要使用到监听等特殊用法也需要使用Component()

7.模块化

 导出:

module.exports 或者 exports,exports 是 module.exports 的一个引用,随意更改 exports 的指向会造成未知的错误。所以更推荐开发者采用 module.exports 来暴露模块接口

module.exports.sayHello = sayHello
exports.sayGoodbye = sayGoodbye

小程序目前不支持直接引入 node_modules使用到 node_modules 时候建议拷贝出相关的代码到小程序的目录中,或者使用小程序支持的 npm 功能。

使用:

使用这些模块的文件中,使用 require 将公共代码引入

var common = require('common.js')

8.数据绑定

简单绑定: {{ message }}

属性中绑定:<view id="item-{{id}}"></view>

控制属性: wx:if="condition"

关键字:<checkbox checked="{{false}}"></checkbox>,如果直接写字符串会进行隐式转换为true

可以进行表达式计算、算术运算

可以对对象和数组中的变量和数据进行组合

<view wx:for="{{[zero, 1, 2, 3, 4]}}"> {{item}} </view>
Page({data: {zero: 0}
})

属性后面有空格会解析成空白字符串 

<view wx:for="{{[1,2,3]}} ">{{item}}
</view>

 等同于

<view wx:for="{{[1,2,3] + ' '}}">{{item}}
</view>

 9.条件渲染 

wx:if  wx:elif  wx:else,一般用在<block>标签中

wx:if 和 hidden区别【-

  • wx:if 之中的模板也可能包含数据绑定,所以当 wx:if 的条件值切换时,框架有一个局部渲染的过程,因为它会确保条件块在切换时销毁或重新渲染。
  • wx:if 也是惰性的,如果在初始渲染条件为 false,框架什么也不做,在条件第一次变成真的时候才开始局部渲染。
  • hidden 就简单的多,组件始终会被渲染,只是简单的控制显示与隐藏(display属性none和block)。
  • wx:if 有更高的切换消耗而 hidden 有更高的初始渲染消耗。因此,如果需要频繁切换的情景下,用 hidden 更好,如果在运行时条件不大可能改变则 wx:if 较好。

 10.列表渲染 wx:for

默认数组的当前项的下标变量名默认为 index,数组当前项的变量名默认为 item(不需要重新声明)

使用 wx:for-item 可以指定数组当前元素的变量名,

使用 wx:for-index 可以指定数组当前下标的变量名:

<view wx:for="{{array}}">{{index}}: {{item.message}}
</view>

如果是对象遍历的item和index分别是key和value

block wx:for使用block标签包裹

wx:key唯一值指定列表中项目的唯一的标识符。

 wx:for 的值为字符串时,会将字符串解析成字符串数组

wx:for="array"
等同于
wx:for="{{['a','r','r','a','y']}}

11.模版渲染和引入

 定义模板:

使用 name 属性,作为模板的名字。然后在<template/>内定义代码片段

<template name="msgItem"><view><text> {{index}}: {{msg}} </text><text> Time: {{time}} </text></view>
</template>

使用模板

当前页面可直接使用,如果跨页面需要进行引用。两种文件引用方式importinclude

使用 is 属性,声明需要的使用的模板,然后将模板所需要的 data 传入,

<import src="item.wxml"/>
<template is="item" data="{{text: 'forbar'}}"/>

import 的作用域

只会 import 目标文件中定义的 template,而不会 import 目标文件 import 的 template。

如:C import B,B import A,在C中可以使用B定义的template,在B中可以使用A定义的template,但是C不能使用A定义的template

include引入

include 可以将目标文件除了 <template/> <wxs/> 外的整个代码引入,相当于是拷贝到 include 位置

<include src="header.wxml"/>
<view> body </view>
<include src="footer.wxml"/>

12.事件

bindtap点击事件;

detail:自定义事件携带数据,点击事件带有的 x, y 同 pageX, pageY 代表距离文档左上角的距离。

currentTarget:如果有事件冒泡,使用currentTarget获取的dataset,表示当前组件上由data-开头的自定义属性组成的集合数据

阻止事件冒泡:使用catchtap即可阻止事件冒泡

<view id="outer" bindtap="handleTap1">outer view<view id="middle" catchtap="handleTap2">middle view<view id="inner" bindtap="handleTap3">inner view</view></view>
</view>

手指触摸事件:小程序中用得不多,内部有封装很多拖拽事件

13.wxss

与 CSS 相比,WXSS 扩展的特性有:

  • 尺寸单位
  • 样式导入

一般设计稿规范:以iPhone6 为基准,屏幕宽度为375px,共有750个物理像素,则750rpx = 375px = 750物理像素,1rpx = 0.5px = 1物理像素

样式导入:@import "common.wxss"

内联样式:如果需要动态渲染可以使用,如果纯静态样式不建议使用内联会影响渲染速度

全局样式app.wxss会作用域全局,但局部样式优先级高于全局

14.自定义组件

右击创建components创建自定义组件

使用时:页面js文件中usingComponent中引入;wxml页面中引入组件

注意:在组件wxss中不应使用ID选择器、属性选择器和标签名选择器。

注意点:

  • 自定义组件名只能是小写字母、中划线和下划线的组合
  • 使用 usingComponents 字段引入;
  • 自定义组件和页面所在项目根目录名不能以“wx-”为前缀,否则会报错。
  • 出于性能考虑,使用 usingComponents 时, setData 内容不会被直接深复,即 this.setData({ field: obj }) 后 this.data.field === obj 。(深复制会在这个值被组件间传递时发生。)

15自定义组件模版和样式

自定义组件插槽<slot>

 默认插槽和具名插槽,基本和vue一致

如果要使用多个插槽需要在options中设置multipleSlots: true

options: {multipleSlots: true // 在组件定义时的选项中启用多slot支持},

 组件样式:

不能使用id,属性,标签 ,子元素选择器(.a > .b)

可以设置默认样式: :host{ color: red; },当前自定义组件下所有默认样式

组件间样式隔离:

父子组件都有同一个样式,样式设置在page中,自定义组件中使用。发现自定义组件中样式没有生效。

页面和组件样式都是相互隔离的。

改变:使用options:{ styleIsolation: "isolated" }进行修改

styleIsolation属性值:

  • isolated 表示启用样式隔离,在自定义组件内外,使用 class 指定的样式将不会相互影响(一般情况下的默认值);
  • apply-shared 表示页面 wxss 样式将影响到自定义组件,但自定义组件 wxss 中指定的样式不会影响页面;
  • shared 表示页面 wxss 样式将影响到自定义组件,自定义组件 wxss 中指定的样式也会影响页面和其他设置了 apply-shared 或 shared 的自定义组件。(这个选项在插件中不可用。)

外部样式类

组件希望接受外部传入的样式类。此时可以在 Component 中用 externalClasses 定义段定义若干个外部样式类。

实现类似于 view 组件的 hover-class 属性:页面可以提供一个样式类,赋予 view 的 hover-class ,这个样式类本身写在页面中而非 view 组件的实现中。

注意:在同一个节点上使用普通样式类和外部样式类时,两个类的优先级是未定义的,因此最好避免这种情况。

引用页面或父组件的样式

 使启用了样式隔离 isolated ,组件仍然可以在局部引用组件所在页面的样式或父组件的样式。

虚拟化组件节点

默认情况下,自定义组件本身的那个节点是一个“普通”的节点,使用时可以在这个节点上设置 class style 、动画、 flex 布局等,就如同普通的 view 组件节点一样。

自定义组件并不希望这个节点本身可以设置样式、响应 flex 布局等,而是希望自定义组件内部的第一层节点能够响应 flex 布局或者样式由自定义组件本身完全决定。这种情况下,可以将这个自定义组件设置为“虚拟的”:

Component({options: {virtualHost: true},properties: {style: { // 定义 style 属性可以拿到 style 属性上设置的值type: String,}},externalClasses: ['class'], // 可以将 class 设为 externalClasses
})
<!-- 页面的 WXML -->
<view style="display: flex"><!-- 如果设置了 virtualHost ,节点上的样式将失效 --><custom-component style="color: blue">不是蓝色的</custom-component>
</view>
<!-- custom-component.wxml -->
<view style="flex: 1">满宽的<slot></slot>
</view>

 需要注意的是,自定义组件节点上的 class style 和动画将不再生效,但仍可以:

  • 将 style 定义成 properties 属性来获取 style 上设置的值;
  • 将 class 定义成 externalClasses 外部样式类使得自定义组件 wxml 可以使用 class 值。

16.Component构造器

Component构造器有两种作用: 创建自定义组件;页面中使用 Component 构造器构造页面

Component构造器创建自定义组件:

Component 构造器可用于定义组件,调用 Component 构造器时可以指定组件的属性、数据、方法等。 

页面中使用 Component 构造器构造页面

监听数据,公共逻辑复用(behaviors)等。

Component 构造器构造页面也可以实现以下功能:

onLoad()中获取页面跳转后的参数;

可以通过properties获取父级页面的数据;(properties定义的数据,可以通过this.data进行获取)

17.双向绑定

通的属性的绑定是单向的

<input value="{{value}}" />

如果使用 this.setData({ value: 'leaf' }) 来更新 value ,this.data.value 和输入框的中显示的值都会被更新为 leaf ;但如果用户修改了输入框里的值,却不会同时改变 this.data.value 。

手动实现双绑

如果要实现可以使用bindinput然后手动更改this.data.value的值

<input type="text" bindinput="inputChange"/>
<span>这是输入框的值: {{inputText}}</span>
Component({data: {inputText: ''},methods: {inputChange(e){console.log(e.detail.value);this.setData({inputText: e.detail.value})},
}
})

 实现简单双向绑定:属性前加上model:value

注意是model:value="{{inputText}}"不是model:input-text="{{inputText}}"。model:input-text="{{inputText}}"是自定义组件双绑方法

<input type="text" model:value="{{inputText}}"/>
<span>这是输入框的值: {{inputText}}</span>

用于双向绑定的表达式有如下限制

  • 只能是一个单一字段的绑定,如以下是非法的
<input model:value="值为 {{value}}" />
<input model:value="{{ a + b }}" />
  • 目前,尚不能 data 路径,如不支持属性深层双绑监听
<input model:value="{{ a.b }}" />

 在自定义组件中传递双向绑定

属性传值必须小写字母+ “-”形式,不能使用大驼峰

父组件: model:input-text="inputText"

子组件:通过properties接收,然后通过update方法直接在子组件中修改(和vue不同,vue必须通知父级修改)

父组件:

<input type="text" model:value="{{inputText}}"/>
<my-component model:input-text="{{inputText}}"></my-component>
  data: {inputText: ''},

 子组件:

<view>
子组件:{{inputText}}
</view>
<button bindtap="updateData">重置数据</button>
properties: {inputText: String},methods: {updateData: function() {// 更新 inputTextthis.setData({inputText: '重置数据'})}},

18.组件通信

  1. WXML数据绑定(slot插槽方式)
  2. 事件方式:用于子组件像父组件传递数据
  3. 父组件this.selectComponent()获取子组件实例对象,直接操作子组件的数据和方法

事件方式:

父组件中传入数据和方法:input-text="{{inputText}}" bind:set-input="handleInput"。handleInput方法中监听子组件传递过来数据并更改inputText

子组件中:properties获取数据,然后在button点击时,通过this.triggerEvent("set-input",{inputText:"重置数据"})进行修改

父组件:

<input type="text" model:value="{{inputText}}"/>
<my-component input-text="{{inputText}}" bind:set-input="handleInput"></my-component>
    handleInput(e){this.setData({inputText: e.detail.inputText})},

子组件:

<view>
子组件:{{inputText}}
</view>
<button bindtap="updateData">重置数据</button>
    updateData: function() {// 自定义事件实现双绑this.triggerEvent('set-input', {inputText: "重置数据"})},

triggleEvent触发事件选项(该方法第三个参数)

bubbles:事件是否冒泡,默认false

composed:是否可以穿越边界。如下为false时事件只在my-component组件中触发时生效,外层的another-component不会生效

<another-component bindcustomevent="pageEventListener1"><my-component bindcustomevent="pageEventListener2"></my-component>
</another-component>

获取组件实例this.selectComponent

在父组件里调用 this.selectComponent ,获取子组件的实例对象。

因为时在父级操作子组件,所以会造成逻辑混乱。所以除特殊需要一般不要使用

const child = this.selectComponent('.my-component');

19.数据监听器observers

类似vue的watch,但是比vue的watch更加强大,在watch基础上也实现了computed的功能。

数据监听器可以用于监听和响应任何属性和数据字段的变化。 2.6.1 以上基础库版本

只能定义在Component()下面

numberA和numberB任何一个变量修改都会重新赋值,相当与vue的computed

numberA:<input model:value="{{numberA}}"> </input>
numberB:<input model:value="{{numberB}}"></input>
sum和为:{{sum}}
Component({data: {// inputText: ''numberA:0,numberB:0,sum:0},observers:{'numberA,numberB':function(newA,newB){this.setData({sum: parseInt(newA) + parseInt(newB)});}},
})

购物车案例:

<!-- 购物车案例 -->
<view><view class="name" wx:for="{{item}}" wx:key="id"><view>{{item.name}}</view><view>¥{{item.price}}</view><view class="number-btn" bindtap="changeNum" data-index="{{index}}" data-type="add">+</view><input type="number" model:value="{{item.num}}" class="number-input"/><view class="number-btn" data-index="{{index}}" data-type="sub" bindtap="changeNum">-</view></view><view>合计:¥{{totalPrice}}</view>
</view>
Component({data: {item:[{id:1,name: '华为Mate 50E 4G',price: 3999,num:0},{id:2,name: '苹果15',price: 7400,num:0},],totalPrice:0},observers:{'item':function(newVal){let totalPrice = this.data.item.reduce((sum,item)=>{return sum = sum + item.price * item.num},0) this.setData({totalPrice});}},methods: {changeNum(e){console.log(e);let { type, index } = e.target.dataset;let data = JSON.parse(JSON.stringify(this.data.item))if(type==='add'){data[index].num +=1;}else{data[index].num -=1;}this.setData({item: data});},ready(){let totalPrice = this.data.item.reduce((sum,item)=>{return sum = sum + item.price * item.num},0)this.setData({totalPrice})}
}
})

20.纯数据字段

定义在data中的字段可以进行组件间传递,但是也同时会影响页面的性能。那么就可以给不需要进行页面渲染只存在逻辑处理的数据声明为纯数据字段

  • options的pureDataPattern定义匹配所有纯数据字段
  • this.data._b可以获取,但是页面不会进行渲染即纯数据字段不会被应用到 WXML 上
  • 属性中的纯数据字段的属性 observer 永远不会触发!如果想要监听属性值变化,使用 数据监听器 代替
Component({options: {pureDataPattern: /^_/ // 指定所有 _ 开头的数据字段为纯数据字段},data: {a: true, // 普通数据字段_b: true, // 纯数据字段},methods: {myMethod() {this.data._b // 纯数据字段可以在 this.data 中获取this.setData({c: true, // 普通数据字段_d: true, // 纯数据字段})}}
})
_b: {type: Boolean,observer() {// 不要这样做!这个 observer 永远不会被触发}},
observers: {timestamp: function () {// timestamp 被设置时,将它展示为可读时间字符串var timeString = new Date(this.data.timestamp).toLocaleString()this.setData({timeString: timeString})}}

 21.滚动组件scroll-view

注意点:

  • scroll-y写法
  • scroll-into-view="{{scrollTo}}的值必须是动态变量
  • <view id="{{item.id}}"> scroll-view里面的数据必须有id且id不能以数字开头如 id: 'test'+i,
<!-- scroll-view滚动组件 -->
<view class="header">这是头部区域<button bindtap="gotoPos">定位到id为50处</button>
</view>
<!-- 注意scroll-y写法 -->
<!-- scroll-into-view的值必须是动态变量,且scroll-view里面的数据必须有id且id不能以数字开头 -->
<scroll-view scroll-y class="scroll-view" scroll-with-animation="true" scroll-into-view="{{scrollTo}}"><block wx:for="{{scrollItem}}" wx:key="id"><view id="{{item.id}}">{{item.id}}-{{item.name}}</view>
</block>
</scroll-view>

 

.header{width: 100%;height: 200rpx;background-color: darkgreen;
}.scroll-view{height: calc(100% - 100px);
}
Component({data: {scrollItem:[],scrollTo:0},methods: {onLoad(){const data = Array(100).fill(0).map((_, i) => {return {id: 'test'+i,name: i+'test'}});this.setData({scrollItem: data});},gotoPos(){this.setData({scrollTo: 'test'+50});}
}
})

 

22.拖拽组件movable-area

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/212859.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

微服务1 springcloud学习笔记P1-P40

b微服务技术栈_哔哩哔哩_bilibili 文档资料: 链接&#xff1a;https://pan.baidu.com/s/1P_Ag1BYiPaF52EI19A0YRw?pwdd03r 提取码&#xff1a;d03r 一 了解微服务技术 二 Eureka (1) Eureka配置 (2) 注册user-service (3) 总结 Ribbon 负载均衡 (1) 流程 三 nacos配置管理…

公众号提高数量

一般可以申请多少个公众号&#xff1f;目前公众号申请数量的规定是从2018年底开始实施的&#xff0c;至今没有变化。规定如下&#xff1a;1、个人可以申请1个个人主体的公众号&#xff1b;2、企业&#xff08;有限公司&#xff09;可以申请2个公众号&#xff1b;3、个体户可以申…

初识消息队列

1、消息 消息&#xff08;Message&#xff09;是指在应用间传送的数据。消息可以非常简单&#xff0c;比如只包含文本字符串&#xff0c;也可以更复杂&#xff0c;可能包含嵌入对象。 2、消息队列 消息队列&#xff08;Message Queue&#xff09;是一种应用间的通信方式&#…

12.8作业

1.头文件 #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QDebug> #include <QMovie>QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEclass Widget : public QWidget {Q_OBJECTpublic:Widget(QWidget *parent nul…

【无线网络技术】——无线局域网(学习笔记)

&#x1f4d6; 前言&#xff1a;本章首先介绍无线局域网的基本概念&#xff0c;然后详细介绍IEEE 802.11的基本工作原理&#xff0c;侧重于媒体访问控制和一跳范围内的通信技术。 目录 &#x1f552; 1. 概述&#x1f558; 1.1 覆盖范围&#x1f558; 1.2 特点&#x1f558; 1.…

SIT3232E高静电防护,单电源供电,双通道,RS232 收发器

SIT3232E 是一款 3.0V~5.5V 供电、双通道、低功耗、高静电防护 ESD 保护&#xff0c;完全满足 TIA/EIA-232 标准要求的 RS-232 收发器。 SIT3232E 包括两个驱动器和两个接收器&#xff0c;具有增强形 ESD 保护功能&#xff0c;达到 15kV 以上 HBM ESD 、 8kV …

为什么Java程序员需要掌握多线程?揭秘并发编程的奥秘

为什么Java程序员需要掌握多线程&#xff1f;揭秘并发编程的奥秘 个人简介前言多线程对于Java的意义&#x1f4cc;1.提高程序性能&#xff1a;&#x1f4cc;2 提高用户体验&#xff1a;&#x1f4cc;3支持并发处理&#xff1a;&#x1f4cc;4 资源共享和同步&#xff1a;&#…

【Python】Python读Excel文件生成xml文件

目录 ​前言 正文 1.Python基础学习 2.Python读取Excel表格 2.1安装xlrd模块 2.2使用介绍 2.2.1常用单元格中的数据类型 2.2.2 导入模块 2.2.3打开Excel文件读取数据 2.2.4常用函数 2.2.5代码测试 2.2.6 Python操作Excel官方网址 3.Python创建xml文件 3.1 xml语法…

Android MVVM+coroutine+retrofit+flow+hilt

文章目录 Android MVVMcoroutineretrofitflowhilt概述依赖注入层数据层视图层模型视图层代码下载 Android MVVMcoroutineretrofitflowhilt 概述 代码结构&#xff1a; 依赖注入层 数据库&#xff1a; Module InstallIn(SingletonComponent::class) class DBModule {Singleto…

IP地址定位技术:追踪位置、识别风险

随着互联网的普及&#xff0c;IP地址定位技术逐渐成为网络安全领域的一项重要工具。通过追踪IP地址位置&#xff0c;可以识别潜在的风险用户&#xff0c;加强网络安全。本文将深入研究IP地址定位技术的原理、应用以及相关的风险与防范。 1. IP地址定位技术的原理&#xff1a; …

C语言——2048完整版

2048是一个简单又有趣的小游戏&#xff0c;相信大家都接触并了解过&#xff0c;那如何通过代码来实现他呢&#xff1f;下面就让我们来一起看看。 目录 1、头文件 2、主函数 3、 StarGame 4、GetNum 5、Show 6、Picture 7、GetButton 8、MergeLeft 9、MergeUp 10、MergeR…

webpack优化打包速度

webpack打包速度太慢 优化 1.多线程打包 js压缩和loader 2.优化启动速度 hard-source-webpack-plugin 3.删除无用的 分析类插件 4.DllPlugin通道打包 1.webpack多线程打包 loader loader 使用 thread-loader 将他放置你要使用的loader前面就行&#xff0c;不过这个lorder例如s…

HarmonyOS学习--TypeScript语言学习(一)

注意&#xff1a;这只是我学习的笔记&#xff01;&#xff01;&#xff01; 注意&#xff1a;这只是我学习的笔记&#xff01;&#xff01;&#xff01; 注意&#xff1a;这只是我学习的笔记&#xff01;&#xff01;&#xff01; 本章目录如下&#xff1a; 一、TypeScript语言…

cmake生成表达式

不积小流&#xff0c;无以成江海 <CONFIG:RELEASE> config这个关键字&#xff0c;主要是看CMAKE_BUILD_TYPE这个变量的值是不是和冒号后的一样&#xff0c;一样的话就返回true, 否则就是false. cmake_minimum_required(VERSION 3.10) project(Test) set(CMAKE_CXX_STA…

每天学习一点shell系列(2)—函数的参数传递

参考博客&#xff1a;shell 脚本-10函数_eno_zeng的博客-CSDN博客 $n 或 ${n} &#xff1a;函数内使用 $n 或 ${n} 访问对应的参数, 数字代表参数的前后顺序, $1 代表第一个参数, $2 代表第三个参数, $n 代表第n个参数&#xff1b;当n>10时&#xff0c;需要使用${n}来获取参…

harmony开发之Text组件的使用

TextInput、TextArea是输入框组件&#xff0c;通常用于响应用户的输入操作&#xff0c;比如评论区的输入、聊天框的输入、表格的输入等&#xff0c;也可以结合其它组件构建功能页面&#xff0c;例如登录注册页面。 图片来源黑马程序员 Text组件的使用&#xff1a; 文本显示组…

算法学习—排序

排序算法 一、选择排序 1.算法简介 选择排序是一个简单直观的排序方法&#xff0c;它的工作原理很简单&#xff0c;首先从未排序序列中找到最大的元素&#xff0c;放到已排序序列的末尾&#xff0c;重复上述步骤&#xff0c;直到所有元素排序完毕。 2.算法描述 1&#xff…

PostgreSQL 技术内幕(十二) CloudberryDB 并行化查询之路

随着数据驱动的应用日益增多&#xff0c;数据查询和分析的量级和时效性要求也在不断提升&#xff0c;对数据库的查询性能提出了更高的要求。为了满足这一需求&#xff0c;数据库引擎不断经历创新&#xff0c;其中并行执行引擎是性能提升的重要手段之一&#xff0c;逐渐成为数据…

Spring全面详解

目录 1. Spring 概述 1.1 Spring是什么 1.2 Spring的作用 1.3 Spring IoC是什么 2. Spring 快速入门 3. Spring Bean 3.1 的实例化方式 空参构造器 3.2 的属性注入 全参构造器注入 setter方法注入 策略模式 3.3 注解管理 3.4 注解方式的属性注入 1. Spring 概述 …

os.walk()遍历文件夹/文件

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…