SearchMyLogsView.vue
<!-- src/views/SearchMyLogsView.vue -->
<template>
<v-container>
<v-row>
<v-col>
<v-text-field v-model="searchTerm" label="검색어" @input="doSearchPosts" ></v-text-field>
</v-col>
</v-row>
<v-row>
<v-col v-for="mylog in filteredMylogs" :key="mylog.id" cols="12" @click="goToMylog(mylog.id)">
<v-card>
<!-- eslint-disable -->
<v-card-title style="font-size:1em" v-html="highlight(mylog.title)"></v-card-title>
<v-card-text style="font-size:1em" class="mt-n2 mb-n6" v-html="highlight(sanitizeContent(mylog.content))"></v-card-text>
<!-- eslint-enable -->
<v-card-subtitle>
<span v-if="mylog.commentCount> 0" style="cursor: pointer">댓글 {{mylog.commentCount }} </span>
{{ mylog.userName }} . {{ formatDate(mylog.createdAt) }}
<span v-if="mylog.views > 0" > ({{ mylog.views }})</span>
</v-card-subtitle>
</v-card>
</v-col>
</v-row>
</v-container>
</template>
<script>
import { mapActions, mapGetters } from "vuex";
import sanitizeHtml from 'sanitize-html';
export default {
data() {
return {
searchTerm: "" // 사용자가 입력한 검색어
};
},
computed: {
...mapGetters('mylogs',['filteredMylogs']),
},
methods: {
...mapActions('mylogs', ['searchMylogs']),
// Firestore에서 게시물 검색
async doSearchPosts() {
if (this.searchTerm) {
// title 또는 content에 검색어가 포함된 게시물 검색
await this.searchMylogs(this.searchTerm);
}
},
// content를 안전한 html로 바꿔준다.
sanitizeContent(content) {
return sanitizeHtml(content.replace(/\n/g, '<br>'), {
allowedTags: ['b', 'i', 'em', 'strong', 'p', 'br'],
allowedAttributes: {}
});
},
formatDate(date) {
if (date && date.toDate) {
return date.toDate().toISOString().replace('T', ' ').substring(0, 16);
}
return '';
},
// 게시물 세부 정보 페이지로 이동
goToMylog(mylogId) {
this.$router.push({ name: "MyLogView", params: { id: mylogId } });
},
highlight(text) {
if (!this.searchTerm)
return text;
const regex = new RegExp(`(${this.searchTerm})`, 'gi');
return text.replace(regex, '<span class="highlight">$1</span>');
}
}
};
</script>
<style>
.highlight {
background-color: yellow;
}
</style>