I'm trying to make editor functionality for page with Vue2. On a page there is a 'editable' filter. It recieves content_id. Using this content_id we should recieve data from root Vue instance (for example pageContent.mainTitle). Depending on editModeOn root variable we should render component or just output appropriate (for example <editable content="mainTitle" />
or content in mainTitle key).
Skeleton of HTML:
<div id="root">
{{ 'mainContent' | editable }}
<label class="checkbox">
<input type="checkbox" v-model="editModeOn">
Switch edit mode
</label>
</div>
And a Vue instance:
new Vue({
el: '#root',
data: {
editModeOn: true,
pageContent: {
mainTitle: "Test title",
mainContent: "Lorem ipsum dolor sit amet, consectetur adipisicing elit. At, et!"
}
},
filters: {
editable(contentId) {
if (!this.editModeOn) {
return `<editable content="{{ this.pageContent[contentId] }}" />`;
} else {
return this.pageContent[contentId];
}
}
}
});
The reason why I'm trying to achieve that functionality using filters is because of when edit mode disabled I don't want to make any wrapper like span or div (as it nesessary as root instance of any component).
Maybe it's a better way to achieve nesessary functionality, but I didn't find it. Has anyone an idea how to make this work? Thanks!
If I understand the problem correctly, you can solve this with a template
. A template tag is not rendered.
<div id="root">
<template v-if="!editModeOn">
{{pageContent['mainContent']}}
</template>
<editable v-else :content="pageContent['mainContent']" />
<label class="checkbox">
<input type="checkbox" v-model="editModeOn">
Switch edit mode
</label>
</div>
Looking at the html, the contentId is hard-coded into the div, so I presume you'd have many such divs on the page. I'd make a component and pass in 'content' attribute.
Switching between edit and display can be with v-show
Vue.component('editable', {
template: `
<div>
<div v-show="!editModeOn">{{ content }}</div>
<div v-show="editModeOn">
<input :value="content" @input="$emit('update:content', $event.target.value)"></input>
</div>
<label class="checkbox">
<input type="checkbox" v-model="editModeOn">
Switch edit mode
</label>
</div>
`,
props: ['content'],
data {
editModeOn: false
}
})
On the main page
<editable :content.sync="pageContent['mainTitle']"></editable>
<editable :content.sync="pageContent['mainContent']"></editable>
or perhaps
<editable v-for="item in pageContent" content.sync="item"></editable>
Some notes:
Using v-show instead of v-if means the user can toggle back and forth between show and edit as desired, v-show keeps the edit in memory between mode but v-if destroys the edit node.
Using the .sync modifier allows the edits to be passed up to the parent, see .sync
I haven't tested this, so it may need some tweaking, but you get the idea. See working example codepen
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.