-
VUE + Quill.js 에디터 #Editor #에디터 #vue프론트엔드/Nuxt 2023. 6. 14. 16:47반응형SMALL
1. cdn 연결하기
* nuxt ssr일 경우 nuxt.config.js가 아니라 default.vue 레이아웃에다 직접 링크 넣어야됨
(다른 레이아웃 파일 사용 시 그 파일에다 삽입)
@ default.vue
<template> <div id="app"> <header-vue /> <pop /> <section class="flex"> <aside class="left-side"></aside> <transition name="page" mode="out-in"> <Nuxt /> </transition> </section> <footer-vue /> </div> </template> <script> export default { head() { return { link: [ {rel: 'stylesheet', type: 'text/css', href: '//cdn.quilljs.com/1.3.4/quill.snow.css'}, ], script: [ { src: '//cdn.quilljs.com/1.3.6/quill.min.js', defer: true }, ], } }, } </script>
2. 프론트 세팅
@ InputEditor.js
<template> <div class="ql-editor"> <div id="editor" ref="editor" style="height:400px;"></div> <input type="file" id="getFile" accept="image/*" style="position: absolute; z-index:-1; opacity:0; left:-1000px; bottom:-1000px;" @change="changeImg"> </div> </template> <script> export default { components: {}, props: { default: "", required: { default: true }, }, data() { return { value: this.default, editor: "", } }, methods: { changeImg(event){ let formData = new FormData(); formData.append("file", event.target.files[0]); this.$axios.post("/api/images", formData) .then(response => { let url = response.data.data; const range = this.editor.getSelection(); this.editor.insertEmbed(range.index, 'image', url); /*this.editor.root.innerHTML += `<img src="${response.data.data}" alt=""/>` return response.data;*/ }); }, changeContents() { this.$emit("change", this.editor.root.innerHTML); }, imageHandler() { document.getElementById('getFile').click(); } }, mounted() { let self = this; const toolbarOptions = [ ['bold', 'italic', 'underline', 'strike'], ['blockquote', 'code-block'], [{'header': 1}, {'header': 2}], [{'list': 'ordered'}, {'list': 'bullet'}], [{'script': 'sub'}, {'script': 'super'}], [{'indent': '-1'}, {'indent': '+1'}], [{'direction': 'rtl'}], [{'size': ['small', false, 'large', 'huge']}], [{'header': [1, 2, 3, 4, 5, 6, false]}], [{'color': []}, {'background': []}], [{'font': []}], [{'align': []}], ['clean', 'image'] ] this.editor = new Quill(this.$refs.editor, { modules: { toolbar: { container: toolbarOptions, handlers: { 'image' : self.imageHandler } } }, theme: 'snow', }) this.editor.on("text-change", () => { this.changeContents(); }) this.editor.pasteHTML(this.default); // this.$refs.editor.quill.setContents(this.default); // this.$store.commit('setQuillInstance', quill) }, watch: { value: function (value, oldValue) { this.$emit("change", value); } } } </script>
@ example.vue
<template> <input-editor :default="form.description" @change="(data) => {form.description = data}"/> </template> <script> import Form from "@/utils/Form"; export default { data(){ return { form: new Form(this.$axios, { description: "", }) } }, } </script>
3. 백엔드 세팅
@ Image.php (migration도 만들되, 컬럼은 id만 있으면 됨)
<?php namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Spatie\MediaLibrary\HasMedia; use Spatie\MediaLibrary\InteractsWithMedia; class Image extends Model implements HasMedia { use HasFactory, InteractsWithMedia; protected $appends = [ "file", ]; public function registerMediaCollections():void { $this->addMediaCollection('file')->singleFile(); } public function getFileAttribute() { if($this->hasMedia('file')) { $media = $this->getMedia('file')[0]; return [ "name" => $media->file_name, "url" => $media->getFullUrl() ]; } return null; } }
@ api.php
Route::post("/images", [\App\Http\Controllers\Api\ImageController::class, "store"]);
@ Api/ImageController.php
<?php namespace App\Http\Controllers\Api; use App\Http\Controllers\Controller; use App\Models\Image; use Illuminate\Http\Request; class ImageController extends ApiController { public function store(Request $request) { $request->validate([ "file" => "required" ]); $image = Image::create(); $image->addMedia($request->file)->toMediaCollection("file", "s3"); $media = $image->getMedia('file')[0]; return $this->respondSuccessfully($media->getFullUrl()); } }
LIST'프론트엔드 > Nuxt' 카테고리의 다른 글
vue 422, 401 등 에러 발생 시 페이지가 이동해버리는 이슈 #vue #nuxt #laravel #error #에러 (0) 2023.08.03 VUE + Quill.js 에디터 #Editor #에디터 #vue (0) 2023.06.14 Vue nuxt 배포 시 첫화면 에러뜰 때 (0) 2023.06.06 nuxt에 구글애널리틱스, 메타픽셀 삽입하는법 #facebook #google (0) 2023.05.30 ssr 모드에서 client일 때만 처리하게 하는법 (ex. window is not defined, document is not defined) (0) 2023.05.30