微信小程序基础

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.hqwc.cn/news/258526.html

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

相关文章

【以医院为案例】讲如何画业务架构图

【以医院为案例】讲如何画业务架构图 背景知识 什么是业务&#xff1f; 业务是个人或企业为了获利而进行的有组织的努力和活动。 以医院为案例: 业务是指医院提供医疗服务的活动。患者通过消费来享受医院提供的医疗服务&#xff0c;从而重新获得健康的身体。可以将患者去医院…

实战| 通杀漏洞挖掘技巧

前言 前端时间&#xff0c;要开放一个端口&#xff0c;让我进行一次安全检测&#xff0c;发现的一个漏洞。 经过 访问之后发现是类似一个目录索引的端口。(这里上厚码了哈) 错误案例测试 乱输内容asdasffda之后看了一眼Burp的抓包&#xff0c;抓到的内容是可以发现这是一个…

家用洗地机希亦、追觅和添可哪款好用?测评PK谁是清洁之王

对于上班族来说&#xff0c;时间非常宝贵&#xff0c;打扫卫生就成为了一件比较痛苦的事情。现在的都市上班族都会寄托于智能家电。在当前市场上&#xff0c;洗地机已成为家庭清洁的面部工具。洗地机是一种高效的清洁设备&#xff0c;以其自动化、高效率的清洁功能&#xff0c;…

express搭建后台node接口

在前端的学习中我们使用express来开发接口结合mysql&#xff0c;然后使用可视化的数据库工具来操作数据&#xff0c; web框架是express 文档是jsdoc swagger 数据库模型是sequelize 部署使用PM2来上服务器&#xff0c; 打包你也可以结合webpack配置target node状态 当然你也可以…

ES-环境安装(elasticsearch:7.17.9,kibana,elasticsearch-head)

ES 环境搭建 1 拉取镜像 常用三件套 docker pull kibana:7.17.9 docker pull elasticsearch:7.17.9 docker pull mobz/elasticsearch-head:52 启动镜像 elasticsearch 安装 这里可以先不挂载文件启动一波&#xff0c;然后把容器里的文件拷贝出来 docker run -p 19200:9200 …

【AI】以大厂PaaS为例,看人工智能技术方案服务能力的方向(2/2)

目录 三、解决方案 3.1 人脸身份验证 3.2 图像审核&#xff08;暴恐、色情等&#xff09; 3.3 人脸会场签到 3.4 机器人视觉 3.5 视频审核 3.6 电商图文详情生成 3.7 智能客服 接上回&#xff1a; 【AI】以大厂PaaS为例&#xff0c;看人工智能技术方案服务能力的方向&…

SSL 协议

SSL 是用于安全传输数据的一种通信协议。它采用公钥加密技术、对称密钥加密技术等保护两个应用之间的信息传输的机密性和完整性。但是&#xff0c;SSL 也有一个不足&#xff0c;就是它本身不能保证传输信息的不可否认性。 SSL 协议包括服务器认证、客户认证、SSL 链路上的数据完…

MySQL - 表达式With as 语句的使用及练习

目录 8.1 WITH AS 的含义 8.2 WITH AS语法的基本结构如下&#xff1a; 8.3 练习题1 8.4 牛客练习题 8.1 WITH AS 的含义 WITH AS 语法是MySQL中的一种临时结果集&#xff0c;它可以在SELECT、INSERT、UPDATE或DELETE语句中使用。通过使用WITH AS语句&#xff0c;可以将一个查…

Python os模块及用法

os 模块代表了程序所在的操作系统&#xff0c;主要用于获取程序运行所在操作系统的相关信息。 在 Python 的交互式解释器中先导入 os 模块&#xff0c;然后输入 os.__all__ 命令&#xff08;__all__ 变量代表了该模块开放的公开接口&#xff09;&#xff0c;即可看到该模块所包…

从浅入深掌握进阶结构体(C语言)

前言 这一期我们将继续讲解结构体的知识&#xff0c;还没有看过上一期的小伙伴一定要赶紧去学习哦。 上一期&#xff0c;冲鸭&#xff01; 那么话不多说我们开始今天的学习吧&#xff01; 文章目录 1,结构体的自引用2,匿名结构体3,位段4,结构体的传参5,尾声 1,结构体的自引用 …

Swift 如何实现自定义 Tab Bar

前言 每个 UI 设计师都喜欢美丽而有动画效果的 Tab Bar。然而&#xff0c;对于开发人员来说&#xff0c;实现这种设计可能是一场噩梦。当然&#xff0c;使用 Apple 的原生 Tab Bar 组件并专注于更有趣的事情&#xff0c;比如业务逻辑的实现&#xff0c;会更容易。但如果我们必…

IC入门必看| 数字IC前端设计学习路线与方法(内附学习视频)

众所周知&#xff0c;数字前端设计对于工程师的能力要求比较高&#xff0c;不仅有学历上的要求&#xff0c;还要求掌握很多的知识技能。 数字前端到底是什么&#xff1f; 集成电路设计&#xff08;Integrated Circuit&#xff0c;简称IC&#xff09;一般分为数字IC设计、模拟…