@x-store/vue-comments
v0.1.14
Published
A comments component for Vue.js 3
Downloads
10
Maintainers
Readme
vue-comments
Description | Install | Usage example | Options | Events | Development
Example Back-End server
Description
The tree comment component for Vue.js 3 Demo. I draw your attention to the fact that this component is not finished yet, its functionality can be changed, removed and supplemented.
- Add / edit / delete comments.
- Adding files. If there is more than one file - view in the form of a gallery.
- Emoji. Unicode characters are used as emoji. The representation of the emoji depend of the system. Will be possible that the system don't have all the representations.
- Convert http / https to hyperlink.
- Loading comments.
- The ability to limit the display of text by the number of lines / characters.
- Likes / Dislikes.
- Adaptation for mobile devices.
Install
npm install @x-store/vue-comments --save
or
yarn add @x-store/vue-comments
import Comments from '@x-store/vue-comments'
import '@x-store/vue-comments/dist/vue-comments.css'
Usage example
options
- component settings
commentsData
- initialization data. The description of the fields can be found at this link: Back-End
options.user.auth
- the parameter must be "true" so that the user can leave comments / like.
<Comments :options="options" :commentsData="comments" />
import Comments from '@x-store/vue-comments'
import '@x-store/vue-comments/dist/vue-comments.css'
export default {
components: {
Comments
},
data() {
return {
options: {
dataApi: {
vote: {
url: "/api/comments/vote/",
},
commentAdd: {
url: "/api/comments/",
},
commentDelete: {
url: "/api/comments/",
},
commentEdit: {
url: "/api/comments/",
},
commentsListGet: {
url: "/api/comments/",
},
},
user: {
auth: true,
name: "Jhon",
img: "https://evgeniysaschenko.github.io/vue-comments/user.jpg"
}
},
comments: {
mapItems: {
0: { items: [1549], quantity: 1 },
1549: { items: [1550], quantity: 1 },
1550: { items: [], quantity: 0 },
},
items: {
1549: {
dateCreate: 1632329876,
dateUpdate: 1632329889,
dislike: 0,
like: 0,
voteValue: 0,
files: [],
id: 1549,
isManageDelete: false,
isManageEdit: false,
parentId: 0,
text: "text 😇😇😇😇",
userImg: "https://evgeniysaschenko.github.io/vue-comments/user.jpg",
userName: "Jhon",
},
1550: {
dateCreate: 1632329876,
dateUpdate: 1632329889,
dislike: 0,
like: 50,
voteValue: 1,
files: [
{
name: "image 1",
preview: "https://evgeniysaschenko.github.io/vue-comments/preview.jpg",
src: "https://evgeniysaschenko.github.io/vue-comments/image.jpg",
},
],
id: 1550,
isManageDelete: false,
isManageEdit: false,
parentId: 1549,
text: "text text",
userImg: "",
userName: "Ivan",
},
},
}
}
},
}
You can change the options
after the component has been mounted by using Object.assign()
:
Object.assign(this.options, { validExtensions: ["jpg"] });
If initialization data needs to be received asynchronously, use v-if
to display the component:
<Comments v-if="isShow" :commentsData="comments" />
export default {
components: {
Comments
},
async created() {
let response = await fetch("/api/comments/?parentId=0&createUser=1");
let comments = await response.json();
this.comments = comments;
this.isShow = true;
},
data() {
return {
isShow: false,
comments: {},
user: {
auth: true,
img: "https://vue-comments.ua-ix.biz/images/users/2.jpg"
}
}
},
}
Options
You can change the behavior of the component using the options
Options description
Current user
| Parameter | Type | Default | Description |
| --- | :---: | --- | --- |
| name | String
| User Name | User name |
| img | String
| image user | User avatar |
| auth | Boolean
| false | This parameter allows you to add comments if set to "true" |
Files
| Parameter | Type | Default | Description |
| --- | :---: | --- | --- |
| filesMaxCount | Number
| Infinity | Maximum number of files to upload |
| validExtensions | Array
| ["jpg", "png", "jpeg", "jpeg", "gif", "svg", "wbpp"] | Allowed file extensions |
| isShowBtnUpload | Boolean
| true | Show button to download files |
Comments
| Parameter | Type | Default | Description |
| --- | :---: | --- | --- |
| isScrollToComment | Boolean
| true | Scroll to added comment |
| text.minLength | Number
| 0 | Minimum text length |
| text.maxLength | Number
| 1000 | Maximum text length |
| text.briefMaxLength | Number
| 150 | Maximum length of preview text (after which the "More" button is added) |
| text.briefMaxLine | Number
/ String
| 4 | Maximum number of lines of preview text (after which the "More" button is added).The values "none" and "number greater than 0" |
| list.mainShowStart | Number
| 5 | On first boot The number of comments in the main list before "Show more" |
| list.secondShowStart | Number
| 1 | On first boot The number of comments in the nested list before "Show more" appears |
| list.mainShow | Number
| 5 | Сlick "Show more" The number of comments that are displayed in the main list when you click on the button "Show more" |
| list.secondShow | Number
| 3 | Сlick "Show more" The number of comments that are displayed in the second list when you click on the button "Show more" |
| deleteCommentBefore | Function
| () => <br>{ return new Promise((resolve, reject) => { resolve }
| You can describe here the action that must be performed before deleting a comment. If resolve()
is called, the comment will be removed, unless reject()
the comment is removed. |
| deleteCommentAfter | Function
| () => <br>{ return new Promise((resolve, reject) => { resolve }
| You can describe here the action that must be performed after deleting a comment. If resolve() is called, the action will be committed, If reject() is called, the action will not be performed. |
Translation
| Parameter | Type | Default | Description |
| --- | :---: | --- | --- |
| translation.btnAnswer | String
| Answer | Answer button |
| translation.btnЕxpand | String
| More | Expand text button |
| translation.btnCollapse | String
| Collapse | Collapse button |
| translation.btnFileDownload | String
| Download | File download button |
| translation.fileDelete | String
| Delete | File delete button |
| translation.fileRestore | String
| Restore | File restore button |
| translation.dateToday | String
| Today | Text of today's date "Today" |
| translation.dateYesterday | String
| Yesterday | Yesterday's date text "Yesterday" |
| translation.dateEditedText | String
| Edited | Text before editing date |
| translation.settingsDelete | String
| Delete | Delete setting text |
| translation.settingsEdit | String
| Edit | Edit setting text |
| translation.btnMore | String
| Show more | Button "Show more" comments |
| translation.btnMoreAnswers | String
| Show answers | Button "Show answers" comments |
| translation.formPlaceholder | String
| Add a comment | Placeholder form |
| translation.btnСancelEditing | String
| Сancel editing | Answer button |
| translation.formAnswerTo | String
| Answer to | Phrase in the form when replying to a comment |
| translation.messageFileParams | String
| Maximum file size 2 Mb, supported extentions: jpg, png, jpeg, jpeg, gif, svg, wbpp | Information about the maximum file size and supported extensions |
| translation.errorFormSend | String
| Error sending form | If this field is replaced with an empty string, the response from the server can be used as an error message (the response must be a string) |
| translation.errorVoteSend | String
| Error sending vote | |
| translation.errorUnexpected | String
| Unexpected error | |
| translation.errorGetComments | String
| Error get comments | |
| translation.errorFileExtension | String
| Error file extension | |
| translation.errorFileSize | String
| Error file size | |
| translation.errorFileMaxCount | String
| Error file limit exceeded | |
| translation.errorTextLength | String
| The length of the text must be between 0 and 1000 characters | |
Data Api
| Parameter | Type | Default | Description |
| --- | :---: | --- | --- |
| dataApi.vote | Object
| send: function
url: "/"
params.method: "POST"
typeData: "form-data"
| Like / Dislike |
| dataApi.commentsListGet | Object
| send: function
url: "/"
params.method: "GET"
typeData: "query"
| Get a list of comments |
| dataApi.commentAdd | Object
| send: function
url: "/"
params.method: "POST"
typeData: "form-data"
| Add a comment |
| dataApi.commentEdit | Object
| send: function
url: "/"
params.method: "PUT"
typeData: "form-data"
| Edit a comment |
| dataApi.commentDelete | Object
| send: function
url: "/"
params.method: "DELETE"
typeData: "form-data"
| Delete a comment |
Note
url
- url of the server that processes the request
typeData
- Indicates how to prepare data for sending to the server. The options could be like this json
, query
, form-data
params
- the method of sending is specified here, you can also add additional headers
send: function
- this function is used to send data to the server, it uses the "fetch" method, if you need to use another method, the "send" function can be replaced with your own, but it must accept and return data as the code below does:
send: ({ url, params }) => {
return fetch(url, params).then((response) => {
if (!response.ok) {
return response.json().then((error)=> {
throw error?.error;
});
}
return response.json();
});
}
Other
| Parameter | Type | Default | Description |
| --- | :---: | --- | --- |
| parentIdStart | Number
/ String
| 0 | This id is for mapItems
, it describes the first level of comments. |
| emojiLilst | Array
| ["😀", "😃", "😄", "😁", "😆", "😅", "😂", "🤣", "😇", "😉", "😊", "🙂", "🙃", "😋", "😌", "😍", "🥳", "😘", "😗", "😚", "🤪", "😜", "😎", "😓", "👌", "👋", "👍", "👎"] | List emoji |
| formAddShowAlways | Boolean
| true | Using this parameter, you can show or hide the form for adding a comment. This may be needed if you do not want to show the form when the user is not logged in. |
| btnAnswerShowAlways | Boolean
| true | Use this option to show or hide the Reply to Comment button. This may be needed if you do not want to show the button when the user is not logged in. |
| imgDefaultUser | String
| image user | Default user avatar. |
| isShowVote | Boolean
| true | If true, like / dislike buttons are displayed |
| isShowBtnEmoji | Boolean
| true | Show button Emoji |
| yourCssClass | String
| | You can add your css class to the parent tag |
Options example
{
parentIdStart: 0,
isShowVote: true,
yourCssClass: "",
filesMaxCount: Infinity,
fileMaxSize: 2097152,
validExtensions: ["jpg", "png", "jpeg", "jpeg", "gif", "svg", "wbpp"],
emojiLilst: ["😀", "😃", "😄", "😁", "😆", "😅", "😂", "🤣", "😇", "😉", "😊", "🙂", "🙃", "😋", "😌", "😍", "🥳", "😘", "😗", "😚", "🤪", "😜", "😎", "😓", "👌", "👋", "👍", "👎"],
isScrollToComment: true,
isShowBtnUpload: true,
isShowBtnEmoji: true,
text: {
minLength: 0,
maxLength: 1000,
briefMaxLength: 150,
briefMaxLine: 4,
},
list: {
mainShowStart: 5,
secondShowStart: 1,
mainShow: 5,
secondShow: 3,
},
translation: {
btnAnswer: "Answer",
btnЕxpand: "More",
btnCollapse: "Collapse",
btnFileDownload: "Download",
formPlaceholder: "Add a comment",
fileDelete: "Delete",
fileRestore: "Restore",
dateToday: "Today",
dateYesterday: "Yesterday",
settingsDelete: "Delete",
settingsEdit: "Edit",
dateEditedText: "Edited:",
btnСancelEditing: "Сancel editing",
btnMore: "Show more",
btnMoreAnswers: "Show answers",
formAnswerTo: "Answer to",
messageFileParams:
"Maximum file size 2 Mb, supported extentions: jpg, png, jpeg, jpeg, gif, svg, wbpp",
errorFormSend: "Error sending form",
errorVoteSend: "Error sending vote",
errorUnexpected: "Unexpected error",
errorGetComments: "Error get comments",
errorFileExtension: "Error file extension",
errorFileSize: "Error file size",
errorFileMaxCount: "Error file limit exceeded",
errorTextLength: "The length of the text must be between 0 and 1000 characters",
},
dataApi: {
vote: {
send: ({ url, params }) => {
return fetch(url, params).then((response) => {
if (!response.ok) {
return response.json().then((error)=> {
throw error?.error;
});
}
return response.json();
});
},
url: "/",
params: {
method: "POST",
},
typeData: "",
},
commentsListGet: {
send: ({ url, params }) => {
return fetch(url, params).then((response) => {
if (!response.ok) {
return response.json().then((error)=> {
throw error?.error;
});
}
return response.json();
});
},
url: "/",
params: {
method: "GET",
},
typeData: "query",
},
commentAdd: {
send: ({ url, params }) => {
return fetch(url, params).then((response) => {
if (!response.ok) {
return response.json().then((error)=> {
throw error?.error;
});
}
return response.json();
});
},
url: "/",
params: {
method: "POST",
},
typeData: "",
},
commentEdit: {
send: ({ url, params }) => {
return fetch(url, params).then((response) => {
if (!response.ok) {
return response.json().then((error)=> {
throw error?.error;
});
}
return response.json();
});
},
url: "/",
params: {
method: "PUT",
},
typeData: "",
},
commentDelete: {
send: ({ url, params }) => {
return fetch(url, params).then((response) => {
if (!response.ok) {
return response.json().then((error)=> {
throw error?.error;
});
}
return response.json();
});
},
url: "/",
params: {
method: "DELETE",
},
typeData: "",
},
},
user: {
name: "User Name",
img: "/img/default-user.png",
auth: false,
},
formAddShowAlways: true,
btnAnswerShowAlways: true,
imgDefaultUser: "/img/default-user.png",
deleteCommentBefore: () => {
return new Promise((resolve, reject) => {
resolve();
});
},
deleteCommentAfter: () => {
return new Promise((resolve, reject) => {
resolve();
});
},
}
Events
You can get information about what action the user has taken (for example, the user has put a like), for this you need to add a message-comment listener to the component
Events example
<Comments @message-comment="messageComment($event)" />
export default {
methods: {
messageComment(data) {
console.log(data);
}
}
}
Events description
| Type | Description |
| --- | --- |
| comment-add
| Adding a comment|
| comment-edit
| Editing a comment |
| comment-delete
| Deleting a comment |
| comments-show
| By pressing the button "Show more comments" |
| vote
| Like / Dislike |
| user-no-auth
| If the user is not logged in |
Development wich Docker
- Install docker
- In order for user to get "root" rights in "Docker", you must run the command: *This is not required, but if this is not done in some situations it may be inconvenient to work
- For current user
sudo usermod -aG docker ${USER}
- For other user
sudo usermod -aG docker username123
After that, you need to restart your computer.
- To start developing. Run the following commands in the project folder:
- Create container
docker compose build
- Run container
docker compose up
Dev-server started in address http://localhost:8080/, api-sever started in address http://localhost:8888/
- Preparation for publication in "NPM" / "GitHub":
- Create "build files" in Docker (npm run build) and copy the files from Docker to a local computer
docker compose --file docker-compose-npm.yml up && docker cp -a vue-comments--front-end:/usr/src/app/vue-comments/dist-demo ./ && docker cp -a vue-comments--front-end:/usr/src/app/vue-comments/dist ./
The created folder "dist-demo" must be replaced with "https://github.com/EvgeniySaschenko/comments-api-server", in the folder "public"
Upload all changes to https://github.com/. "vue-comments" publish to "npm". "comments-api-server" upload to https://vue-comments.ua-ix.biz/.
Useful Commands
- Copy file from local computer to Docker container
docker cp -a ./package.json vue-comments--front-end:/usr/src/app/vue-comments
- Copy a file from a Docker container to a local computer
docker cp -a vue-comments--front-end:/usr/src/app/vue-comments/dist ./