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

2024-01-09

在环信即时通讯云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-input
			      	placeholder="手机号码"
			        v-decorator="[
			          'phone',
			          {
			            rules: [{ required: true, message: 'Please input your phone number!' }],
			          },
			        ]"
			        style="width: 100%"
			      >
			        <a-select
			          initialValue="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-input
			          	placeholder="短信验证码"
			            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 != '获取验证码') return
			const form = this.form;
		    form.validateFields(['phone'], { force: true }, (err, value) => {
		    	if(!err){
		    		const {phone, imageCode} = value
		    		this.getCaptcha({phoneNumber: phone, imageCode})
		    	}
		    });
		},
		getCaptcha(payload){
			const self = this
			const imageId = this.imageId
			axios.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 = times
			timer = setTimeout(() => {
				this.$data.btnTxt--
				times--
				if(this.$data.btnTxt === 0){
					times = 60
					this.$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 = false
        loginValue.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 } } = error
      handleSDKErrorNotifi(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.phoneNumber
    try {
        await fetchUserLoginSmsCode(phoneNumber)
        ElMessage({
            type: 'success',
            message: '验证码获取成功!',
            center: true
        })
        startCountDown()
    } catch (error) {
        ElMessage({ type: 'error', message: '验证码获取失败!', center: true })
    }
}
const startCountDown = () => {
    isSenedAuthCode.value = true
    let timer = null
    timer = setInterval(() => {
        if (
            authCodeNextCansendTime.value <= 60 &&
            authCodeNextCansendTime.value > 0
        ) {
            authCodeNextCansendTime.value--
        } else {
            clearInterval(timer)
            timer = null
            authCodeNextCansendTime.value = 60
            isSenedAuthCode.value = false
        }
    }, 1000)
}
</script>

<template>
    <el-form :model="loginValue" :rules="rules">
        <el-form-item prop="phoneNumber">
            <el-input
                class="login_input_style"
                v-model="loginValue.phoneNumber"
                placeholder="手机号"
                clearable
            />
        </el-form-item>
        <el-form-item prop="smsCode">
            <el-input
                class="login_input_style"
                v-model="loginValue.smsCode"
                placeholder="请输入短信验证码"
            >
                <template #append>
                    <el-button
                        type="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-button
                    v-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/

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

  • Chart.js 在初始化时设置活动段

    我正在使用 Chart js v2 并且尝试在加载图表时模拟圆环图上某个段的 悬停状态 因此看起来有一个部分已突出显示 我已经搜索和梳理了代码一天 但找不到一个好的方法来做到这一点 提前致谢 设置片段的悬停样式有点令人困惑 因为它没有真正记
  • socket.io 的良好初学者教程? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • JavaScript 中的埃拉托斯特尼筛法对大量数据无限运行

    我一直在尝试写埃拉托斯特尼筛法 http en wikipedia org wiki Sieve of EratosthenesJavaScript 中的算法 基本上我只是按照以下步骤操作 创建从 2 到 n 1 的连续整数列表 令第一个素
  • 为什么 iife 在一个简单的例子中不起作用?

    我不明白为什么函数表达式调用不起作用并抛出错误 你能给我解释一下吗 var a function x alert x function a 1 谢谢大家 任务比我想象的要容易得多 这是因为 JS 将 IIFE 解析为函数的参数调用 这样做时
  • Three.js:缩放几何图形后错误的 BoundingBox

    在我的场景中 我有一个简单的立方体 var test new THREE Mesh new THREE CubeGeometry 10 10 10 new THREE MeshBasicMaterial scene add test 该立方
  • 如何更改 Google Maps v3 API for Directions 中的开始和结束标记图像

    我使用 DirectionsRender 绘制了一条路线 但我不知道如何用我自己的标记替换通用的 Google 标记 我知道并在正常的谷歌地图情况下使用它 但发现很难用开始和结束的方向标记来做到这一点 如果这是一个愚蠢的问题 感谢您的任何建
  • Snap.svg - 停止在可悬停元素的子元素上重新触发悬停事件

    对于一个项目 我使用的 SVG 形状由背景多边形和背景多边形上方的一些文本 我已将其转换为路径 组成 我正在使用 Snap svg 为我的形状设置动画 当我将鼠标悬停在多边形上时 形状应该缩放到特定尺寸 包括其中的所有内容 鼠标移开时 形状
  • Bootstrap按钮加载+Ajax

    我正在使用 Twitter Bootstrap 的按钮加载状态 http twitter github com bootstrap javascript html buttons http twitter github com bootst
  • 调整图像大小并将画布旋转 90 度

    这里有很多关于在 js 上使用画布旋转图像的主题 我阅读了其中的大部分内容 但无法找到解决我的问题的方法 我正在接收任何分辨率的图像 来自上传组件 我将其大小调整为 1024x768 如下所示 var canvas document cre
  • 使用 CSS 或 Javascript 填充动画

    我只是想知道是否可以使用 CSS 或 javascript 创建填充动画 基本上我想创建一个填充动画 如下图所示 http i40 tinypic com eit6ia png http i40 tinypic com eit6ia png
  • 在 HTML5 画布中,如何用我选择的背景遮盖图像?

    我试图用画布来实现这一点 globalCompositeOperation 但没有运气 所以我在这里问 这里有类似的问题 但我没有在其中找到我的案例 我的画布区域中有图层 从下到上的绘制顺序 画布底座填充纯白色 fff 用fillRect
  • Javascript split 不是一个函数

    嘿朋友们 我正在使用 javascript sdk 通过 jQuery facebook 多朋友选择器在用户朋友墙上发布信息 但是我收到此错误friendId split 不是函数 这是我的代码 function recommendToFr
  • Vuejs 2:去抖动不适用于手表选项

    当我在 VueJs 中反跳此函数时 如果我提供毫秒数作为原语 它就可以正常工作 但是 如果我将其提供为对 prop 的引用 它会忽略它 这是道具的缩写版本 props debounce type Number default 500 这是不
  • 可以设置标题样式吗? (并且使用CSS或js?)[重复]

    这个问题在这里已经有答案了 我想知道是否可以设计一个title a href title This is a title Hello a 样式问题有两个方面 文本格式 编码 我猜这是可能的 所以在问题中这样做 工具提示样式 你能把它弄大一点
  • Three.js 各种大小的粒子

    我是 Three js 的新手 正在尝试找出添加 1000 个粒子的最佳方法 每个粒子都有不同的大小和颜色 每个粒子的纹理是通过绘制画布创建的 通过使用粒子系统 所有粒子都具有相同的颜色和大小 为每个粒子创建一个粒子系统是非常低效的 有没有
  • 使用 Vue 的多模式组件

    我在 Vue 中实现动态模式组件时遇到问题 A common approach I follow to display a set of data fetched from the db is I dump each of the rows
  • Vue 和 Vuex:处理依赖的计算属性

    我的应用程序是一个使用 Vuex 在 Vue 中构建的精简电子表格 关键组件是TableCollection Table and Row The TableCollection有一个包含多个的数组Table对象 每个Table有一个包含多个
  • 如何隐藏/禁用 Highcharts.js 中的图例框?

    我想问是否可以使用 HighCharts js 库隐藏图表中的所有图例框 var chart object chart renderTo render to type graph type colors graph colors title
  • 带参数的事件监听器

    我想将参数传递给 JavaScript 中的事件侦听器 我已经找到了解决方案 但我无法理解它们为什么或如何工作以及为什么其他解决方案不起作用 我有 C C 背景 但是 Javascript 函数的执行有很大不同 您能否帮助我理解以下示例如何
  • Vue.js[vuex] 如何从突变中调度?

    我有一个要应用于 json 对象的过滤器列表 我的突变看起来像这样 const mutations setStars state payload state stars payload this dispatch filter setRev

随机推荐

  • 双系统安装win7出现grub怎么解决

    我们在重装系统时 特别苹果装双系统时 会出现安装过程或者安装后的问题 发现系统开机显示grub 导致不能正常进入系统 让人很是着急 其实出现这种情况是因为系统找不到主引记录所导致 只要重建主引记录mbr即可解决 下面小编就教教大家win7系
  • 实时获取建材网商品数据:API实现详解与代码示例

    一 引言 随着电子商务的快速发展 实时获取商品数据对于企业决策 市场分析以及数据驱动的营销策略至关重要 建材网作为国内知名的建材信息平台 提供了API接口 使得第三方开发者可以方便地获取商品数据 本文将详细介绍如何使用 建材网的API接口
  • 代码随想录算法训练营Day18 | 二叉搜索树中的插入操作、二叉搜索树的最近公共祖先、删除二叉搜索树的节点、修剪二叉搜索树、二叉搜索树转换成累加树、将有序数组转换成二叉搜索树

    LeetCode 701 二叉搜索树的插入操作 本题思路 既然是二叉搜索树 那么插入就变得比较简单了 因为二叉搜索树的左树节点值都小于根节点值 右树节点值都大于根节点值 直接将要插入的节点值和根节点进行对比 如果比它小 就往左孩子走 比他大
  • go测试覆盖率

    go test cover ok mytest cached coverage 42 9 of statements go test 增加 cover 参数可以查看测试用例的覆盖率 go test coverprofile size cov
  • 从源码角度来谈谈 HashMap

    HashMap的知识点可以说在面试中经常被问到 是Java中比较常见的一种数据结构 所以这一篇就通过源码来深入理解下HashMap 1 HashMap的底层是如何实现的 基于JDK8 1 1 HashMap的类结构和成员 HashMap继承
  • 浅谈归并排序:合并 K 个升序链表的归并解法

    在面试中遇到了这道题 如何实现多个升序链表的合并 这是 LeetCode 上的一道原题 题目具体如下 用归并实现合并 K 个升序链表 LeetCode 23 合并K个升序链表 给你一个链表数组 每个链表都已经按升序排列 请你将所有链表合并到
  • 怎么让gpt给论文降重

    大家好 今天来聊聊怎么让gpt给论文降重 希望能给大家提供一点参考 以下是针对论文重复率高的情况 提供一些修改建议和技巧 可以借助此类工具 怎么让GPT给论文降重 随着人工智能技术的不断发展 GPT 生成型预训练变换器 在论文降重方面的应用
  • Python组装jmx并调用JMeter执行压测

    JMeter 可以通过os命令调用Python脚本 Python同样可以通过系统命令调用JMeter执行压测 Python调用JMeter 首先要安装JMeter 官方下载地址 解压并配置配置环境路径或建立软连 使得在命令输入jmeter便
  • 软件测试开发/全日制/测试管理丨接口功能测试

    在复杂而庞大的软件系统中 各个组件之间的顺畅交流是确保整个系统正常运行的基石 接口功能测试 作为软件测试中的关键环节之一 致力于验证系统中不同部分之间的通信协议和数据传递的正确性 以确保整个系统交流的和谐旋律 了解接口功能测试 接口功能测试
  • 【解决】executable‘s TLS segment is underaligned: alignment is 8, needs to be at least 32 for ARM Bionic

    executable s TLS segment is underaligned alignment is 8 needs to be at least 32 for ARM Bionic 解决办法 使用ndk r21e 指定 sysroo
  • Linux CentOS 8.x、9.x 系统安装启动某些服务报:libtinfo.so.5、libncurses.so.5 的问题,解决方式

    场景 启动服务 xxx server start 报如下问题 error while loading shared libraries libtinfo so 5 cannot open shared object file No such
  • 引用的法条如何降重 GPT改写

    大家好 今天来聊聊引用的法条如何降重 GPT改写 希望能给大家提供一点参考 以下是针对论文重复率高的情况 提供一些修改建议和技巧 可以借助此类工具 引用的法条如何降重 在法学论文中 引用法条是必要的 但直接引用会导致论文重复率过高 那么 如
  • Metasploit安装及使用教程(非常详细)从零基础入门到精通,看完这一篇就够了。

    通过本篇文章 我们将会学习以下内容 1 在Windows上安装Metasploit 2 在Linux和MacOS上安装Metasploit 3 在Kali Linux中使用 Metasploit 4 升级Kali Linux 5 使用虚拟化
  • Sui链上铭文爆火,TPS近6000领先同行

    在2023年接近尾声时 用户涌入众多智能合约平台进行铭文相关交易 无意中对各种网络进行了压力测试 在许多平台出现拥堵和费用飙升的情况下 Sui通过实现令人印象深刻的TPS 在没有减速或gas费用激增的情况下脱颖而出 最初用于比特币的铭文提供
  • vcpkg安装zlmediakit(windows环境)

    文章目录 一 简介 二 vcpkg安装 1 vcpkg源码下载 2 vcpkg安装 三 安装zlmediakit 1 默认安装开启特性 core mp4 openssl webrtc 2 安装全部特性zlmediakit 包括webrtc
  • 职场人最忌讳的10件事:从人性的角度揭示职场中的禁忌行为

    职场人最忌讳的10件事 从人性的角度揭示职场中的禁忌行为 在职场中 每个人都有自己的行为准则和价值观 然而 有些事情却是普遍被认为不可取的 从人性的角度来看 这些事情可能会触碰到人们的某些心理或道德底线 导致他人产生反感或不信任 本文将探讨
  • 服务器超线程的好处

    服务器超线程的好处 1 提高性能 超线程通过提高整体系统吞吐量显着提高服务器性能 通过允许多个线程在单个物理内核上同时执行 超线程减少了空闲时间并最大限度地利用了可用资源 这会加快任务执行速度并缩短应用程序的响应时间 尤其是在多线程工作负载
  • 外包干了2个月,技术退步明显...

    先说一下自己的情况 大专生 18年通过校招进入武汉某软件公司 干了接近4年的功能测试 今年年初 感觉自己不能够在这样下去了 长时间呆在一个舒适的环境会让一个人堕落 而我已经在一个企业干了四年的功能测试 已经让我变得不思进取 谈了2年的女朋友
  • Kali Linux 安全渗透核心总结,444页核心知识点

    就像IT人离不开Linux系统一样 网安人也离不开Kali Linux 作为攻击性防御和渗透测试的代名词 越来越多的人开始学习Kali 如果你也对kali感兴趣 又想深入了解这方面内容 不妨收藏一下这份Kali Linux安全渗透教程 共4
  • 环信IM Demo登录方式如何修改为自己项目的?

    在环信即时通讯云IM 官网下载Demo 本地运行只有 手机 验证码 的方式登录 怎么更改为自己项目的Appkey和用户去进行登录呢 本文以Web端为例 教大家如何更改代码来实现 1 VUE2 Demo vue2 demo源码下载 vue2