a layout based WYSIWYG html editor.
$ npm install
$ npm run bundle
$ npm run serve
$ npm run build
$ npm run test
$ npm run lint
$ npm run build-layouts
- Layer Preview
- desktop(960 ~ (100%))
- tablet(959px ~ 600px)
- mobile(599px ~)
- Layer Manager
- Simple HTML Validator
$ npm install --save @fastcampus/fastcomposer
<template>
<composer @save="onSave"/>
</template>
<script>
import Composer from 'your-path/fastcomposer/src/views/composer';
import 'your-path-to-layouts-style.css';
export default {
name: 'yourApp',
methods: {
onSave(html, json) {
// ...
}
}
}
</script>
see also: src/main.js
import Vue from 'vue'; // vue@2
import Composer from '@day1co/composer';
import layouts from '../layouts-somewhere';
import sample from '../layouts-somewhere/sample.json';
import 'layouts-somewhere/styles';
const vm = new Vue({
data: () => ({
render(h) {
return h(Composer, {
props: {
layerModals: sample,
layoutModels: layouts,
},
on: {
save(html, json) {
// ...
},
uploadFile(file, callback) {
// handle file upload here
// file: { id, type: enum, files: File[0-1] }
// callback: (res: { url: string }) => void
}
}
})
}
}).$mount('#app');
// call vm.$destroy or handle onDestroy as required
Name | Type | Default | Optional | Description |
---|---|---|---|---|
layoutModels | Array | [] | No | @fastcampus/layouts list를 넣어준다 |
layerModals | Array | [] | Yes | 서버로부터 저장된 layer data 가 존재한다면 이곳에 넣어준다. |
컴포저 저장시 동작한다.
- html:
string
composer로 제작된 html - json:
object
layer 설정 값
템플릿에서 파일 업로드 속성이 존재하는 경우 동작한다.
<composer @uploadFile="onUpload"></composer>
methods: {
async onUpload(fileInfo, callback) {
const res = await uploadToYourServer(fileInfo);
// callback으로 결과를 넘겨준다 (res.url)
callback(res);
}
}
- fileInfo:
File
- callback:
function
업로드된 이미지를 컴포저에 반영을 위해 실행
// 서버에 저장된 mainJson을 object형태로 넣어준다.(layouts.json포맷과 일치해야함)
this.$refs.setLayerBlockData({...})
this.$refs.fastComposer.notification.success('success message');
this.$refs.fastComposer.notification.error('error message');
{
"params": [
{
"name": "...",
"type": "list",
"maxLength": 3,
"params": [
{
"name": "...",
"type": "...",
"description": "...",
"isRequired": true
}
]
}
]
}
{
"params": [
{
"name": "cards",
"type": "list",
"description": "추가/삭제를 이용하여 원하는 만큼 카드 리스트를 구현 할 수 있습니다.",
"maxLength": 3,
"params": [
{
"name": "src",
"type": "image",
"description": "image url",
"isRequired": true
},
{
"name": "width",
"type": "number",
"description": "image width(pixel)"
},
{
"name": "height",
"type": "number",
"description": "image height(pixel)"
},
{
"name": "alt",
"type": "text",
"description": "alternative text"
}
]
},
{
"name": "tabs",
"type": "list",
"description": "추가/삭제를 이용하여 원하는 만큼 탭 리스트를 구현 할 수 있습니다.",
"maxLength": 5,
"params": [
{
"name": "content",
"type": "textarea",
"description": "text area"
},
{
"name": "width",
"type": "number",
"description": "image width(pixel)"
},
{
"name": "height",
"type": "number",
"description": "image height(pixel)"
},
{
"name": "alt",
"type": "text",
"description": "alternative text"
}
]
}
],
"values": {
"title": "제목",
"cards": [
{
"src": "https://via.placeholder.com/320x320.png/00c",
"width": "320",
"height": "320",
"alt": "simple image"
}
],
"tabs": []
}
}
<% cards.forEach((item) => { %>
<div><img src="<%= item.src %>"/></div>
<div><%= item.width%></div>
<div><%= item.height %></div>
<div><%= item.alt %></div>
<% }); %>
may the SOURCE be with you...