VUE 自定义控件的事件

2024-09-20  本文已影响0人  大成小栈
1. 自定一个组件 TopBar
<template>
  <!-- 顶部工具栏组件 -->
  <div v-if="showNav" class="top-bar" :style="{ height: `${height}`, backgroundColor: `${backgroundColor}` }">
    <!-- 顶部返回图标 默认显示 -->
    <div v-if="showBack" class="icon icon-back" @click="handleBack"/>
    <!-- 顶部标题 -->
    <span class="title">{{ title }}</span>
    <!-- 顶部更多图标 默认不显示 -->
    <div v-if="showMore" class="icon icon-more" @click="handleMore"/>
    <!-- 顶部分享图标 默认不显示 -->
    <div v-if="showShare" class="icon icon-share" :class="[{ 'icon-share-adjusted': !showMore }]" @click="handleShare"/>
  </div>
</template>

<script setup lang="ts">

import { callNativeFunction, closeWebView } from '@/utils/clientBridge';
import { computed, defineProps, onMounted, ref, withDefaults } from 'vue';

interface Props {
  showNav?: boolean;
  title?: string;
  backgroundColor?: string;
  height?: string;
  showBack?: boolean;
  showShare?: boolean;
  showMore?: boolean;
}
// 使用 withDefaults 为 props 设置默认值
const props = withDefaults(defineProps<Props>(), {
  showNav: true,
  title: '',
  backgroundColor: '#000',
  height: '44px',
  showBack: true,
  showShare: false,
  showMore: false,
});

const emit = defineEmits<{
  (event: 'bar-icon-click',type:string): void;
}>();



function handleBack() {
  // 调用客户端返回协议
  closeWebView();
}

// TODO: 调用客户端更多协议
function handleMore() {
  window.console.log('调用客户端更多协议');
  emit("bar-icon-click","more")
}

// TODO: 调用客户端分享协议
function handleShare() {
  window.console.log('调用客户端分享协议');
  emit("bar-icon-click","share")
}

</script>

<style lang="less" scoped>
@import '~@/assets/styles/common.less';

.top-bar {
  width: 100vw;
  position: relative;
  display: flex;
  justify-content: center;
  align-items: center;
  position: relative;

  .icon {
    width: 24px;
    height: 24px;
    background-repeat: no-repeat;
    background-size: cover;
    background-position: center;
  }

  .icon-back {
    background-image: url('../../assets/images/df_icon_back.png');
    position: absolute;
    left: 16px;
  }

  .icon-more {
    background-image: url('../../assets/images/df_icon_more.png');
    position: absolute;
    right: 16px;
  }

  .icon-more-adjusted {
    right: 56px;
  }

  .icon-share {
    background-image: url('../../assets/images/df_icon_share.png');
    position: absolute;
    right: 56px;
  }

  .icon-share-adjusted {
    right: 16px;
  }

  .title {
    font-family: Poppins;
    text-align: center;
    color: #fff;
    font-size: 18px;
    font-weight: 500;
    line-height: normal;
    text-transform: capitalize;
    letter-spacing: 0px;
  }
}
</style>

其中,定义了一个事件回调

const emit = defineEmits<{
  (event: 'bar-icon-click',type:string): void;
}>();

触发回调的逻辑:

// TODO: 调用客户端更多协议
function handleMore() {
  window.console.log('调用客户端更多协议');
  emit("bar-icon-click","more")
}

// TODO: 调用客户端分享协议
function handleShare() {
  window.console.log('调用客户端分享协议');
  emit("bar-icon-click","share")
}
2. 父视图中调用子组件,对事件的实现
<template>
  <div class="video-preview no-select" @click.capture="handleCaptureClick">
    <TopBar title="" :showShare="true" :showNav="true" :show-more="true" backgroundColor="#03141A"
            @bar-icon-click="barClickHandle" id="top-bar-id"/>

  </div>
</template>

<script lang="ts" setup>

import TopBar from '@/components/TopBar/index.vue';

const {proxy} = getCurrentInstance()!;


const barClickHandle = (type) => {
  console.log("barClickHandle", type)
  if ("more" === type) {
    showMenuPop.value = true
  }
  if ("share" === type && selectedTemplate.value) {
    if (selectedTemplate.value.id) {
      let title = "Try the great template!"
      let templateId = selectedTemplate.value.id

      openLoadingIcon()
      getClientUserInfo().then(res => {
        closeLoadingIcon()
        if (res && res.userId) {
          let shareUrl = "https://dreamfaceapp.com/share/template?userId=" + res.userId + "&channel=system&tempId=" + templateId
            + "&apn=com.dreamapp.dubhe"
          if (getEnvStatus().isRelease) {
            apiPostRequest(config.api.shortUrlGet, {url: shareUrl}).then(res => {
              callShare(res.url || shareUrl, title)
            }).catch(e => {
              callShare(res.url || shareUrl, title)
            })
          } else {
            callShare(shareUrl, title)
          }
        }
      }).catch(e => {
        closeLoadingIcon()
      })
    }
  }
}

function callShare(url: string, title: string) {
  let shareParams = {
    title: title,
    description: url,
    remoteUrl: "",
    localPath: "",
    mimeType: "TEXT",
    channel: "system"
  }
  callNativeShare(shareParams)
}

</script>

类似于 iOS 中 Delegate / Block 。

上一篇下一篇

猜你喜欢

热点阅读