Vueは検索結果を実現してキーワードをハイライト表示します。


本論文の例では、Vueの検索結果を共有し、キーワードを表示するための具体的なコードを表示します。
1.解決すべき問題
  • 親コンポーネントは、検索されたフィールドをサブアセンブリ
  • に送る。
  • サブコンポーネントは、データを受け取り、正則一致し、フィールドを置換する。
  • 2.具体的なコード
    親コンポーネントコード
    
    <template>
     <div>
     <div v-if="showMe">
     <div class="re_search">
      <svg @click="$router.go(-1)">
      <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#arrow-left.6f6409e" rel="external nofollow" ></use>
      </svg>
      <input type="search" v-model="search_text" class="v-md" placeholder="       " @keydown.enter="search_method">
     </div>
     <OneBusiness v-for="(item, n) in search_res" :key="n" :item="item" :search_text="search_text"></OneBusiness>
     </div>
     <!--&lt;!&ndash;   Fixednav      &ndash;&gt;-->
     <div class="space"></div>
     <!--       -->
     </div>
    </template>
    
    <script>
    import { mapGetters } from 'vuex';
    import OneBusiness from './small_components/One_business';
    import {getSearchData} from 'src/service/getData'
    
    
    export default {
     name: 'search',
     data () {
     return {
      showMe: false,
      search_text: '', //      
      search_res: [] //     
     };
     },
     mounted () {
     this.$store.dispatch('setLoading', true);
     //     
     var time = Math.floor(Math.random() * 2000);
     console.log('      ' + time);
     setTimeout(() => {
      this.$store.dispatch('setLoading', false);
      this.showMe = true;
     }, time);
     this.search_method();
     },
     computed: {
     ...mapGetters([
      'getFalseBussinessbrief' //       
     ])
     },
     methods: {
     async search_method () {
    
      var mainWord = this.$route.params.keyword;
      if (this.search_text !== '' && this.search_text !== this.$route.params.keyword) {
      mainWord = this.search_text;
      }
      this.search_text = mainWord;
      this.search_res = (await getSearchData(this.search_text)).obj.results;
      console.log(this.search_res);
     }
     },
     components: {
     OneBusiness
     }
    };
    </script>
    
    <style lang="less" scoped>
    .re_search{
     background:#0096ff;
     line-height:0;
     padding: .2rem;
     svg{
     width:.6rem;
     height:.6rem;
     }
     input[type="search"]{
     display:inline-block;
     height:.9rem;
     width:8rem;
     outline: none;
     border: none;
     border-radius:.45rem;
     background:#f2f2f2;
     box-sizing: border-box;
     padding: 0 .5rem;
     font-size:.4rem;
     }
    }
    </style>
    サブコンポーネントコード
    
    <template>
     <!--        -->
     <section class="tj_business" >
     <section class="one_business clear">
      <div class="business_img">
      <img src="../../images/guozhao.png" alt="">
      </div>
      <div class="business_info">
      <section class="business_name clear">
       <router-link :to="'/business/' + item.classNum">
       <h3 class="fl ell"><span v-if="item.className">  </span> {{item.classNum}} {{ item.className }}</h3>
       </router-link>
       <div class="name_icon fr">
       <div class="code_num fr">
        <svg @click="add_cart(item.id)" style=" width: .5rem; height: .5rem;">
        <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#cart-minus" rel="external nofollow" ></use>
        </svg>
       </div>
       </div>
      </section>
      <section class="business_code clear">
       <div class="code_num fl">
       <!--<svg class="v-md">-->
        <!--<use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#rating-star" rel="external nofollow" ></use>-->
       <!--</svg>-->
       <span class="v-md">【{{item.parentNum}} 】{{ item.groupName }}</span>
       </div>
       <div class="code_icon fr">
       </div>
      </section>
      <section class="business_other clear">
       <div class="other_price fl">
       <span class="com_gray1" v-html="ruleTitle"></span>
       <span>/</span>
       <span class="com_gray1">{{ item.number }}</span>
       </div>
       <div class="other_dis fr">
       </div>
      </section>
      </div>
     </section>
    
     </section>
    
    </template>
    
    <script>
     import {
     addMyshopcart,
     } from 'src/service/getData'
    
     export default {
     name: 'one_business',
     props: {
      search_text:String,
      item:{}
     },
     data () {
      return {
      msg: '1'
    
      };
     },
     mounted () {
    
     },
     computed: {
      isLogin () {
      return this.$store.getters.getLogin;
      },
      ruleTitle() {
      let titleString = this.item.gname;
      if (!titleString) {
       return '';
      }
      if (this.search_text && this.search_text.length > 0) {
       //        
       let replaceReg = new RegExp(this.search_text, 'g');
       //     v-html 
       let replaceString = '<span class="search-text">' + this.search_text + '</span>';
       //     
       titleString = titleString.replace(replaceReg, replaceString);
      }
      return titleString;
      }
     },
     methods: {
      async add_cart(id){
      if (!this.isLogin) {
       this.$router.replace('/login');
      } else {
       var userId = this.$store.getters.getuname;
       var result = await addMyshopcart(id, userId)
       console.log(result.resMsg)
    
       if (result.res === 1) {
       this.$router.replace('/ShopCart/' + userId);
       } else {
       alert(result.resMsg)
       }
      }
      }
     }
    
     };
    </script>
    
    <!-- Add "scoped" attribute to limit CSS to this component only -->
    <style lang="less">
     @baseBlue: #0096ff;
     @com_gray1: #666;
     @com_gray2: #999;
    .search-text{
     color: #52250a;
     background: #ffd930;
     font-size: .2rem;
     padding: .02rem;
     border-radius: 2px;
     vertical-align: top;
     margin-right: .04rem;
    }
    
    
     .com_gray1 {
     color: @com_gray1;
     }
    
     .com_gray2 {
     color: @com_gray2;
     }
    
     .com_blue {
     color: @baseBlue;
     }
    
     /*      */
     .one_business {
     background: #fff;
    
     .business_img {
      width: 1.6rem;
      height: 1.6rem;
      padding: 0.4rem;
      float: left;
      img {
      width: 100%;
      height: 100%;
      }
     }
     .business_info {
      float: right;
      width: 7.4rem;
      height: 1.6rem;
      padding: 0.4rem .2rem .4rem 0;
      .business_name {
      font-size: .35rem;
      line-height: .45rem;
      vertical-align: top;
      h3 {
       width: 5rem;
       display: inline-block;
       /*span {*/
       /*color: #52250a;*/
       /*background: #ffd930;*/
       /*font-size: .2rem;*/
       /*padding: .02rem;*/
       /*border-radius: 2px;*/
       /*vertical-align: top;*/
       /*margin-right: .04rem;*/
       /*}*/
      }
      .bzp {
       width: .3rem;
       height: .3rem;
       font-size: .26rem;
       text-align: center;
       line-height: .3rem;
       display: inline-block;
       color: @com_gray2;
       border: 0.01rem solid #ddd;
       padding: 0.01rem;
       border-radius: 3px;
       i {
       font-style: normal;
       }
    
      }
      }
      .business_code, .business_other {
      font-size: .25rem;
      margin-top: .3rem;
      line-height: .25rem;
      }
    
     }
     .code_num {
      svg {
      width: .3rem;
      height: .3rem;
      fill: #ffaa0c;
      }
     }
     .zsd {
      font-size: .25rem;
      height: .35rem;
      line-height: .3rem;
      padding: 0 0.05rem;
      display: inline-block;
      color: @baseBlue;
      background: #fff;
      border: 0.01rem solid @baseBlue;
      box-sizing: border-box;
      border-radius: 3px;
     }
     .fnzs {
      font-size: .25rem;
      height: .35rem;
      padding: 0 0.05rem;
      line-height: .3rem;
      display: inline-block;
      background: @baseBlue;
      color: #fff;
      border: 0.01rem solid @baseBlue;
      box-sizing: border-box;
      border-radius: 3px;
     }
     }
    </style>
    以上が本文の全部です。皆さんの勉強に役に立つように、私たちを応援してください。