Blue Chicken - The Legend Of Zelda
본문 바로가기

개인공부

문자열 찾기

주어진 요구 사항을 충족하기 위해 Vue 3의 `<script setup>` 구문을 사용하여 사용자가 입력한 텍스트를 `class='memo'` 영역의 텍스트에서 찾아서 볼드(`<b>`) 처리하는 기능을 구현할 수 있습니다. 입력한 문자열을 강조하는 방법으로, 입력값에 따라 해당 텍스트를 동적으로 갱신하는 로직을 추가할 필요가 있습니다.

아래의 코드는 사용자가 입력 필드에 텍스트를 입력하고 "찾기" 버튼을 누르면, 입력된 텍스트를 메모 내에서 검색하여 볼드 처리하는 방법을 보여줍니다. 이를 위해 Vue의 반응형 API와 문자열 처리를 조합합니다:

```vue

<template>
    <div>
        <h1>Search Page (script setup 사용)</h1>
        <label>입력하세요 : </label> 
        <form @submit.prevent="highlightText">
            <input type="text" v-model="searchQuery" />
            <button type="submit">찾기</button> <br />
        </form>
        <div class="memo" v-html="highlightedText"></div>
    </div>
</template>

<script setup>
import { ref, computed } from 'vue';

const searchQuery = ref('');
const originalText = "In the heart of an ancient forest, where sunlight filters through the dense canopy to dance upon the mossy floor, there exists a tranquil clearing. This magical glen, untouched by time and hidden from the eyes of the modern world, is home to creatures of myth and legend. Whispering winds carry tales of yore, as the forest's inhabitants move in harmony with the rhythm of nature. Here, the boundary between the realms of fantasy and reality blurs, inviting the curious and the brave to explore its mysteries. The ancient trees, standing as silent witnesses to centuries past, guard the secrets of the clearing, promising adventure and enchantment to those who dare to venture into their domain.";

// 계산된 속성을 사용하여 입력된 검색 쿼리에 따라 텍스트를 강조 표시합니다.
const highlightedText = computed(() => {
    if (!searchQuery.value) {
        return originalText;
    }
    const regex = new RegExp(`(${searchQuery.value})`, 'gi');
    return originalText.replace(regex, '<b>$1</b>');
});

// 입력 텍스트를 강조하는 함수는 실제로는 계산된 속성에서 모두 처리됩니다.
function highlightText() {
    // 여기서 추가 로직이 필요하지 않다면 이 함수는 비어 있어도 됩니다.
    // 모든 로직은 computed 속성인 highlightedText에서 처리됩니다.
}
</script>


```

### 코드 설명:
- **`v-model`**: 사용자 입력을 반응형 데이터 속성 `searchQuery`에 바인딩합니다.
- **`v-html`**: `highlightedText` 계산된 속성에서 반환된 HTML을 실제 HTML로 렌더링합니다.
- **정규 표현식 (`RegExp`)**: 검색 쿼리를 이용하여 원본 텍스트에서 해당 문자열을 찾고, `<b>` 태그로 감싸 강조 표시합니다. `gi` 플래그는 검색을 대소문자 구분 없이(`i`) 하며 전체 텍스트에서 모든 인스턴스를 찾습니다(`g`).

이 방식은 사용자가 어떤 단어든 입력하면 그 단어가 원본 텍스트 내에서 볼드 처리되어 강조됩니다. 다만, 사용자가 HTML 태그와 유사한 값을 입력할 때 XSS(Cross-site Scripting) 취약점을 고려해야 하며, 실제 배포 환경에서는 사용자 입력을 적절히 살균(sanitize)하는 것이 중요합니다.


Vue.js에서 입력 문자열을 강조하는 과정에 JavaScript의 `filter` 함수를 사용하는 것은 직접적으로 적합하지 않습니다. `filter` 함수는 배열의 요소를 기준으로 조건에 맞는 요소만을 필터링하여 새 배열을 생성하는 메서드입니다. 그러므로, 주어진 문제처럼 특정 단어나 문구를 문자열에서 찾아 강조하는 작업에는 `filter` 메서드를 사용할 수 없습니다. 대신, 이런 경우에는 `replace` 메서드나 정규 표현식을 사용하여 문자열 내에서 패턴을 찾고 변형하는 것이 일반적입니다.

### 문자열 처리의 올바른 접근 방법
문자열에서 특정 텍스트를 찾아 강조하려면 위에서 보여드린 예처럼 정규 표현식과 `replace` 메서드를 사용하는 것이 적합합니다. 여기서 `replace` 메서드는 텍스트 내에서 패턴을 찾아 다른 문자열로 대체할 수 있으므로, 검색어를 볼드(`<b>`) 태그로 감싸 강조하는 작업에 적합합니다.

### 예시
이미 제시한 코드에서는 `replace`와 정규 표현식을 사용하여 검색된 단어를 `<b>` 태그로 감싸는 방법을 사용했습니다:

```javascript
const highlightedText = computed(() => {
    if (!searchQuery.value) {
        return originalText;
    }
    const regex = new RegExp(`(${searchQuery.value})`, 'gi');
    return originalText.replace(regex, '<b>$1</b>');
});
```

### `filter` 함수의 용도
`filter` 함수의 사용 예로, 만약 배열에 저장된 여러 문장 중 특정 키워드를 포함하는 문장만을 선택하려면 `filter`를 사용할 수 있습니다:

```javascript
const sentences = [
    "Hello world",
    "This is a test",
    "Filter example"
];
const keyword = "test";
const filteredSentences = sentences.filter(sentence => sentence.includes(keyword));
```
이 예에서 `filter` 함수는 `keyword`를 포함하는 문장만을 배열에서 선택합니다. 하지만 주어진 상황에서 HTML 문자열의 일부를 동적으로 강조하려면, `filter` 대신 `replace`를 사용하는 것이 올바른 방법입니다.


<template>
    <div>
        <h1>Search Page (script setup 사용)</h1>
        <label>입력하세요 : </label> 
        <form @submit.prevent="highlightText">
            <input type="text" :value="searchQuery" @input="updateSearchQuery" />
            <button type="submit">찾기</button> <br />
        </form>
        <div class="memo" v-html="highlightedText"></div>
    </div>
</template>

<script setup>
import { ref, computed } from 'vue';

const searchQuery = ref('');
const originalText = "In the heart of an ancient forest, where sunlight filters through the dense canopy to dance upon the mossy floor, there exists a tranquil clearing. This magical glen, untouched by time and hidden from the eyes of the modern world, is home to creatures of myth and legend. Whispering winds carry tales of yore, as the forest's inhabitants move in harmony with the rhythm of nature. Here, the boundary between the realms of fantasy and reality blurs, inviting the curious and the brave to explore its mysteries. The ancient trees, standing as silent witnesses to centuries past, guard the secrets of the clearing, promising adventure and enchantment to those who dare to venture into their domain.";

// 계산된 속성을 사용하여 입력된 검색 쿼리에 따라 텍스트를 강조 표시합니다.
const highlightedText = computed(() => {
    if (!searchQuery.value) {
        return originalText;
    }
    const regex = new RegExp(`(${searchQuery.value})`, 'gi');
    return originalText.replace(regex, '<b>$1</b>');
});

function updateSearchQuery(event) {
    searchQuery.value = event.target.value;
}

function highlightText() {
    // 함수 내에서 추가 로직이 필요하지 않다면 비워두어도 됩니다.
}
</script>

일반적인 Vue 애플리케이션에서는 v-model을 사용하여 입력과 데이터 상태를 연결하는 것이 더 일반적이고, 코드 관리 측면에서 권장됩니다.

v-model을 활용하여 데이터 바인딩을 수행하고, 사용자 인터페이스와 애플리케이션의 데이터 상태 사이의 동기화를 효과적으로 관리합니다.

1. 양방향 데이터 바인딩

v-model을 사용하는 가장 대표적인 케이스입니다. 사용자 입력과 애플리케이션의 데이터 상태를 실시간으로 동기화하는 양방향 데이터 바인딩을 쉽게 구현할 수 있습니다. 예를 들어, 사용자가 입력하는 폼 데이터를 실시간으로 처리하고 검증하거나, 사용자 설정을 즉시 반영하는 인터페이스에 매우 유용합니다.

 

Vue의 반응형 시스템을 이용하는 것이 특히 유용한 몇 가지 일반적인 사용 예시는 다음과 같습니다. 이들은 v-model을 활용하여 데이터 바인딩을 수행하고, 사용자 인터페이스와 애플리케이션의 데이터 상태 사이의 동기화를 효과적으로 관리합니다.

1. 양방향 데이터 바인딩

v-model을 사용하는 가장 대표적인 케이스입니다. 사용자 입력과 애플리케이션의 데이터 상태를 실시간으로 동기화하는 양방향 데이터 바인딩을 쉽게 구현할 수 있습니다. 예를 들어, 사용자가 입력하는 폼 데이터를 실시간으로 처리하고 검증하거나, 사용자 설정을 즉시 반영하는 인터페이스에 매우 유용합니다.

<template>
  <input v-model="message">
  <p>메시지: {{ message }}</p>
</template>

<script>
export default {
  data() {
    return {
      message: ''
    };
  }
}
</script>

2. 실시간 폼 검증

사용자가 폼 필드에 데이터를 입력할 때 입력 값에 대한 유효성 검사를 실시간으로 수행합니다. v-model과 함께 컴포넌트 메서드 또는 계산된 속성을 사용하여 입력 데이터의 유효성을 체크하고 즉시 사용자에게 피드백을 제공할 수 있습니다.

<template>
  <input v-model="email">
  <p v-if="emailError">{{ emailError }}</p>
</template>

<script>
export default {
  data() {
    return {
      email: ''
    };
  },
  computed: {
    emailError() {
      const validEmail = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
      if (this.email && !validEmail.test(this.email)) {
        return '유효한 이메일 주소를 입력해주세요.';
      }
      return null;
    }
  }
}
</script>​

3. 동적 UI 업데이트

사용자의 입력에 따라 UI의 다른 부분을 즉각적으로 업데이트 해야 할 경우에도 v-model이 유용합니다. 예를 들어, 슬라이더로 특정 값을 조정하고 그에 따라 시각적 요소를 바로 변경하는 상황에서 사용할 수 있습니다.

<template>
  <input type="range" v-model="brightness" min="0" max="100">
  <div :style="{ opacity: brightness / 100 }">
    밝기: {{ brightness }}%
  </div>
</template>

<script>
export default {
  data() {
    return {
      brightness: 50
    };
  }
}
</script>

4. 복잡한 상태 관리

여러 컴포넌트 또는 복잡한 사용자 인터페이스에서 중앙 집중식 상태 관리를 사용하지 않고 v-model을 통해 로컬 상태를 관리할 수 있습니다. 이를 통해 상태 변화에 따른 UI의 갱신을 자동으로 처리할 수 있습니다.

이러한 예시들은 Vue의 반응형 시스템을 활용하여 개발자가 데이터 상태와 UI 간의 상호 작용을 효율적으로 관리할 수 있게 돕습니다. 이를 통해 코드의 복잡성을 줄이고, 개발 과정을 간소화할 수 있습니다.


정규표현식 ? 특정 규칙을 가진 문자열을 찾기 위해 사용되는 일종의 패턴

이 패턴을 사용하여 문자열 검색, 문자열 대체, 데이터 검증 등을 수행 할 수 있다.

정규 표현식은 특정 프로그래밍 언어에 국한 된 것이 아니라, 많은 텍스트 에디터, 프로그래밍 언어 및 다른 도구에서 널리 사용된다.

RegExp 생성자는 패턴을 사용해 텍스트를 판별할때 사용합니다.

캡처 그룹이란 정규 표현식에서 괄호로 둘러싼 부분이고 $1, $2 등으로 참조할 수 있다.

그래서 아래 코드에서 ()안에 searchQuery.value를 넣고 작업한다.

g와 i는 정규표현식에서 사용되는 플래그다.

더보기

g(global) : 정규 표현식이 문자열 내에서 여러 번 일치하는 모든 패턴을 찾도록 합니다. g 플래그가 없는 경우, 정규 표현식은 첫 번째 일치만 찾고 검색을 중단합니다. g 플래그가 없는 경우 정규 표현식은 첫 번째 일치만 찾고 검색을 중단합니다. g 플래그 설정 시 문자열 전체를 대상으로 모든 일치 항목을 찾는다.

i(ignore case) : 이 플래그는 대소문자를 구분하지 않고 검색을 수행합니다. 즉 A와 a를 동일하게 처리, i 플래그 없이는 정규표현식이 대소문자를 구분하여 일치를 찾는다.

const regex = new RegExp(`(${searchQuery.value})`, 'gi');
return originalText.replace(regex, '<b>$1</b>');

Computed 속성과 watch 속성은 모두 반응형 데이터를 기반으로 코드를 실행하지만 사용 목적과 방식이 다르다.

Computed 속성

목적 : 데이터의 변경에 따라 자동으로 계산되어야 하는 값을 정의할 때 사용

특징 : 계산된 값을 캐싱하며, 의존하는 반응형 데이터가 변경될 때만 함수가 재실행 됩니다. 즉, 의존하는 데이터가 변하지 않으면, 이전에 계산된 값을 재사용합니다.

용도 : 복잡한 로직을 통해 데이터를 변환하거나 여러 소스의 데이터를 결합하여 새로운 값을 도출할 때 주로 사용됩니다. 예를 들어, 사용자 이름과 성을 결합하여 전체 이름을 생성하는 경우 등

사용 예 : 사용자가 제공한 이름과 성을 기반으로 전체 이름을 자동으로 생성

 

watch 속성

목적 : 데이터의 변화를 감지하고 데이터의 변경에 반응하여 특정 작업을 수행

특징 : 데이터가 변할 때마다 지정된 함수가 실행되며, 데이터의 이전 값과 현재 값을 모두 알 수 있다.

용도 : 데이터 변경에 따라 비동기적 또는 시간이 많이 소요되는 작업을 수행할 때 유용, 예를 들어 사용자의 입력에 기반하여 서버 요청을 보내는 경우, 로컬 스토리지의 데이터를 업데이트하는 경우 

사용 예 : 사용자의 위치 정보가 바뀔 때마다 날씨 정보를 업데이트 하는 기능에 사용

 

Vue에서 사용할 수 있는 그 외의 속성

Methods 속성 (Methods):

  • 설명: 메소드는 Vue 인스턴스에 정의된 함수들입니다. 이 메소드들은 이벤트에 반응하거나 재사용 가능한 로직을 수행하는 데 사용됩니다. 예를 들어, 버튼 클릭 시 수행될 작업을 메소드로 정의할 수 있습니다.
  • 사용 예: 사용자가 '로그인' 버튼을 클릭할 때 로그인 처리를 수행하는 함수를 메소드로 정의합니다.

Data 속성 (Data):

  • 설명: 데이터 속성은 Vue 인스턴스의 반응형 데이터를 정의합니다. 이 데이터는 애플리케이션의 상태를 저장하고, 템플릿에서 직접 바인딩되어 동적인 콘텐츠를 만드는 데 사용됩니다.
  • 사용 예: 사용자의 입력을 저장하는 변수, 메시지 목록, 선택된 아이템의 상태 등을 데이터로 관리할 수 있습니다.

Props 속성 (Props):

  • 설명: Props는 부모 컴포넌트로부터 자식 컴포넌트로 데이터를 전달할 때 사용합니다. 이를 통해 부모 컴포넌트와 자식 컴포넌트 간에 데이터를 공유할 수 있습니다.
  • 사용 예: 사용자 목록 컴포넌트에서 각 사용자의 상세 정보를 보여주는 자식 컴포넌트로 사용자 데이터를 props로 전달할 수 있습니다.

이러한 속성들은 Vue.js에서 애플리케이션의 다양한 기능과 상호작용을 구현하는 데 중요한 역할을 합니다. 각각의 속성이 애플리케이션의 특정 측면을 담당하며, 함께 사용되어 복잡한 기능을 쉽고 효과적으로 구현할 수 있습니다.