卡片
效果
流程
安装插件 yarn add @wangeditor/plugin-link-card
注册
js
import { Boot } from "@wangeditor/editor";
import linkCardModule from "@wangeditor/plugin-link-card";
// 注册。要在创建编辑器之前注册,且只能注册一次,不可重复注册。
Boot.registerModule(linkCardModule);
- 配置
js
import { IEditorConfig } from "@wangeditor/editor";
const editorConfig: Partial<IEditorConfig> = {
hoverbarKeys: {
// 在编辑器中,选中链接文本时,要弹出的菜单
link: {
menuKeys: [
"editLink",
"unLink",
"viewLink", // 默认的配置可以通过 `editor.getConfig().hoverbarKeys.link` 获取
"convertToLinkCard", // 增加 '转为链接卡片'菜单
],
},
},
MENU_CONF: {
// '转为链接卡片'菜单的配置
convertToLinkCard: {
// 自定义获取 link-card 信息,可选
// 返回 { title, iconImgSrc }
async getLinkCardInfo(linkText: string, linkUrl: string) {
// 1. 可通过 iframe 加载网页,然后获取网页 title 和其中的图片
// 2. 服务端获取(有些网页会设置 `X-Frame-Options` ,无法通过 iframe 加载)
// // 模拟异步返回
// return new Promise(resolve => {
// setTimeout(() => {
// const info = { title: linkText, iconImgSrc: '' }
// resolve(info)
// }, 100)
// })
},
},
// 其他...
},
// 其他...
};
显示 HTML
html
<div
data-w-e-type="link-card"
data-w-e-is-void
data-title="百度新闻"
data-link="http://news.baidu.com/"
data-iconImgSrc="https://news-bos.cdn.bcebos.com/mvideo/log-news.png"
>
<div class="info-container">
<div class="title-container">
<p>百度新闻</p>
</div>
<div class="link-container"><span>http://news.baidu.com/</span></div>
</div>
<div class="icon-container">
<img src="https://news-bos.cdn.bcebos.com/mvideo/log-news.png" />
</div>
</div>
渲染样式
css
div[data-w-e-type="link-card"] {
width: 450px;
margin: 0 auto;
background-color: #f1f1f1;
border-radius: 10px;
display: flex;
padding: 10px 20px;
cursor: pointer;
}
div[data-w-e-type="link-card"] .info-container {
flex: 1;
padding-right: 20px;
}
div[data-w-e-type="link-card"] .info-container p {
margin-top: 5px;
font-weight: bold;
}
div[data-w-e-type="link-card"] .info-container span {
opacity: 0.5;
}
div[data-w-e-type="link-card"] .icon-container {
width: 64px;
overflow: hidden;
}
div[data-w-e-type="link-card"] .icon-container img {
width: 100%;
height: 100%;
object-fit: contain;
}
代码
vue
<template>
<div style="border: 1px solid #ccc">
<Toolbar
style="border-bottom: 1px solid #ccc"
:editor="editorRef"
:defaultConfig="toolbarConfig"
:mode="mode"
/>
<Editor
style="height: 500px; overflow-y: hidden"
v-model="valueHtml"
:defaultConfig="editorConfig"
:mode="mode"
@onCreated="handleCreated"
/>
</div>
<button @click="getcontent">提交</button>
</template>
<script setup lang="ts">
import "@wangeditor/editor/dist/css/style.css"; // 引入 css
import { onBeforeUnmount, ref, shallowRef, onMounted } from "vue";
import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
import { Boot, IEditorConfig } from "@wangeditor/editor";
import linkCardModule from "@wangeditor/plugin-link-card";
// 编辑器实例,必须用shallowRef包裹
const editorRef = shallowRef();
// 内容HTML
const valueHtml = ref("<p>hello</p>");
// 编辑器模式
const mode = ref("default"); // simple或者default;
// 模拟ajax异步获取数据内容
onMounted(() => {
setTimeout(() => {
valueHtml.value = "<p>模拟 Ajax 异步设置内容</p>";
}, 1500);
});
// 工具栏配置
const toolbarConfig = {};
// 编辑器配置
const editorConfig = {
placeholder: "请输入内容...",
hoverbarKeys: {
// 在编辑器中,选中链接文本时,要弹出的菜单
link: {
menuKeys: [
"editLink",
"unLink",
"viewLink", // 默认的配置可以通过 `editor.getConfig().hoverbarKeys.link` 获取
"convertToLinkCard", // 增加 '转为链接卡片'菜单
],
},
},
MENU_CONF: {
convertToLinkCard: {},
},
};
editorConfig.MENU_CONF["convertToLinkCard"] = {
// 自定义获取 link-card 信息,可选
// 返回 { title, iconImgSrc }
async getLinkCardInfo(linkText: string, linkUrl: string) {
// 1. 可通过 iframe 加载网页,然后获取网页 title 和其中的图片
// 2. 服务端获取(有些网页会设置 `X-Frame-Options` ,无法通过 iframe 加载)
// // 模拟异步返回
return new Promise((resolve) => {
setTimeout(() => {
const info = { title: linkText, iconImgSrc: "" };
resolve(info);
}, 100);
});
},
};
// 组件销毁的时候,也即时 销毁编辑器
onBeforeUnmount(() => {
const editor = editorRef.value;
if (editor == null) return;
editor.destroy();
});
// 编辑器示例
const handleCreated = (editor: any) => {
editorRef.value = editor; // 记录editor实例
};
// 获取到编辑器内容
const getcontent = () => {
console.log(valueHtml.value);
window.alert(valueHtml.value);
};
// 仅仅注册一次
Boot.registerModule(linkCardModule);
</script>
<style lang="scss" scoped></style>