我正在向我的Laravel 5.4项目添加tinymce。我已经把它变成了一个全局组件。这可以很好地工作。做了它应该做的事情,一切都很好。现在,在跟随Laracast最新的“使用TDD构建论坛”系列文章时..我开始想,我可以将该组件添加到reply组件中,并在那里使用它!是啊..不是的。我是个笨蛋,所以我肯定漏掉了一些明显的东西。有人能帮上忙吗?我甚至决定调用全局组件作为子组件..这也不是什么乐趣。
chrome上的Vue调试工具说它就在那里...但是编辑器不会渲染。所以我有点困惑。我也尝试过将<slot>添加到不同的地方,但没有任何改变。任何帮助都将不胜感激!
谢谢大家!
下面的代码-
app.js:
Vue.component('flash', require('./components/Flash.vue'));
Vue.component('reply', require('./components/Reply.vue'));
Vue.component('tinymce-editor',require('./components/Tinymce.vue'));
const app = new Vue({
el: '#app',
});Tinymce.vue:
<template>
<textarea name="body" class="form-control" id="tinymce" v-text="body" rows="5"></textarea>
</template>
<script>
export default {
name: 'tinymce-editor',
props: {
body: {
default: 'Something to say, have you?'
}
},
mounted: function() {
const self = this;
tinymce.init({
menubar: false,
path_absolute: "/",
selector: "#tinymce",
entity_encoding: "raw",
toolbar_items_size: "small",
style_formats: [
{"title": "Bold", "icon": "bold", "format": "bold"},
{"title": "Italic", "icon": "italic", "format": "italic"},
{"title": "Underline", "icon": "underline", "format": "underline"},
{"title": "Strikethrough", "icon": "strikethrough", "format": "strikethrough"},
{"title": "Superscript", "icon": "superscript", "format": "superscript"},
{"title": "Subscript", "icon": "subscript", "format": "subscript"},
{"title": "Code", "icon": "code", "format": "code"}
],
plugins: 'advlist anchor autolink autoresize code colorpicker hr image link lists preview searchreplace spellchecker textcolor wordcount',
block_formats: "Paragraph=p;Heading 1=h1;Heading 2=h2;Heading 3=h3;Heading 4=h4;Heading 5=h5;Heading 6=h6;",
toolbar1: "undo redo | formatselect | bullist numlist | link unlink | uploadimg image",
toolbar2: "styleselect fontsizeselect | forecolor | bold italic underline strikethrough | alignleft aligncenter alignright alignjustify | outdent indent | removeformat",
init_instance_callback: function(editor) {
// init tinymce
editor.on('init', function () {
tinymce.activeEditor.setContent(self.value);
});
}
});
},
update: function(newVal, oldVal) {
// set val and trigger event
$(this.el).val(newVal).trigger('keyup');
}
}
</script>Reply.vue:
<script>
import Favorite from './Favorite.vue';
import Tinymce from './Tinymce.vue';
export default {
name: 'Reply',
props: ['attributes'],
components: {
'favorite': Favorite,
'tinymce-editor': Tinymce
},
data() {
return {
editing: false,
body: this.attributes.body
};
},
methods: {
update() {
axios.patch('/replies/' + this.attributes.id, {
body: this.body
});
this.editing = false;
flash('Updated!');
},
destroy() {
axios.delete('/replies/' + this.attributes.id);
$(this.$el).fadeOut(300, () => {
flash('Your reply has been deleted.');
});
}
}
}
</script>reply.blade.php:
<reply :attributes="{{ $reply }}" inline-template v-cloak>
<div id="reply-{{$reply->id}}" class="panel panel-default">
<div class="panel-heading">
<div class="level">
<h5 class="flex">
<a href="{{ route('profile',$reply->owner->name) }}">
{{ $reply->owner->name }}
</a> said {{ $reply->created_at->diffForHumans() }}...
</h5>
<favorite :reply="{{$reply}}"></favorite>
</div>
</div>
<div class="panel-body">
<div v-if="editing">
<div class="form-group">
<tinymce-editor body="{{ $reply->body }}"></tinymce-editor>
</div>
<button class="btn btn-xs btn-primary" @click="update">Update</button>
<button class="btn btn-xs btn-link" @click="editing = false">Cancel</button>
</div>
<div v-else v-html="body"></div>
</div>
@can('update', $reply)
<div class="panel-footer level">
<button class="btn btn-xs btn-success mr-1" @click="editing = true">Edit</button>
<button class="btn btn-xs btn-danger mr-1" @click="destroy">Delete</button>
</div>
@endcan
</div>
</reply>发布于 2017-05-08 03:36:30
我终于想通了。实际上这里有两个问题。编辑器上的ID不是唯一的。这就是子编辑器没有渲染的原因。一旦我解决了这个问题,我就遇到了子进程不更新父进程的问题。所以我也必须解决这个问题。更新了下面的代码,以供其他可能需要它的人使用。这可能不是“最佳实践”代码,但它是有效的。我非常乐于改进!谢谢大家!
Reply.vue:
<script>
import Favorite from './Favorite.vue';
export default {
name: 'Reply',
props: ['attributes'],
components: {
'favorite': Favorite,
},
data() {
return {
editing: false,
body: this.attributes.body
};
},
methods: {
updateBody(newContent) {
this.body = newContent;
},
update() {
axios.patch('/replies/' + this.attributes.id, {
body: this.body
});
this.editing = false;
flash('Updated!');
},
destroy() {
axios.delete('/replies/' + this.attributes.id);
$(this.$el).fadeOut(300, () => {
flash('Your reply has been deleted.');
});
}
}
}
</script>Tinymce.vue:
<template>
<textarea :id="id" name="body" class="form-control" rows="5" >{{ body }}</textarea>
</template>
<script>
export default {
name: 'tinymce-editor',
props: {
body: {
default: 'Something to say, have you?'
}
},
data(){
return {
id: 'tinymce-'+Date.now(),
}
},
mounted: function() {
const self = this;
tinymce.init({
menubar: false,
path_absolute: "/",
selector: '#'+self.id,
entity_encoding: "raw",
toolbar_items_size: "small",
style_formats: [
{"title": "Bold", "icon": "bold", "format": "bold"},
{"title": "Italic", "icon": "italic", "format": "italic"},
{"title": "Underline", "icon": "underline", "format": "underline"},
{"title": "Strikethrough", "icon": "strikethrough", "format": "strikethrough"},
{"title": "Superscript", "icon": "superscript", "format": "superscript"},
{"title": "Subscript", "icon": "subscript", "format": "subscript"},
{"title": "Code", "icon": "code", "format": "code"}
],
plugins: 'advlist anchor autolink autoresize code colorpicker hr image link lists preview searchreplace spellchecker textcolor wordcount',
block_formats: "Paragraph=p;Heading 1=h1;Heading 2=h2;Heading 3=h3;Heading 4=h4;Heading 5=h5;Heading 6=h6;",
toolbar1: "undo redo | formatselect | bullist numlist | link unlink | uploadimg image",
toolbar2: "styleselect fontsizeselect | forecolor | bold italic underline strikethrough | alignleft aligncenter alignright alignjustify | outdent indent | removeformat",
init_instance_callback: function(editor) {
// init tinymce
editor.on('init', function () {
tinymce.editors[self.id].setContent(self.body);
});
editor.on('keyup', function() {
const newContent = tinymce.editors[self.id].getContent();
// Fire an event to let its parent know
self.$emit('content-updated', newContent);
});
}
});
},
update: function() {
const self = this;
if (self.body) {
tinymce.editors[self.id].setContent(self.body);
}
},
beforeDestroy: function(){
tinymce.remove(this.id)
}
}
</script>reply.blade.php:
<reply :attributes="{{ $reply }}" inline-template v-cloak>
<div id="reply-{{$reply->id}}" class="panel panel-default">
<div class="panel-heading">
<div class="level">
<h5 class="flex">
<a href="{{ route('profile',$reply->owner->name) }}">
{{ $reply->owner->name }}
</a> said {{ $reply->created_at->diffForHumans() }}...
</h5>
<favorite :reply="{{$reply}}"></favorite>
</div>
</div>
<div class="panel-body">
<div v-if="editing">
<div class="form-group">
<tinymce-editor v-model="body" body="{{ $reply->body }}" v-on:content-updated="updateBody"></tinymce-editor>
</div>
<button class="btn btn-xs btn-primary" @click="update">Update</button>
<button class="btn btn-xs btn-link" @click="editing = false">Cancel</button>
</div>
<div v-else v-html="body"></div>
</div>
@can('update', $reply)
<div class="panel-footer level">
<button class="btn btn-xs btn-success mr-1" @click="editing = true">Edit</button>
<button class="btn btn-xs btn-danger mr-1" @click="destroy">Delete</button>
</div>
@endcan
</div>
</reply>https://stackoverflow.com/questions/43820753
复制相似问题