环信IM Demo登录方式如何修改为自己项目的?

在环信即时通讯云IM 官网下载Demo,本地运行只有手机+验证码的方式登录?怎么更改为自己项目的Appkey和用户去进行登录呢?

👇👇👇本文以Web端为例,教大家如何更改代码来实现

1、 VUE2 Demo

vue2 demo源码下载

vue2 demo线上体验

第一步:更改appkey

webim-vue-demo===>src===>utils===>WebIMConfig.js
在这里插入图片描述

第二步:更改代码

webim-vue-demo===>src===>pages===>login===>index.vue

<template><a-layout><div class="login"><div class="login-panel"><div class="logo">Web IM</div><a-input v-model="username" :maxLength="64" placeholder="用户名" /><a-input v-model="password" :maxLength="64" v-on:keyup.13="toLogin" type="password" placeholder="密码" /><a-input v-model="nickname" :maxLength="64" placeholder="昵称" v-show="isRegister == true" /><a-button type="primary" @click="toRegister" v-if="isRegister == true">注册</a-button><a-button type="primary" @click="toLogin" v-else>登录</a-button></div><p class="tip" v-if="isRegister == true">已有账号?<span class="green" v-on:click="changeType">去登录</span></p><p class="tip" v-else>没有账号?<span class="green" v-on:click="changeType">注册</span></p><!-- <div class="login-panel"><div class="logo">Web IM</div><a-form :form="form" ><a-form-item has-feedback><a-inputplaceholder="手机号码"v-decorator="['phone',{rules: [{ required: true, message: 'Please input your phone number!' }],},]"style="width: 100%"><a-selectinitialValue="86"slot="addonBefore"v-decorator="['prefix', { initialValue: '86' }]"style="width: 70px"><a-select-option value="86">+86</a-select-option></a-select></a-input></a-form-item><a-form-item><a-row :gutter="8"><a-col :span="14"><a-inputplaceholder="短信验证码"v-decorator="['captcha',{ rules: [{ required: true, message: 'Please input the captcha you got!' }] },]"/></a-col><a-col :span="10"><a-button v-on:click="getSmsCode" class="getSmsCodeBtn">{{btnTxt}}</a-button></a-col></a-row></a-form-item><a-button style="width: 100%" type="primary" @click="toLogin" class="login-rigester-btn">登录</a-button></a-form> --><!-- </div> --></div></a-layout>
</template><script>
import './index.less';
import { mapState, mapActions } from 'vuex';
import axios from 'axios'
import { Message } from 'ant-design-vue';
const domain = window.location.protocol+'//a1.easemob.com'
const userInfo = localStorage.getItem('userInfo') && JSON.parse(localStorage.getItem('userInfo'));
let times = 60;
let timer
export default{data(){return {username: userInfo && userInfo.userId || '',password: userInfo && userInfo.password || '',nickname: '',btnTxt: '获取验证码'};},beforeCreate() {this.form = this.$form.createForm(this, { name: 'register' });},mounted: function(){const path = this.isRegister ? '/register' : '/login';if(path !== location.pathname){this.$router.push(path);}if(this.isRegister){this.getImageVerification()}},watch: {isRegister(result){if(result){this.getImageVerification()}}},components: {},computed: {isRegister(){return  this.$store.state.login.isRegister;},imageUrl(){return this.$store.state.login.imageUrl},imageId(){return this.$store.state.login.imageId}},methods: {...mapActions(['onLogin', 'setRegisterFlag', 'onRegister', 'getImageVerification', 'registerUser', 'loginWithToken']),toLogin(){this.onLogin({username: this.username.toLowerCase(),password: this.password});// const form = this.form;// form.validateFields(['phone', 'captcha'], { force: true }, (err, value) => {// 	if(!err){// 		const {phone, captcha} = value// 		this.loginWithToken({phone, captcha})// 	}// });},toReset(){this.$router.push('/resetpassword')},toRegister(e){e.preventDefault(e);// this.form.validateFieldsAndScroll((err, values) => {//     if (!err) {//     	this.registerUser({//     		userId: values.username,//             userPassword: values.password,//             phoneNumber: values.phone,//             smsCode: values.captcha,//     	})//     }// });this.onRegister({username: this.username.toLowerCase(),password: this.password,nickname: this.nickname.toLowerCase(),});},changeType(){this.setRegisterFlag(!this.isRegister);},getSmsCode(){if(this.$data.btnTxt != '获取验证码') returnconst form = this.form;form.validateFields(['phone'], { force: true }, (err, value) => {if(!err){const {phone, imageCode} = valuethis.getCaptcha({phoneNumber: phone, imageCode})}});},getCaptcha(payload){const self = thisconst imageId = this.imageIdaxios.post(domain+`/inside/app/sms/send/${payload.phoneNumber}`, {phoneNumber: payload.phoneNumber,}).then(function (response) {Message.success('短信已发送')self.countDown()}).catch(function (error) {if(error.response && error.response.status == 400){if(error.response.data.errorInfo == 'Image verification code error.'){self.getImageVerification()}if(error.response.data.errorInfo == 'phone number illegal'){Message.error('请输入正确的手机号!')}else if(error.response.data.errorInfo == 'Please wait a moment while trying to send.'){Message.error('你的操作过于频繁,请稍后再试!')}else if(error.response.data.errorInfo.includes('exceed the limit')){Message.error('获取已达上限!')}else{Message.error(error.response.data.errorInfo)}}});},countDown(){this.$data.btnTxt = timestimer = setTimeout(() => {this.$data.btnTxt--times--if(this.$data.btnTxt === 0){times = 60this.$data.btnTxt = '获取验证码'return clearTimeout(timer)}this.countDown()}, 1000)}}
};
</script>

webim-vue-demo===>src===>store===>login.js
只用更改actions下的onLogin,其余不用动

onLogin: function(context, payload){context.commit('setUserName', payload.username);let options = {user: payload.username,pwd: payload.password,appKey: WebIM.config.appkey,apiUrl: 'https://a1.easecdn.com'};WebIM.conn.open(options).then((res)=>{localStorage.setItem('userInfo', JSON.stringify({ userId: payload.username, password: payload.password,accessToken:res.accessToken}));});},

2、VUE3 DEMO:

vue3 demo源码下载

vue3 demo线上体验

第一步:更改appkey

webim-vue-demo===>src===>IM===>config===>index.js

c27eca4aefd5861bb4014d86d7b080de.png

第二步:更改代码

webim-vue-demo===>src===>views===>Login===>components===>LoginInput===>index.vue

<script setup>
import { ref, reactive, watch, computed } from 'vue'
import { ElMessage } from 'element-plus'
import { EaseChatClient } from '@/IM/initwebsdk'
import { handleSDKErrorNotifi } from '@/utils/handleSomeData'
import { fetchUserLoginSmsCode, fetchUserLoginToken } from '@/api/login'
import { useStore } from 'vuex'
import { usePlayRing } from '@/hooks'
const store = useStore()
const loginValue = reactive({phoneNumber: '',smsCode: ''
})
const buttonLoading = ref(false)
//根据登陆初始化一部分状态
const loginState = computed(() => store.state.loginState)
watch(loginState, (newVal) => {if (newVal) {buttonLoading.value = falseloginValue.phoneNumber = ''loginValue.smsCode = ''}
})
const rules = reactive({phoneNumber: [{ required: true, message: '请输入手机号', trigger: 'blur' },{pattern: /^1[3-9]\d{9}$/,message: '请输入正确的手机号',trigger: ['blur', 'change']}],smsCode: [{required: true,message: '请输入短信验证码',trigger: ['blur', 'change']}]
})
//登陆接口调用
const loginIM = async () => {const { clickRing } = usePlayRing()clickRing()buttonLoading.value = true/* SDK 登陆的方式 */try {let { accessToken } = await EaseChatClient.open({user: loginValue.phoneNumber.toLowerCase(),pwd: loginValue.smsCode.toLowerCase(),});window.localStorage.setItem(`EASEIM_loginUser`, JSON.stringify({ user: loginValue.phoneNumber, accessToken: accessToken }))} catch (error) {console.log('>>>>登陆失败', error);const { data: { extraInfo } } = errorhandleSDKErrorNotifi(error.type, extraInfo.errDesc);loginValue.phoneNumber = '';loginValue.smsCode = '';}finally {buttonLoading.value = false;}/*  !环信后台接口登陆(仅供环信线上demo使用!) */// const params = {//     phoneNumber: loginValue.phoneNumber.toString(),//     smsCode: loginValue.smsCode.toString()// }// try {//     const res = await fetchUserLoginToken(params)//     if (res?.code === 200) {//         console.log('>>>>>>登陆token获取成功', res.token)//         EaseChatClient.open({//             user: res.chatUserName.toLowerCase(),//             accessToken: res.token//         })//         window.localStorage.setItem(//             'EASEIM_loginUser',//             JSON.stringify({//                 user: res.chatUserName.toLowerCase(),//                 accessToken: res.token//             })//         )//     }// } catch (error) {//     console.log('>>>>登陆失败', error)//     if (error.response?.data) {//         const { code, errorInfo } = error.response.data//         if (errorInfo.includes('does not exist.')) {//             ElMessage({//                 center: true,//                 message: `用户${loginValue.username}不存在!`,//                 type: 'error'//             })//         } else {//             handleSDKErrorNotifi(code, errorInfo)//         }//     }// } finally {//     buttonLoading.value = false// }
}
/* 短信验证码相关 */
const isSenedAuthCode = ref(false)
const authCodeNextCansendTime = ref(60)
const sendMessageAuthCode = async () => {const phoneNumber = loginValue.phoneNumbertry {await fetchUserLoginSmsCode(phoneNumber)ElMessage({type: 'success',message: '验证码获取成功!',center: true})startCountDown()} catch (error) {ElMessage({ type: 'error', message: '验证码获取失败!', center: true })}
}
const startCountDown = () => {isSenedAuthCode.value = truelet timer = nulltimer = setInterval(() => {if (authCodeNextCansendTime.value <= 60 &&authCodeNextCansendTime.value > 0) {authCodeNextCansendTime.value--} else {clearInterval(timer)timer = nullauthCodeNextCansendTime.value = 60isSenedAuthCode.value = false}}, 1000)
}
</script><template><el-form :model="loginValue" :rules="rules"><el-form-item prop="phoneNumber"><el-inputclass="login_input_style"v-model="loginValue.phoneNumber"placeholder="手机号"clearable/></el-form-item><el-form-item prop="smsCode"><el-inputclass="login_input_style"v-model="loginValue.smsCode"placeholder="请输入短信验证码"><template #append><el-buttontype="primary":disabled="loginValue.phoneNumber && isSenedAuthCode"@click="sendMessageAuthCode"v-text="isSenedAuthCode? `${authCodeNextCansendTime}S`: '获取验证码'"></el-button></template></el-input></el-form-item><el-form-item><div class="function_button_box"><el-buttonv-if="loginValue.phoneNumber && loginValue.smsCode"class="haveValueBtn":loading="buttonLoading"@click="loginIM">登录</el-button><el-button v-else class="notValueBtn">登录</el-button></div></el-form-item></el-form>
</template><style lang="scss" scoped>
.login_input_style {margin: 10px 0;width: 400px;height: 50px;padding: 0 16px;
}::v-deep .el-input__inner {padding: 0 20px;font-style: normal;font-weight: 400;font-size: 14px;line-height: 20px;letter-spacing: 1.75px;color: #3a3a3a;&::placeholder {font-family: 'PingFang SC';font-style: normal;font-weight: 400;font-size: 14px;line-height: 20px;/* identical to box height */letter-spacing: 1.75px;color: #cccccc;}
}::v-deep .el-input__suffix-inner {font-size: 20px;margin-right: 15px;
}::v-deep .el-form-item__error {margin-left: 16px;
}::v-deep .el-input-group__append {background: linear-gradient(90deg, #04aef0 0%, #5a5dd0 100%);width: 60px;color: #fff;border: none;font-weight: 400;button {font-weight: 300;}
}.login_text {font-family: 'PingFang SC';font-style: normal;font-weight: 400;font-size: 12px;line-height: 17px;text-align: right;.login_text_isuserid {display: inline-block;// width: 100px;color: #f9f9f9;}.login_text_tologin {margin-right: 20px;width: 80px;color: #05b5f1;cursor: pointer;&:hover {text-decoration: underline;}}
}.function_button_box {margin-top: 10px;width: 400px;button {margin: 10px;width: 380px;height: 50px;border-radius: 57px;}.haveValueBtn {background: linear-gradient(90deg, #04aef0 0%, #5a5dd0 100%);border: none;font-weight: 300;font-size: 17px;color: #f4f4f4;&:active {background: linear-gradient(90deg, #0b83b2 0%, #363df4 100%);}}.notValueBtn {border: none;font-weight: 300;font-size: 17px;background: #000000;mix-blend-mode: normal;opacity: 0.3;color: #ffffff;cursor: not-allowed;}
}
</style>

3、React DEMO:

React Demo源码下载

React Demo线上体验

第一步:更改appkey

webim-dev===>demo===>src===>config===>WebIMConfig.js
在这里插入图片描述

第二步:更改代码

webim-dev===>demo===>src===>config===>WebIMConfig.js
将usePassword改为true

在这里插入图片描述

4、Uniapp Demo:

uniapp vue2 demo源码下载

uniapp vue3 demo源码下载

第一步:更改appkey

uniapp vue2 demo
webim-uniapp-demo===>utils===>WebIMConfig.js
在这里插入图片描述

uniapp vue3 demo
webim-uniapp-demo===>EaseIM===>config===>index.js

7fc3d3d4077b50be4fdba689acb2f9a4.png

第二步:更改代码

webim-uniapp-demo===>pages===>login===>login.vue

c18a811eba8546dc53bebca8fa0b31da.png

5、微信小程序 Demo:

微信小程序源码下载

第一步:更改appkey

webim-weixin-demo===>src===>utils===>WebIMConfig.js

109f65d6690a9ace085c47e9b5e9eb49.png

第二步:更改代码

webim-weixin-demo===>src===>pages===>login===>login.wxml

<import src="../../comps/toast/toast.wxml" />
<view class="login">
<view class="login_title">
<text bindlongpress="longpress">登录</text>
</view><!-- 测试用 请忽略 -->
<view class="config" wx:if="{{ show_config }}">
<view>
<text>使用沙箱环境</text>
<switch class="config_swich" checked="{{isSandBox? true: false}}" color="#0873DE" bindchange="changeConfig" />
</view>
</view><view class="login_user {{nameFocus}}">
<input type="text" placeholder="请输入用户名" placeholder-style="color:rgb(173,185,193)" bindinput="bindUsername" bindfocus="onFocusName" bindblur="onBlurName" />
</view>
<view class="login_pwd {{psdFocus}}">
<input type="text" password placeholder="用户密码" placeholder-style="color:rgb(173,185,193)" bindinput="bindPassword" bindfocus="onFocusPsd" bindblur="onBlurPsd"/>
</view>
<view class="login_btn">
<button hover-class="btn_hover" bind:tap="login">登录</button>
</view>
<template is="toast" data="{{ ..._toast_ }}"></template>
</view>

webim-weixin-demo===>src===>pages===>login===>login.js

let WebIM = require("../../utils/WebIM")["default"];
let __test_account__, __test_psword__;
let disp = require("../../utils/broadcast");let runAnimation = true
Page({
data: {
name: "",
psd: "",
grant_type: "password",
rtcUrl: '',
show_config: false,
isSandBox: false
},statechange(e) {
console.log('live-player code:', e.detail.code)
},error(e) {
console.error('live-player error:', e.detail.errMsg)
},onLoad: function(option){
const me = this;
const app = getApp();
new app.ToastPannel.ToastPannel();disp.on("em.xmpp.error.passwordErr", function(){
me.toastFilled('用户名或密码错误');
});
disp.on("em.xmpp.error.activatedErr", function(){
me.toastFilled('用户被封禁');
});wx.getStorage({
key: 'isSandBox',
success (res) {
console.log(res.data)
me.setData({
isSandBox: !!res.data
})
}
})if (option.username && option.password != '') {
this.setData({
name: option.username,
psd: option.password
})
}
},bindUsername: function(e){
this.setData({
name: e.detail.value
});
},bindPassword: function(e){
this.setData({
psd: e.detail.value
});
},
onFocusPsd: function(){
this.setData({
psdFocus: 'psdFocus'
})
},
onBlurPsd: function(){
this.setData({
psdFocus: ''
})
},
onFocusName: function(){
this.setData({
nameFocus: 'nameFocus'
})
},
onBlurName: function(){
this.setData({
nameFocus: ''
})
},login: function(){
runAnimation = !runAnimation
if(!__test_account__ && this.data.name == ""){
this.toastFilled('请输入用户名!')
return;
}
else if(!__test_account__ && this.data.psd == ""){
this.toastFilled('请输入密码!')
return;
}
wx.setStorage({
key: "myUsername",
data: __test_account__ || this.data.name.toLowerCase()
});getApp().conn.open({
user: __test_account__ || this.data.name.toLowerCase(),
pwd: __test_psword__ || this.data.psd,
grant_type: this.data.grant_type,
appKey: WebIM.config.appkey
});
},longpress: function(){
console.log('长按')
this.setData({
show_config: !this.data.show_config
})
},changeConfig: function(){
this.setData({
isSandBox: !this.data.isSandBox
}, ()=>{
wx.setStorage({
key: "isSandBox",
data: this.data.isSandBox
});
})}});

相关文档:

注册环信:https://console.easemob.com/user/register

集成文档:https://docs-im-beta.easemob.com/document/ios/quickstart.html

社区支持:https://www.imgeek.net/

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

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

相关文章

叉车车载终端定制_基于MT6762安卓核心板的车载终端设备方案

叉车车载终端是一款专为叉车车载场景设计的4英寸Android车载平板电脑。它采用了高能低耗的8核ARM架构处理器和交互开放的Android 12操作系统&#xff0c;算力表现强大。此外&#xff0c;该产品还具备丰富的Wi-Fi-5、4G LTE和蓝牙等通讯功能&#xff0c;可选配外部车载蘑菇天线&…

【麒麟V10系统x86环境--bash: ./install:/bin/bash:解释器错误: 权限不够】

不知道那位大拿分享的这个神操作、给力呀 标题-bash: ./install&#xff1a;/bin/bash&#xff1a;解释器错误: 权限不够 执行这个命令即可&#xff1b;sudo setstatus Softmode

Ubuntu server搭建dhcp服务器

安装 直接使用一下命令进行安装 apt-get install isc-dhcp-server 以下就是安装好的图片 然后进入dhcp目录 cd /etc/dhcp 进入后用ls查看当前目录存在哪些文件 使用如下进入dhcp.conf vim dhcpd.conf 红&#xff1a;设置ip域和子网掩码 绿&#xff1a;设置ip池范围 黄…

t2vec code

文章目录 执行过程preprocess.jl 解释h5 文件结构 执行过程 (base) zzqserver1:~/project/t2vec/preprocessing$ julia porto2h5.jl Processing 1710660 trips… 100000 200000 300000 400000 500000 600000 700000 800000 900000 1000000 1100000 1200000 1300000 1400000 15…

2024最新适用于 Windows 、Mac 的最佳屏幕录制软件

屏幕录制软件可以帮助我们录制 PC 和MacBook的实时屏幕视频。如果您想为 优酷录制视频&#xff0c;或者您正在为您的公司制作基于视频的项目&#xff0c;并且需要捕获屏幕的实时视频录制&#xff0c;那么我们在此列出了 一 款适合您的 Windows 、Mac的 2024 年最佳屏幕录制软件…

锤科HandShaker修改版,支持安卓14、澎湃OS

如今几乎各家手机厂商都在布局生态&#xff0c;但PC端往往是最容易被忽略的一环&#xff0c;哪怕是很强的华为鸿蒙、小米澎湃&#xff0c;想要做到手机和电脑互联&#xff0c;也限制了笔记本机型 虽然我一直致力于解锁非小米电脑安装小米电脑管家&#xff0c;比如前几天刚刚更…

决策树(公式推导+举例应用)

文章目录 引言决策树学习基本思路划分选择信息熵信息增益增益率&#xff08;C4.5&#xff09;基尼指数&#xff08;CART&#xff09; 剪枝处理预剪枝&#xff08;逐步构建决策树&#xff09;后剪枝&#xff08;先构建决策树再剪枝&#xff09; 连续值与缺失值处理连续值处理缺失…

考古学家 - 华为OD统一考试

OD统一考试 分值&#xff1a; 200分 题解&#xff1a; Java / Python / C 题目描述 有一个考古学家发现一个石碑&#xff0c;但是很可惜发现时其已经断成多段。 原地发现N个断口整齐的石碑碎片&#xff0c;为了破解石碑内容&#xff0c;考古学家希望有程序能帮忙计算复原后的石…

精品公式——“V型反转”,精准把握V型反转行情,主副图分享

► 日线表现 代码评估 技术指标代码评估&#xff1a; M5, M14, M25 - 指数移动平均线&#xff08;EMA&#xff09;: M5:EMA(C,5),COLORLIBLUE;&#xff1a;5日指数移动平均线&#xff0c;用浅蓝色表示。 M14:EMA(C,13),COLORF00FF0;&#xff1a;13日指数移动平均线&#xff…

定时任务框架-xxljob

spring传统的定时任务Scheduled&#xff0c;但是这样存在这一些问题 &#xff1a; 做集群任务的重复执行问题 cron表达式定义在代码之中&#xff0c;修改不方便 定时任务失败了&#xff0c;无法重试也没有统计 如果任务量过大&#xff0c;不能有效的分片执行 1.分布式任务调…

详解矩阵的正交化(附例题分析)

目录 一. 矩阵Gram-Schmidt正交化的好处 二. 矩阵标准正交化过程 三. 例题 3.1 标准正交化 3.2 算法小结 3.3 优化分析 四. 小结 矩阵有两类等价关系 矩阵对角化 特殊矩阵 一. 矩阵Gram-Schmidt正交化的好处 假如有三个线性独立的向量a,b,c&#xff0c;他们是标准正…

Word不同部分(分节)设置页眉和页码的使用指南——附案例操作

Word页眉和页码分节设置的使用指南 目录 Word页眉和页码分节设置的使用指南摘要1. 插入分节符2. 设置不同的页眉3. 设置不同的页码4. 调整页码的起始值5. 删除或更改分节6. 预览和调整 摘要 在撰写word文档时&#xff0c;我们经常需要在不同的部分应用不同的页眉和页码格式。在…

2024年 最新 iPhone手机 历代机型、屏幕尺寸、纵横比、分辨率 整理

&#x1f3ac; 博客主页&#xff1a;https://xiaoy.blog.csdn.net &#x1f3a5; 本文由 呆呆敲代码的小Y 原创&#xff0c;首发于 CSDN&#x1f649; &#x1f384; 学习专栏推荐&#xff1a;Unity系统学习专栏 &#x1f332; 游戏制作专栏推荐&#xff1a;游戏制作 &…

数字信号处理 唐向宏著 pdf +课后答案 免费下载

数字信号处理——原理、实现与仿真 pdf 唐向宏著 &#xff0b;课后答案 杭州电子科技大学 费劲心思在网上花钱买的&#xff0c;共享给大家 永久链接&#xff1a;https://wwi.lanzoup.com/b0140pf4f 密码&#xff1a;aflj 里面除了有原书PDF&#xff0c;还有课后题答案

启动redis出现Creating Server TCP listening socket 127.0.0.1:6379: bind: No error异常

1.进入redis安装目录&#xff0c;地址栏输入cmd 2.输入命令 redis-server.exe redis.windows.conf redis启动失败 解决&#xff0c;输入命令 #第一步 redis-cli.exe#第二步 shutdown#第三步 exit第四步 redis-server.exe redis.windows.conf 显示以下图标即成功

日程安排小程序实战教程

日常中我们经常有一些事情需要提醒自己&#xff0c;使用日历的形式比较符合实际的使用习惯。本篇我们就利用微搭低代码工具带着大家开发一款日程安排的小程序。 1 创建数据源 登录微搭低代码控制台&#xff0c;打开数据模型&#xff0c;点击创建 输入数据源的名称日程安排 …

【PaperReading- VLM】1. FERRET

CategoryContent论文题目FERRET: REFER AND GROUND ANYTHING ANYWHERE AT ANY GRANULARITY作者Haoxuan You (Columbia University), Haotian Zhang, Zhe Gan, Xianzhi Du, Bowen Zhang, Zirui Wang, Liangliang Cao (Apple AI/ML), Shih-Fu Chang (Columbia University), Yinfe…

【【深入浅出了解静态时钟分析和时钟约束】】

深入浅出了解静态时钟分析和时钟约束 时序分析是什么&#xff1f; 我们提出一些特定的时序要求&#xff08;或者说是添加特定的时序约束&#xff09;&#xff0c;使用特定的时序模型&#xff0c;针对特定的电路进行分析。分析的最终结果是要求系统时序满足我们提出的要求。 这…

Flink异步IO

本文讲解 Flink 用于访问外部数据存储的异步 I/O API。对于不熟悉异步或者事件驱动编程的用户,建议先储备一些关于 Future 和事件驱动编程的知识。 本文代码gitee地址: https://gitee.com/ddxygq/BigDataTechnical/blob/main/Flink/src/main/java/operator/AsyncIODemo.java …

【HarmonyOS4.0】第九篇-ArkUI布局容器组件(一)

容器组件指的是它可以包含一个或多个子组件的组件&#xff0c;除了前边介绍过的公共属性外。 一、线性布局容器&#xff08;Row、Column&#xff09; 线性容器类表示按照水平方向或者竖直方向排列子组件的容器&#xff0c;ArkUI开发框架通过 Row 和 Colum 来实现线性布局。 …