返回 slidev
TheTweet.vue
根目录 / docs / .vitepress / theme / components / TheTweet.vue
1 <!--
2 A simple wrapper for embedded Tweet
3
4 Usage:
5
6 <TheTweet id="20" />
7 -->
8
9 <script setup lang="ts">
10 import { isClient, useScriptTag } from '@vueuse/core'
11 import { getCurrentInstance, onMounted, ref } from 'vue'
12 import { isDark } from '../composables/dark'
13
14 const props = defineProps<{
15 id: string | number
16 scale?: string | number
17 conversation?: string
18 }>()
19
20 const tweet = ref<HTMLElement | null>()
21
22 const vm = getCurrentInstance()!
23 const loaded = ref(false)
24
25 async function create() {
26 // @ts-expect-error Global variable
27 if (!window.twttr?.widgets?.createTweet)
28 return
29 // @ts-expect-error Global variable
30 await window.twttr.widgets.createTweet(
31 props.id.toString(),
32 tweet.value,
33 {
34 theme: isDark.value ? 'dark' : 'light',
35 conversation: props.conversation || 'none',
36 },
37 )
38 loaded.value = true
39 }
40
41 if (isClient) {
42 // @ts-expect-error Global variable
43 if (window?.twttr?.widgets?.createTweet) {
44 onMounted(create)
45 }
46 else {
47 useScriptTag(
48 'https://platform.twitter.com/widgets.js',
49 () => {
50 if (vm.isMounted)
51 create()
52 else
53 onMounted(create, vm)
54 },
55 { async: true },
56 )
57 }
58 }
59 </script>
60
61 <template>
62 <div class="w-full flex">
63 <div ref="tweet" class="mx-auto w-140">
64 <div v-if="!loaded" class="w-30 h-30 my-10px bg-gray-400 bg-opacity-10 rounded-lg flex opacity-50">
65 <div class="m-auto animate-pulse text-4xl">
66 <div class="i-carbon:logo-twitter" />
67 </div>
68 </div>
69 </div>
70 </div>
71 </template>
72
72 lines Plain Text