vue-bilibili-embed-renderer
Version:
It is better to use Bilibili's embed renderer component for Vue applications
96 lines (95 loc) • 3.33 kB
JavaScript
import { defineComponent, computed, useAttrs, openBlock, createElementBlock, mergeProps, unref } from "vue";
const calcHeight = (width, height, aspectWidth, aspectHeight) => {
if (height) {
return height;
}
if (typeof width === "number") {
return width * aspectHeight / aspectWidth;
} else if (typeof width === "string" && width.search("px") !== -1) {
const widthNum = Number(width.replace("px", ""));
return widthNum * aspectHeight / aspectWidth;
} else if (typeof width === "string" && width === "100%") {
return "100%";
}
return 360;
};
const isBrowser = !!(typeof window !== "undefined" && window.document && window.document.createElement);
const _hoisted_1 = ["width", "height", "src"];
const bilibiliUrl = "//player.bilibili.com/player.html";
const _sfc_main = defineComponent({
...{
inheritAttrs: false
},
__name: "core",
props: {
aid: {},
bvid: {},
page: { default: 1 },
isWide: { type: Boolean, default: true },
highQuality: { type: Boolean, default: true },
hasDanmaku: { type: Boolean, default: false },
aspectWidth: {},
aspectHeight: {},
width: { default: 480 },
height: {},
iframeClass: { default: "" }
},
setup(__props) {
const props = __props;
if (!props.aid && !props.bvid) {
throw new Error("Either aid or bvid must be provided");
}
const defaultAspectWidth = isBrowser ? 4 : 16;
const defaultAspectHeight = isBrowser ? 3 : 9;
const finalAspectWidth = props.aspectWidth || defaultAspectWidth;
const finalAspectHeight = props.aspectHeight || defaultAspectHeight;
const height = calcHeight(props.width, props.height, finalAspectWidth, finalAspectHeight);
const highQualityValue = props.highQuality ? 1 : 0;
const wideValue = props.isWide ? 1 : 0;
const danmakuValue = props.hasDanmaku ? 1 : 0;
const iframeSrc = computed(() => {
let src = `${bilibiliUrl}?`;
if (props.bvid) {
src += `bvid=${props.bvid}`;
} else {
src += `aid=${props.aid}`;
}
src += `&page=${props.page}&high_quality=${highQualityValue}&as_wide=${wideValue}&danmaku=${danmakuValue}`;
return src;
});
const attrs = useAttrs();
const finalClassName = computed(() => {
const classes = [props.iframeClass];
if (typeof attrs.class === "string") {
classes.push(attrs.class);
} else if (Array.isArray(attrs.class)) {
classes.push(...attrs.class);
} else if (attrs.class && typeof attrs.class === "object") {
const classObj = attrs.class;
Object.keys(classObj).forEach((key) => {
if (classObj[key])
classes.push(key);
});
}
return classes.filter(Boolean).join(" ") || void 0;
});
const { width } = props;
return (_ctx, _cache) => {
return openBlock(), createElementBlock("iframe", mergeProps({
width: unref(width),
height: unref(height),
src: iframeSrc.value,
allowFullScreen: true,
class: finalClassName.value
}, _ctx.$attrs), null, 16, _hoisted_1);
};
}
});
const install = (app) => {
app.component("BilibiliEmbedRenderer", _sfc_main);
};
var index = {
install,
BilibiliEmbedRenderer: _sfc_main
};
export { _sfc_main as BilibiliEmbedRenderer, index as default };