微信小程序聊天功能的示例代码


Posted in Javascript onJanuary 13, 2020

效果

微信小程序聊天功能的示例代码

初始化滚动条高度

var keyHeight = 0;

数据格式

const CHAT_DATA=[
 {
  type:0,//0客服1用户
  content:'欢迎欢迎欢迎欢迎欢迎欢迎欢迎欢迎欢迎欢迎欢迎欢迎欢迎欢迎欢迎欢迎欢迎欢迎欢迎欢迎欢迎欢迎欢迎欢迎欢迎欢迎欢迎欢迎',
  headImg:'../../assets/common/images/headHortrait.jpeg',//头像
  creatTime:'2019-01-01',//创建时间
  contentType:'text'
 }, {
  type: 0,//0客服1用户
  content: '1111111',
  headImg: '../../assets/common/images/headHortrait.jpeg',//头像
  creatTime: '2019-01-01',//创建时间
  contentType: 'text'
 }, {
  type: 1,//0客服1用户
  content: '222222',
  headImg: '../../assets/common/images/headHortrait.jpeg',//头像
  creatTime: '2019-01-01',//创建时间
  contentType: 'text'
 }, {
  type: 0,//0客服1用户
  content: '333333',
  headImg: '../../assets/common/images/headHortrait.jpeg',//头像
  creatTime: '2019-01-01',//创建时间
  contentType: 'text'
 }, {
  type: 1,//0客服1用户
  content: '4444444',
  headImg: '../../assets/common/images/headHortrait.jpeg',//头像
  creatTime: '2019-01-01',//创建时间
  contentType: 'text',
 }, {
  type: 0,//0客服1用户
  content: 'http://tmp/wxc79c66d8b0ed19a8.o6zAJs6QE8L8FKq645ts4e3LoKzI.pGakaVHKmbQ3160aa57e2bf33cb576fbabf691cd890b.durationTime=3706.aac',
  headImg: '../../assets/common/images/headHortrait.jpeg',//头像
  creatTime: '2019-01-01',//创建时间
  contentType: 'voice',
  duration: '3706',
 },{
  type: 1,//0客服1用户
  content: 'http://tmp/wxc79c66d8b0ed19a8.o6zAJs6QE8L8FKq645ts4e3LoKzI.pGakaVHKmbQ3160aa57e2bf33cb576fbabf691cd890b.durationTime=3706.aac',
  headImg: '../../assets/common/images/headHortrait.jpeg',//头像
  creatTime: '2019-01-01',//创建时间
  contentType: 'voice',
  duration:'3706'
 },
 {
  type: 1,//0客服1用户
  content: 'https://img.yzcdn.cn/vant/cat.jpeg',
  headImg: '../../assets/common/images/headHortrait.jpeg',//头像
  creatTime: '2019-01-01',//创建时间
  contentType: 'img'
 }, {
  type: 1,//0客服1用户
  content: 'https://img.yzcdn.cn/vant/cat.jpeg',
  headImg: '../../assets/common/images/headHortrait.jpeg',//头像
  creatTime: '2019-01-01',//创建时间
  contentType: 'img'
 }
];

wxml对话框

<block wx:key wx:for='{{chatData}}' wx:for-index="index">

   <!-- 单个消息1 客服发出(左) -->
   <view wx:if='{{item.type==0}}' id='msg-{{index}}' class="contentLeft" style=''>
    <view class="head">
      <image class="headImg" src='{{item.headImg}}' mode='widthFix'></image>
    </view>
    <view class='leftMsg' wx:if="{{item.contentType==='text'}}">{{item.content}}</view>
    <view class='leftMsg' wx:if="{{item.contentType==='voice'}}" data-duration="{{item.content}}">{{item.duration}}s</view>
     
    <view class='leftMsg img' wx:if="{{item.contentType==='img'}}"><image src="{{item.content}}" data-src="{{item.content}}" mode='widthFix' bindtap="onPreview"/></view>
   </view>

   <!-- 单个消息2 用户发出(右) -->
   <view wx:else id='msg-{{index}}' class="contentRight">
    <view class='rightMsg' wx:if="{{item.contentType==='voice'}}" data-duration="{{item.duration}}" bindtap="playRecord" style="width:{{30+item.duration*5}}px;justify-content: flex-end;display:flex;color:#000;">{{item.duration}}"<van-icon name="../../../assets/common/icon/voice-r.png" style="padding:0 0 0 5px;" /></view>
    <view class='rightMsg' wx:if="{{item.contentType==='text'}}">{{item.content}}</view>
    
    <view class='rightMsg img' wx:if="{{item.contentType==='img'}}"><image src="{{item.content}}" data-src="{{item.content}}" mode='widthFix' bindtap="onPreview"/></view>
     <view>
      <image class="headImg" src='{{item.headImg}}' mode='widthFix'></image>
    </view>
   </view>

  </block>

wxml底部输入框

<view class='inputRoom' style='bottom: {{inputBottom}};height: {{bottomHeight}}'>
  <van-row class="bottomRow">
   <van-col span="2"wx:if="{{show}}"> <van-icon bindtap="startRecord" class="iconfont icon" class-prefix='icon' size="40rpx" name="yuyin" ></van-icon></van-col>
    <van-col span="2" wx:if="{{!show}}"> <van-icon bindtap="startRecord" class="iconfont icon" class-prefix='icon' size="40rpx" name="fabiaowenzhang" ></van-icon></van-col>
   <van-col span="18" wx:if="{{show}}"> <input bindconfirm='sendClick'bind:input="inputValue" adjust-position='{{false}}' value='{{inputVal}}' confirm-type='send' bindfocus='focus' bindblur='blur'></input></van-col>
   <van-col span="18" wx:if="{{!show}}"> <view class="holdTape" bind:touchstart="startTalk" bind:touchend='stopRecord'>按住请说话</view></van-col>
   <van-col span="2"><van-icon class="iconfont icon" class-prefix='icon' size="40rpx" name='biaoqing' bindtap="getEmoji"></van-icon></van-col>
   <van-col span="2"><van-uploader use-slot accept='image' bind:after-read="uploadeImg"> <van-icon class="iconfont icon" class-prefix='icon' size="40rpx" name='icon02' ></van-icon></van-uploader></van-col>
  </van-row> 
   <view wx:if="{{showEmoji}}" class="emoji">
   <emoji bind:clickEmoji="clickEmoji" data-key="inputVal" value="{{inputVal}}" />
  </view>
 </view>
  
</view>
<view class="recordDailog" wx:if="{{showDailog}}"  >
<view class="show">
 <image src="../../assets/common/images/record.png"></image>
 <text>{{toastTitle}}</text>
</view>

css

#page{
 height: 90%;
overflow-y: auto;

}
.content{
 background: white;

}

.inputRoom {
 width: 100vw;
 /* height: 16vw; */
 border-top: 1px solid #cdcdcd;
 position: fixed;
 bottom: 0;
 display: flex;
 align-items: center;
 z-index: 20;
 background: white;
 flex-direction: column;

}
.bottomRow{
 width: 100%;
 height: 16vw;
display: flex;
align-items: center;
flex-direction: row
}
.bottomRow .van-row{
 width: 100%;

}
.emoji{
 height: 30vw;
}
input {
width: 90%;
height: 9.33vw;
background-color: #EEF4FA;
border-radius: 6rpx;
font-size: 28rpx;
color: #444;
padding: 0 3%;
margin-left: 2%;
}

.leftMsg {
 font-size: 26rpx;
 color: #333333;
line-height: 6vw;
padding: 2vw 2.5vw;
background-color: #EEF4FA;
 border-radius: 10rpx;
 z-index: 10;
}

.rightMsg {
 font-size: 26rpx;
 color: white;
 line-height: 6vw;
 padding: 2vw 2.5vw;
 background-color: #496DFF;
 border-radius: 10rpx;
 z-index: 10;
}



.chatFrame{
 background: white;
 height: 100%
} 
.icon{
 line-height: 8vw;

}
.head{
 display: flex;
 align-items: center
}
.headImg{
 border-radius: 50%; width: 60rpx;height: 60rpx;
}
.holdTape{
 width: 90%;
height: 9.33vw;
background-color: #EEF4FA;
border-radius: 6rpx;
padding: 0 3%;
margin-left: 2%;
display: flex;
align-items: center;
justify-content: center;

}

.recordDailog{
 -webkit-transition-duration: 300ms;
transition-duration: 300ms;
z-index: 1000;
position: fixed;
top: 50%;
left: 50%;
width: -webkit-fit-content;
width: fit-content;
-webkit-transform: translate(-50%,-50%);
transform: translate(-50%,-50%);
max-width: var(--toast-max-width,70%);

}

.show{
width: var(--toast-default-width,90px);
min-height: var(--toast-default-min-height,90px);
padding: var(--toast-default-padding,16px);
display: flex;
-webkit-flex-direction: column;
flex-direction: column;
-webkit-align-items: center;
align-items: center;
-webkit-justify-content: center;
justify-content: center;
box-sizing: initial;
color: var(--toast-text-color,#fff);
font-size: var(--toast-font-size,14px);
line-height: var(--toast-line-height,20px);
white-space: pre-wrap;
word-wrap: break-word;
background-color: var(--toast-background-color,rgba(50,50,51,.88));
border-radius: var(--toast-border-radius,4px);

}
.show image{
 width: 24px;
 height: 24px
}
image{
 /* max-width: 88vw;
max-height: 400rpx; */
width: 100%
}
.img{
background: none;
width: 90%
}
.contentRight{
 display: flex; justify-content: flex-end; padding: 2vw 2vw 2vw 11vw;width: 86%;
}
.contentLeft{
 display: flex; padding: 2vw 11vw 2vw 2vw;width: 86%;
}

js

// pages/contact/contact.js
const {
 pageFunc
} = require('../../utils/util.js');
const app = getApp();
var windowWidth = wx.getSystemInfoSync().windowWidth;
var windowHeight = wx.getSystemInfoSync().windowHeight;
var keyHeight = 0;
const { CHAT_DATA}=require("../../data/customerService.js");
import Toast from '../../components/vant/toast/toast';
const recorderManager = wx.getRecorderManager();
const innerAudioContext = wx.createInnerAudioContext();
const db = wx.cloud.database();
/**
 * 初始化数据
 */
/**
 * 计算msg总高度
 */
function calScrollHeight(that, keyHeight) {
 var query = wx.createSelectorQuery();
 query.select('.scrollMsg').boundingClientRect(function(rect) {
 }).exec();
}
Page({

 /**
  * 页面的初始数据
  */
 data: {
  scrollHeight: '100vh',
  inputVal:"",
  inputBottom: 0,
  chatData:[],
  show:true,
  showDailog:false,
  bottomHeight:"18vw",
  sendData:{},
  pagination: {
   pageSize: 5,
   currentPage: 1,
   total: 0,
  },
  showEmoji:false,
  toastTitle:"录音中...."
 },

 /**
  * 生命周期函数--监听页面加载
  */
 onLoad: function (options) {
  // this.setData({
  //  cusHeadIcon: app.globalData.userInfo.avatarUrl,
  // });
  const {
   pagination
  } = this.data
  this.getData({ param: CHAT_DATA, pagination });
   wx.pageScrollTo({
    scrollTop: 1000
   })
 },
 getData(params) {
  const { chatData } = this.data;
  const {
   param,
   pagination: {
    pageSize = 10,
    currentPage = 1
   },
  } = params;
  this.setData({
   pagination: { pageSize, currentPage }
  });
  const {
   data,
   pagination
  } = pageFunc(param, currentPage, pageSize);
  data.forEach((item) => {
   if (item.duration) {
    item.duration = Math.ceil(item.duration / 1000)
   }
  });
   this.setData({
    'chatData': data.concat(chatData)
   });
 },
 startRecord(){//开始录音
 const {show}=this.data
  if (show){
   this.setData({
    show: false,
   })
  }else{
   this.setData({
    show: true,
   })
  }
  
  
 },
 startTalk(e){//开始说话
  this.setData({
   showDailog:true,
  })
  const options = {
   duration: 60000,
   sampleRate: 44100,
   numberOfChannels: 1,
   encodeBitRate: 192000,
   format: 'aac',
   frameSize: 50
  }
  recorderManager.start(options)
  recorderManager.onStart((res) => {
  })
 },
 stopRecord(){//停止说话
  const that=this
  this.setData({
   showDailog:false,
  })
  recorderManager.stop();
  recorderManager.onStop((res) => {
   const { sendData, chatData } = that.data;
   let { tempFilePath, duration, fileSize} = res
   sendData.tempFilePathData=res
   duration = Math.ceil(duration / 1000)
   const data = { content: tempFilePath, duration , fileSize, contentType: 'voice', type: 1};
   chatData.push(data);
   wx.createSelectorQuery().select('.content').boundingClientRect(function (rect) {
    // 使页面滚动到底部
    wx.pageScrollTo({
     scrollTop: rect.bottom + 5000
    })
   }).exec();
   that.setData({
    'tempFilePath': tempFilePath,
    sendData,
    chatData,
    scrollHeight: (windowHeight - 0) + 'px',
    toView: 'msg-' + (chatData.length - 1),
    inputBottom: '0px'
   })
  })
 },

 playRecord(e){//播放语音
  const { currentTarget: { dataset: { duration } }}=e;
  const { tempFilePath} = this.data
  innerAudioContext.autoplay = true;
  innerAudioContext.src = tempFilePath ,
   innerAudioContext.onPlay(() => {
    this.setData({
     toastTitle: "播放中....",
     showDailog: true,
    })
   })
  innerAudioContext.onEnded((res) => {
   this.setData({
    toastTitle: "录音中....",
    showDailog: false,
   })
  })
  innerAudioContext.onError((res) => {
  });
  innerAudioContext.play()
 },

 uploadeImg(e){
  const { file: { path,size:fileSize} } = e.detail;
  const { chatData } = this.data;
  const data = { content: path, fileSize, contentType: 'img', type: 1 };
  chatData.push(data);
  wx.createSelectorQuery().select('.content').boundingClientRect(function (rect) {
   // 使页面滚动到底部
   wx.pageScrollTo({
    scrollTop: rect.bottom + 5000
   })
  }).exec()
  this.setData({
   chatData,
   scrollHeight: (windowHeight - 0) + 'px',
   toView: 'msg-' + (chatData.length - 1),
   inputBottom:'0px'
  })
 },
 getEmoji(){//获取表情包
  wx.createSelectorQuery().select('.content').boundingClientRect(function (rect) {
   // 使页面滚动到底部
   wx.pageScrollTo({
    scrollTop: rect.bottom + 5000
   })
  }).exec()
 this.setData({
  showEmoji:true,
  bottomHeight:"48vw"
 })
 },

 clickEmoji: function (e) {//选择表情包
  const {
   detail: {
    value
   },
   currentTarget: {
    dataset: {
     key
    }
   }
  } = e;
  this.setData({
   [key]: value
  })
 },

 onPreview(e){
  const {
   currentTarget: {
    dataset: {
     src
    }
   }
  } = e;
  const urls = [src]
  wx.previewImage({
   current: src,
   urls
  })
 },
 /**
  * 生命周期函数--监听页面显示
  */
 onShow: function () {

 },

 /**
  * 页面相关事件处理函数--监听用户下拉动作
  */
 onPullDownRefresh: function () {
  let { pagination: { currentPage } } = this.data
  this.getData({
   param: CHAT_DATA,
   pagination: {
    pageSize: 5,
    currentPage: currentPage + 1,
   }
  });
 },

 /**
  * 页面上拉触底事件的处理函数
  */
 onReachBottom: function () {

 },

 /**
  * 获取聚焦
  */
 inputValue(e){
  const {detail:{value}}=e
  this.setData({
   inputVal:value
  })
 },
 focus: function (e) {
  const { chatData}=this.data
  keyHeight = e.detail.height;
  wx.pageScrollTo({
   scrollTop: windowHeight - keyHeight
  })
  this.setData({
   toView: 'msg-' + (chatData.length - 1),
   inputBottom: keyHeight + 'px',
   scrollHeight: (windowHeight - keyHeight) + 'px',
   showEmoji:false,
   bottomHeight: "18vw"
  })
  //计算msg高度
  // calScrollHeight(this, keyHeight);

 },

 //失去聚焦(软键盘消失)
 blur: function (e) {
  const { chatData } = this.data
  this.setData({
   scrollHeight: '100vh',
   inputBottom: 0
  })
  this.setData({
   toView: 'msg-' + (chatData.length - 1)
  })

 },

 /**
  * 发送点击监听
  */
 sendClick: function (e) {
  const { chatData, scrollHeight}=this.data;
  wx.createSelectorQuery().select('.content').boundingClientRect(function (rect) {
   // 使页面滚动到底部
   wx.pageScrollTo({
    scrollTop: rect.bottom + 5000
   })
  }).exec()
 
  chatData.push({
   type: 1,
   contentType: 'text',
   content: e.detail.value,
   headImg: '../../assets/common/images/headHortrait.jpeg',
  })
  this.setData({
   chatData,
   inputVal:''
  });


 },

 /**
  * 退回上一页
  */
 toBackClick: function () {
  wx.navigateBack({})
 }

})// pages/contact/contact.js
const {
 pageFunc
} = require('../../utils/util.js');
const app = getApp();
var windowWidth = wx.getSystemInfoSync().windowWidth;
var windowHeight = wx.getSystemInfoSync().windowHeight;
var keyHeight = 0;
const { CHAT_DATA}=require("../../data/customerService.js");
import Toast from '../../components/vant/toast/toast';
const recorderManager = wx.getRecorderManager();
const innerAudioContext = wx.createInnerAudioContext();
const db = wx.cloud.database();
/**
 * 初始化数据
 */
/**
 * 计算msg总高度
 */
function calScrollHeight(that, keyHeight) {
 var query = wx.createSelectorQuery();
 query.select('.scrollMsg').boundingClientRect(function(rect) {
 }).exec();
}
Page({

 /**
  * 页面的初始数据
  */
 data: {
  scrollHeight: '100vh',
  inputVal:"",
  inputBottom: 0,
  chatData:[],
  show:true,
  showDailog:false,
  bottomHeight:"18vw",
  sendData:{},
  pagination: {
   pageSize: 5,
   currentPage: 1,
   total: 0,
  },
  showEmoji:false,
  toastTitle:"录音中...."
 },

 /**
  * 生命周期函数--监听页面加载
  */
 onLoad: function (options) {
  // this.setData({
  //  cusHeadIcon: app.globalData.userInfo.avatarUrl,
  // });
  const {
   pagination
  } = this.data
  this.getData({ param: CHAT_DATA, pagination });
   wx.pageScrollTo({
    scrollTop: 1000
   })
 },
 getData(params) {
  const { chatData } = this.data;
  const {
   param,
   pagination: {
    pageSize = 10,
    currentPage = 1
   },
  } = params;
  this.setData({
   pagination: { pageSize, currentPage }
  });
  const {
   data,
   pagination
  } = pageFunc(param, currentPage, pageSize);
  data.forEach((item) => {
   if (item.duration) {
    item.duration = Math.ceil(item.duration / 1000)
   }
  });
   this.setData({
    'chatData': data.concat(chatData)
   });
 },
 startRecord(){//开始录音
 const {show}=this.data
  if (show){
   this.setData({
    show: false,
   })
  }else{
   this.setData({
    show: true,
   })
  }
  
  
 },
 startTalk(e){//开始说话
  this.setData({
   showDailog:true,
  })
  const options = {
   duration: 60000,
   sampleRate: 44100,
   numberOfChannels: 1,
   encodeBitRate: 192000,
   format: 'aac',
   frameSize: 50
  }
  recorderManager.start(options)
  recorderManager.onStart((res) => {
  })
 },
 stopRecord(){//停止说话
  const that=this
  this.setData({
   showDailog:false,
  })
  recorderManager.stop();
  recorderManager.onStop((res) => {
   const { sendData, chatData } = that.data;
   let { tempFilePath, duration, fileSize} = res
   sendData.tempFilePathData=res
   duration = Math.ceil(duration / 1000)
   const data = { content: tempFilePath, duration , fileSize, contentType: 'voice', type: 1};
   chatData.push(data);
   wx.createSelectorQuery().select('.content').boundingClientRect(function (rect) {
    // 使页面滚动到底部
    wx.pageScrollTo({
     scrollTop: rect.bottom + 5000
    })
   }).exec();
   that.setData({
    'tempFilePath': tempFilePath,
    sendData,
    chatData,
    scrollHeight: (windowHeight - 0) + 'px',
    toView: 'msg-' + (chatData.length - 1),
    inputBottom: '0px'
   })
  })
 },

 playRecord(e){//播放语音
  const { currentTarget: { dataset: { duration } }}=e;
  const { tempFilePath} = this.data
  innerAudioContext.autoplay = true;
  innerAudioContext.src = tempFilePath ,
   innerAudioContext.onPlay(() => {
    this.setData({
     toastTitle: "播放中....",
     showDailog: true,
    })
   })
  innerAudioContext.onEnded((res) => {
   this.setData({
    toastTitle: "录音中....",
    showDailog: false,
   })
  })
  innerAudioContext.onError((res) => {
  });
  innerAudioContext.play()
 },

 uploadeImg(e){
  const { file: { path,size:fileSize} } = e.detail;
  const { chatData } = this.data;
  const data = { content: path, fileSize, contentType: 'img', type: 1 };
  chatData.push(data);
  wx.createSelectorQuery().select('.content').boundingClientRect(function (rect) {
   // 使页面滚动到底部
   wx.pageScrollTo({
    scrollTop: rect.bottom + 5000
   })
  }).exec()
  this.setData({
   chatData,
   scrollHeight: (windowHeight - 0) + 'px',
   toView: 'msg-' + (chatData.length - 1),
   inputBottom:'0px'
  })
 },
 getEmoji(){//获取表情包
  wx.createSelectorQuery().select('.content').boundingClientRect(function (rect) {
   // 使页面滚动到底部
   wx.pageScrollTo({
    scrollTop: rect.bottom + 5000
   })
  }).exec()
 this.setData({
  showEmoji:true,
  bottomHeight:"48vw"
 })
 },

 clickEmoji: function (e) {//选择表情包
  const {
   detail: {
    value
   },
   currentTarget: {
    dataset: {
     key
    }
   }
  } = e;
  this.setData({
   [key]: value
  })
 },

 onPreview(e){
  const {
   currentTarget: {
    dataset: {
     src
    }
   }
  } = e;
  const urls = [src]
  wx.previewImage({
   current: src,
   urls
  })
 },
 /**
  * 生命周期函数--监听页面显示
  */
 onShow: function () {

 },

 /**
  * 页面相关事件处理函数--监听用户下拉动作
  */
 onPullDownRefresh: function () {
  let { pagination: { currentPage } } = this.data
  this.getData({
   param: CHAT_DATA,
   pagination: {
    pageSize: 5,
    currentPage: currentPage + 1,
   }
  });
 },

 /**
  * 页面上拉触底事件的处理函数
  */
 onReachBottom: function () {

 },

 /**
  * 获取聚焦
  */
 inputValue(e){
  const {detail:{value}}=e
  this.setData({
   inputVal:value
  })
 },
 focus: function (e) {
  const { chatData}=this.data
  keyHeight = e.detail.height;
  wx.pageScrollTo({
   scrollTop: windowHeight - keyHeight
  })
  this.setData({
   toView: 'msg-' + (chatData.length - 1),
   inputBottom: keyHeight + 'px',
   scrollHeight: (windowHeight - keyHeight) + 'px',
   showEmoji:false,
   bottomHeight: "18vw"
  })
  //计算msg高度
  // calScrollHeight(this, keyHeight);

 },

 //失去聚焦(软键盘消失)
 blur: function (e) {
  const { chatData } = this.data
  this.setData({
   scrollHeight: '100vh',
   inputBottom: 0
  })
  this.setData({
   toView: 'msg-' + (chatData.length - 1)
  })

 },

 /**
  * 发送点击监听
  */
 sendClick: function (e) {
  const { chatData, scrollHeight}=this.data;
  wx.createSelectorQuery().select('.content').boundingClientRect(function (rect) {
   // 使页面滚动到底部
   wx.pageScrollTo({
    scrollTop: rect.bottom + 5000
   })
  }).exec()
 
  chatData.push({
   type: 1,
   contentType: 'text',
   content: e.detail.value,
   headImg: '../../assets/common/images/headHortrait.jpeg',
  })
  this.setData({
   chatData,
   inputVal:''
  });


 },

 /**
  * 退回上一页
  */
 toBackClick: function () {
  wx.navigateBack({})
 }

})

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
jQuery select操作控制方法小结
May 26 Javascript
JS实现控制表格行文本对齐的方法
Mar 30 Javascript
使用jQuery判断浏览器滚动条位置的方法
May 30 Javascript
webpack vue 项目打包生成的文件,资源文件报404问题的修复方法(总结篇)
Jan 09 Javascript
VUE 全局变量的几种实现方式
Aug 22 Javascript
node错误处理与日志记录的实现
Dec 24 Javascript
JQuery样式操作、click事件以及索引值-选项卡应用示例
May 14 jQuery
jQuery Datatables 动态列+跨列合并实现代码
Jan 30 jQuery
ES2020系列之空值合并运算符 '??'
Jul 22 Javascript
React Ant Design树形表格的复杂增删改操作
Nov 02 Javascript
在Vue中使用mockjs代码实例
Nov 25 Vue.js
TS 类型收窄教程示例详解
Sep 23 Javascript
js实现适配移动端的拖动效果
Jan 13 #Javascript
Vue 嵌套路由使用总结(推荐)
Jan 13 #Javascript
优化Vue中date format的性能详解
Jan 13 #Javascript
JS document文档的简单操作完整示例
Jan 13 #Javascript
JavaScript数组排序小程序实现解析
Jan 13 #Javascript
JS document form表单元素操作完整示例
Jan 13 #Javascript
JS校验与最终登陆界面功能完整示例
Jan 13 #Javascript
You might like
Windows IIS PHP 5.2 安装与配置方法
2009/06/08 PHP
理解PHP中的stdClass类
2014/04/18 PHP
php删除指定目录的方法
2015/04/03 PHP
JavaScript语法着色引擎(demo及打包文件下载)
2007/06/13 Javascript
juqery 学习之五 文档处理 插入
2011/02/11 Javascript
JS图片根据鼠标滚动延时加载的实例代码
2013/07/13 Javascript
nodejs中转换URL字符串与查询字符串详解
2014/11/26 NodeJs
JavaScript动态创建link标签到head里的方法
2014/12/22 Javascript
整理Javascript事件响应学习笔记
2015/12/02 Javascript
探究Javascript模板引擎mustache.js使用方法
2016/01/26 Javascript
HTML中使背景图片自适应浏览器大小实例详解
2017/04/06 Javascript
Vue中如何实现轮播图的示例代码
2017/07/27 Javascript
Angular中的$watch方法详解
2017/09/18 Javascript
用POSTMAN发送JSON格式的POST请求示例
2018/09/04 Javascript
详解react阻止无效重渲染的多种方式
2018/12/11 Javascript
vue 中 elment-ui table合并上下两行相同数据单元格
2019/12/26 Javascript
javascript 使用sleep函数的常见方法详解
2020/04/26 Javascript
el-form 多层级表单的实现示例
2020/09/10 Javascript
javascript实现随机抽奖功能
2020/12/30 Javascript
[03:52]DOTA2英雄基础教程 酒仙
2013/12/23 DOTA
Python切片操作深入详解
2018/07/27 Python
opencv python 图像去噪的实现方法
2018/08/31 Python
Python批量生成幻影坦克图片实例代码
2019/06/04 Python
草莓网化妆品日本站:Strawberrynet日本
2017/10/20 全球购物
娱乐地球:Entertainment Earth
2020/01/08 全球购物
小学教师自我鉴定范文
2014/03/20 职场文书
商场开业庆典策划方案
2014/06/02 职场文书
党员干部批评与自我批评反四风思想汇报
2014/09/21 职场文书
领导班子在批评与自我批评座谈会上的发言
2014/09/28 职场文书
党支部组织生活会整改方案
2014/09/30 职场文书
群众路线教育实践活动整改方案(个人版)
2014/10/25 职场文书
党风廉正建设个人工作总结
2015/03/06 职场文书
实习介绍信范文
2015/05/05 职场文书
2015年中学团委工作总结
2015/07/22 职场文书
如何在centos上使用yum安装rabbitmq-server
2021/03/31 Servers
MySQL系列之七 MySQL存储引擎
2021/07/02 MySQL