Vue PWA mylog

mylog 찾기

그랜파 개발자 2024. 11. 22. 15:42

Vue로 PWA 개발 - 그랜파 개발자

Vue 프로젝트 Beta Test : mylog, 일상의 기록

개발이 진행됨에 따라 소스 코드를 계속 추가해 갑니다.

mylog 찾기

마이로그의 찾기는 아주 단순합니다. 검색어를 입력하여 찾기를 하면 제목 또는 내용에 입력한 검색어가 포함되어 있는 모든 마이로그를 찾습니다. 장난감 수준이기는 하지만 아쉬운대로 쓸만합니다. 찾기 기능을 좀 더 고도화 하려면 고려해야 할 것들이 많습니다. 여기서는 검색어를 입력하여 검색어를 포함하는 마이로그를 찾는 것으로 만족하려 합니다.

 

전체 마이로그는 이미 로드되어 있습니다. 검색어를 입력하면 제목 또는 내용에 검색어를 포함하고 있는 마이로그를 로드되어 있는 마이로그에서 필터를 적용하여 검색 결과를 구합니다. 영문의 경우 대소문자 구분없이 찾기 위하여 검색어를 소문자로 만들고 마이로그 제목과 내용도 소문자로 만들어 필터를 적용합니다.

const searchTermLower = searchTerm.toLowerCase();
let filteredMylogs = []; 
filteredMylogs = getters.mylogs.filter((mylog) => {   
  // title 또는 content에 검색어가 포함된 게시물 검색  
  return (
    mylog.title.toLowerCase().includes(searchTermLower) ||
    mylog.content.toLowerCase().includes(searchTermLower)
  );
});

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 }}&nbsp; &nbsp;</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>

mylogs.js

// src/store/modules/mylogs.js
import { v4 as uuidv4 } from 'uuid';
import { db, doc, collection, getDoc, getDocs, setDoc, addDoc,updateDoc, deleteDoc, arrayUnion, increment, where } from "@/firebase";
import { query, orderBy } from "@/firebase";

const state = {
  . . .
  filteredMylogs: [], // 검색된 게시물 목록
};

const mutations = {
  . . .
  setFilteredMylogs(state, filteredMylogs) {  // 마이로그 찾기
    state.filteredMylogs = filteredMylogs;
  },
};

const actions = {
  . . .
  // Firestore에서 게시물 검색
  async searchMylogs({ commit, getters }, searchTerm ) {
    // 검색어를 소문자로 
    const searchTermLower = searchTerm.toLowerCase();
    let filteredMylogs = [];    
    // 검색된 결과 필터링
    filteredMylogs = getters.mylogs.filter((mylog) => {   
      // title 또는 content에 검색어가 포함된 게시물 검색  
      return (
        mylog.title.toLowerCase().includes(searchTermLower) ||
        mylog.content.toLowerCase().includes(searchTermLower)
      );
    });
    commit('setFilteredMylogs', filteredMylogs); // 검색 결과를 상태에 저장    
  },
};

const getters = {
  . . .
  filteredMylogs: state => state.filteredMylogs,  // 검색된 게시물 목록
};

export default {
  namespaced: true,
  state,
  mutations,
  actions,
  getters
};

Vue PWA 프로젝트, mylog 코드

'Vue PWA mylog' 카테고리의 다른 글

mylog FCM과 서비스 워커  (2) 2024.11.24
mylog 독자  (1) 2024.11.23
mylog 내것  (0) 2024.11.21
mylog 쓰기  (0) 2024.11.20
mylog 구독  (0) 2024.11.19