Appearance
案例
瀑布流
父组件
vue
<template>
// 父向子传参 props
<Child :list="list"></Child>
</template>
<script setup lang='ts'>
import {ref, reactive} from 'vue'
import Child from "./components/child.vue";
const list = [
{
height: 300,
background: 'red'
},
{
height: 400,
background: 'pink'
},
{
height: 500,
background: 'blue'
},
{
height: 200,
background: 'green'
},
{
height: 300,
background: 'gray'
},
{
height: 400,
background: '#CC00FF'
},
{
height: 200,
background: 'black'
},
{
height: 100,
background: '#996666'
},
{
height: 500,
background: 'skyblue'
},
{
height: 300,
background: '#993366'
},
{
height: 100,
background: '#33FF33'
},
{
height: 400,
background: 'skyblue'
},
{
height: 200,
background: '#6633CC'
},
{
height: 300,
background: '#666699'
},
{
height: 300,
background: '#66CCFF'
},
{
height: 300,
background: 'skyblue'
},
{
height: 200,
background: '#CC3366'
},
{
height: 200,
background: '#CC9966'
},
{
height: 200,
background: '#FF00FF'
},
{
height: 500,
background: '#990000'
},
{
height: 400,
background: 'red'
},
{
height: 100,
background: '#999966'
},
{
height: 200,
background: '#CCCC66'
},
{
height: 300,
background: '#FF33FF'
},
{
height: 400,
background: '#FFFF66'
},
{
height: 200,
background: 'red'
},
{
height: 100,
background: 'skyblue'
},
{
height: 200,
background: '#33CC00'
},
{
height: 300,
background: '#330033'
},
{
height: 100,
background: '#0066CC'
},
{
height: 200,
background: 'skyblue'
},
{
height: 100,
background: '#006666'
},
{
height: 200,
background: 'yellow'
},
{
height: 300,
background: 'yellow'
},
{
height: 100,
background: '#33CCFF'
},
{
height: 400,
background: 'yellow'
},
{
height: 400,
background: 'yellow'
},
{
height: 200,
background: '#33FF00'
},
{
height: 300,
background: 'yellow'
},
{
height: 100,
background: 'green'
}
]
</script>
<style lang='scss'>
#app,
html,
body {
height: 100%;
}
* {
padding: 0;
margin: 0;
}
</style>子组件
vue
<template>
<div class="wraps">
<div :style="{height:item.height+'px',background:item.background,left:item.left+'px',top:item.top+'px'}"
v-for="(item,index) in waterList" :key="index" class="items"></div>
</div>
</template>
<script setup lang="ts">
import {onMounted, reactive} from "vue";
// 接收父组件的传参
const props = defineProps<{
list: Array<any>
}>()
//定义第一行的数组
const waterList = reactive<Array<any>>([])
//定义一个用来统计第一行高度的数组
const heightList = reactive<number[]>([])
const init = () => {
const width = 130
const x = document.body.clientWidth
console.log(x)
const column = Math.floor(x / width)
// console.log(column)
// console.log(props.list)
//遍历
for (let i = 0; i < props.list.length; i++) {
//第一行的div
if (i < column) {
props.list[i].left = i * width
props.list[i].top = 20
waterList.push(props.list[i])
heightList.push(props.list[i].height)
} else {
// 定义最小高度
let current = heightList[0]
// 最小项索引
let index = 0
heightList.forEach((height, ind) => {
if (current > height) {
current = height
index = ind
}
})
props.list[i].top = current + 40
props.list[i].left = index * width
heightList[index] = heightList[index] + 20 + props.list[i].height
waterList.push(props.list[i])
}
}
}
onMounted(() => {
init()
})
</script>
<style scoped lang="scss">
.wraps {
position: relative;
height: 100%;
.items {
position: absolute;
width: 120px;
}
}
</style>富文本编辑器
使用tinymce
shell
ni @tinymce/tinymce-vue tinymceApp.vue
init
vue
<script setup lang="ts">
import { onMounted } from 'vue'
import tinymce from 'tinymce'
onMounted(() => {
tinymce.init({
selector: '#mytiny',
})
})
</script>
<template>
<div id="mytiny" />
</template>
<style scoped>
</style>TIP
将 node_modules 中的 tinymce 文件夹中的 icons models plugins skins themes 五个文件夹复制到 public 文件夹中
修改样式
vue
<script setup lang="ts">
import { onMounted } from 'vue'
import tinymce from 'tinymce'
onMounted(() => {
tinymce.init({
selector: '#mytiny',
statusbar: false, // //底部状态栏
menubar: false, // //顶部菜单栏
toobar: false, // //工具栏
})
})
</script>使用 Editor 组件
vue
<script setup lang="ts">
import Editor from '@tinymce/tinymce-vue'
const initObj = {
statusbar: true,
menubar: true,
toolbar: true,
}
</script>
<template>
<Editor :init="initObj" />
</template>
<style scoped>
</style>中文化
将 langs 文件夹放在 public 下
vue
<script setup lang="ts">
import { onMounted } from 'vue'
import tinymce from 'tinymce'
const initObj = {
selector: '#mytiny',
statusbar: true,
menubar: true,
toolbar: true,
skin: 'oxide-dark', // //换肤
language: 'zh-Hans',// //语言
}
onMounted(() => {
tinymce.init(initObj)
})
</script>修改工具栏内容
Toolbar Buttons Available for TinyMCE
vue
<script setup lang="ts">
import { onMounted } from 'vue'
import tinymce from 'tinymce'
onMounted(() => {
tinymce.init({
selector: '#mytiny',
statusbar: true,
menubar: true,
skin: 'oxide-dark',
language: 'zh-Hans',
toolbar: 'undo redo | styles | bold italic | alignleft aligncenter',// //工具栏
width: 600,
})
})
</script>修改顶部菜单栏
vue
<script setup lang="ts">
import { onMounted } from 'vue'
import tinymce from 'tinymce'
onMounted(() => {
tinymce.init({
selector: '#mytiny',
statusbar: true,
menu: {
file: { title: 'File', items: 'newdocument restoredraft | preview | export print | deleteallconversations' },
edit: { title: 'Edit', items: 'undo redo | cut copy paste pastetext | selectall | searchreplace' },
},
menubar: 'file',
skin: 'oxide-dark',
language: 'zh-Hans',
width: 600,
})
})
</script>TIP
menu 需要搭配 menubar 一起使用,不然不能隐藏其中的某些不想要的项
获取文本内容
tinymce.activeEditor.getContent() 方法获得
不填写参数 或者使用 { format: 'html' } 作为参数得到的是html
使用 { format: 'text' } 得到文本
js
function send() {
console.log(tinymce.activeEditor.getContent())
console.log(tinymce.activeEditor.getContent({ format: 'text' }))
}设置文本内容
tinymce.activeEditor.setContent() 方法设置
参数里写要设置的文本,直接写文本就是使用p标签的文本,也可以使用html写法
js
function setInContent() {
// tinymce.activeEditor.setContent('123')
tinymce.activeEditor.setContent('<h1>hello world</h1>')
}获取选中的内容进行操作
tinymce.activeEditor.selection 方法进行获取
获取选中的文本 tinymce.activeEditor.selection.getContent()
修改选中的文本 tinymce.activeEditor.selection.setContent('hello')
使用插件
增加 plugins 属性,在 toolbar 中添加新增的插件名称
vue
<script>
onMounted(() => {
tinymce.init({
selector: '#mytiny',
statusbar: true,
menu: {
file: { title: 'File', items: 'newdocument restoredraft | preview | export print | deleteallconversations' },
edit: { title: 'Edit', items: 'undo redo | cut copy paste pastetext | selectall | searchreplace' },
},
menubar: 'file edit',
skin: 'oxide-dark',
plugins: 'image code table',
language: 'zh-Hans',
toolbar: 'undo redo | styles | bold italic | alignleft aligncenter | image code table',
width: 600,
})
})
</script>自定义按钮
使用 tinymce.editor.ui.Registry
vue
<script >
onMounted(() => {
tinymce.init({
selector: '#mytiny',
statusbar: true,
menubar: 'file edit',
skin: 'oxide-dark',
plugins: 'image code table',
setup(editor) {
console.log('editor', editor)
editor.ui.registry.addButton('red', {
icon: 'help',
tooltip: '变红',
onAction: () => {
console.log(1)
},
})
},
language: 'zh-Hans',
toolbar: 'undo redo | styles | bold italic | red | image code table',
width: 600,
})
})
</script>将选中内容改变样式
vue
<script>
onMounted(() => {
tinymce.init({
selector: '#mytiny',
statusbar: true,
menu: {
file: { title: 'File', items: 'newdocument restoredraft | preview | export print | deleteallconversations' },
edit: { title: 'Edit', items: 'undo redo | cut copy paste pastetext | selectall | searchreplace' },
},
menubar: 'file edit',
skin: 'oxide-dark',
plugins: 'image code table',
setup(editor) {
console.log('editor', editor)
editor.ui.registry.addButton('red', {
icon: 'help',
tooltip: '变红',
onAction: () => {
// 获取选中文字 //
const text = editor.selection.getContent({ format: 'text' })
editor.selection.setContent(`<span class="red-class">${text}</span>`)
},
})
},
language: 'zh-Hans',
toolbar: 'undo redo | styles | bold italic | red showVuePop | image code table',
width: 600,
content_css: '/mycontent.css',
})
})
</script>content_css: '/mycontent.css' 中的 mycontent.css 文件 放在 public 下面