Web

非 React 框架自定义渲染

更新时间: 2024/03/14 19:21:15

本文介绍非 React框架如何对 IM UIKit 进行自定义渲染。

背景信息

  • 非 React 框架下进行自定义渲染时,IM UIKit 内部实际使用 React 进行渲染,因此 React 和 React-Dom 会作为依赖项集成到您的项目中。

  • 每个组件的 props 参数定义与 React 版本一致。但您需要额外编写 JSX 版本的 props,因为在 Vue 或其他框架中无法直接编写和编译 JSX 代码。我们提供了 compile 函数,在运行时动态编译 JSX,支持以字符串形式写 JSX。

    具体的props 参数,请参见如下文档中的参数说明:

前提条件

实现方法

本节将通过典型的业务场景介绍如何实现自定义渲染。

自定义渲染会话组件

假设您希望会话(聊天)组件ChatContainer 实现自定义每条消息的样式,但保留该组件默认的头像和称谓,那么示例代码如下:

js<template>
  <div ref="conversation" class="conversation"></div>
  <div ref="chat" class="chat"></div>
</template>

<script lang="ts">
import {
  ConversationContainer,
  ChatContainer,
  // 引入组件提供的头像组件
  ComplexAvatarContainer,
} from "@xkit-yx/im-kit-ui";
import { compile } from "jsx-web-compiler";

export default {
  name: "Conversation",
  mounted() {
    window.uikit.render(
      ConversationContainer,
      null,
      this.$refs.conversation as HTMLElement
    );
    window.uikit.render(
      ChatContainer,
      {
        // 这里以群聊消息为例,单聊使用 renderP2pCustomMessage
        renderTeamCustomMessage: (data) => {
          // 这里通过 uikit 实例获取 store,store 文档参考 https://doc.yunxin.163.com/docs/interface/messaging/web/typedoc/UIKit/Latest/zh/modules.html
          const store = window.uikit.getStateContext()?.store!
          return compile(
            `<div>
              <context.ComplexAvatarContainer account='${data.msg.from}' />
              // 通过该方法获取称谓
              <span>${store.uiStore.getAppellation({account: data.msg.from })}</span>
            </div>`,
            // 将头像组件传入 compile 函数的第二个参数 context 中,compile 函数中通过 context.ComplexAvatarContainer 访问
            { ComplexAvatarContainer }
          )
        }
      },
      this.$refs.chat as HTMLElement
    );
  },

  beforeUnmount() {
    window.uikit.unmount(this.$refs.conversation as HTMLElement);
    window.uikit.unmount(this.$refs.chat as HTMLElement);
  },
};
</script>

<style scoped>
.conversation {
  width: 20%;
}
.chat {
  width: 80%;
}
</style>

发送自定义消息

发送方可以在会话界面的消息发送按钮上绑定发送消息的函数,您可以根据业务需要,决定调用 sendCustomMsgActivesendCustomMsgBySDK 函数发送自定义消息。

以“发送一条评价消息”为例,发送时,可将“是否为评价消息”标记在附件信息attach字段中,然后在消息接收时进行判断:

  • 如果是评价消息,则使用自定义渲染。
  • 如果不是,则返回 null,使用默认的消息渲染逻辑。

评价消息.png

// 发送评价消息
const sendEvaluationMessage = () => {
  // 这里通过 uikit 实例获取 store,store 文档参考 https://doc.yunxin.163.com/docs/interface/messaging/web/typedoc/UIKit/Latest/zh/modules.html
  const store = this.$uikit.getStateContext()?.store
  const [scene, to] = store.uiStore.selectedSession.split('-')
  const from = store.userStore.myUserInfo.account
  //用户自定义参数
  const attach = {
    isEvaluation: true
  }
  // sence代表发送场景 form 发送方 to接收方
  store.msgStore.sendCustomMsgActive({
    scene,
    from,
    to,
    attach: JSON.stringify(attach)
  })
}

this.$uikit.render(
      ChatContainer,
      {
        actions: [
            {
              action: 'emoji',
              visible: true,
            },
            {
              action: 'sendImg',
              visible: true,
            },
            {
              action: 'sendFile',
              visible: true,
            },
            {
              action: 'evaluation',
              visible: true,
              render: (props) => {
               return compile(`
                <context.Button onClick={context.sendEvaluationMessage} size="small" disabled={context.props.mute}>
                  <i className="iconfont icon-message_fill_light" />
                </context.Button>
              `, {
                props,
                CommonIcon,
                Button,
                sendEvaluationMessage
              });
            },
            },
        ]
      },
      this.$refs.chat
    );

接收自定义消息

同样以“接收评价消息”为例,接收方可从如下回调函数中获取 IM UIKit 渲染一条消息的所有参数,从而自行实现任意的 UI 展示。

如果需要针对特定类型(type)的消息进行单独的渲染处理,可以根据 type 判断并返回自定义的内容,如果返回 undefined 或 false 则使用默认渲染方式。

回调 类型 说明
renderP2pCustomMessage ((options: RenderP2pCustomMessageOptions) => Element | null) 渲染单聊中的自定义消息
renderTeamCustomMessage ((options: RenderTeamCustomMessageOptions) => Element | null) 渲染群聊中的自定义消息
this.$uikit.render(
      ChatContainer,
      {
        renderMessageInnerContent: (options) => {
          let isEvaluation
          if(options.attach){
            isEvaluation = options.attach.isEvaluation
          }
          return isEvaluation ?
            compile(`<div className='wrapper'>
         <div className='msg-wrapper'>
          <div className='text'>欢迎您进行评价</div>
          <img className='star' src="https://yx-web-nosdn.netease.im/common/57dea86c692f76efdfecff37ee7e1059/星星.png"/>
          <img className='star' src="https://yx-web-nosdn.netease.im/common/57dea86c692f76efdfecff37ee7e1059/星星.png"/>
          <img className='star' src="https://yx-web-nosdn.netease.im/common/57dea86c692f76efdfecff37ee7e1059/星星.png"/>
          <img className='star' src="https://yx-web-nosdn.netease.im/common/57dea86c692f76efdfecff37ee7e1059/星星.png"/>
          <img className='star' src="https://yx-web-nosdn.netease.im/common/57dea86c692f76efdfecff37ee7e1059/星星.png"/>
          </div>
        </div> `, {
              options,
            }) : false
        },
        actions: [
            {
              action: 'emoji',
              visible: true,
            },
            {
              action: 'sendImg',
              visible: true,
            },
            {
              action: 'sendFile',
              visible: true,
            },
            {
              action: 'evaluation',
              visible: true,
              render: (props) => {
               return compile(`
                <context.Button onClick={context.sendEvaluationMessage} size="small" disabled={context.props.mute}>
                  <i className="iconfont icon-message_fill_light" />
                </context.Button>
              `, {
                props,
                CommonIcon,
                Button,
                sendEvaluationMessage
              });
            },
            },
        ]
      },
      this.$refs.chat
    );

更多自定义消息相关请参考实现自定义消息收发

此文档是否对你有帮助?
有帮助
去反馈
  • 背景信息
  • 前提条件
  • 实现方法
  • 自定义渲染会话组件
  • 发送自定义消息
  • 接收自定义消息