首頁 > 軟體

Vue通過字串關鍵字元實現動態渲染input輸入框

2022-12-09 14:02:29

今天做一個簡單的demo,就是有一個字串,字串裡面有識別符號,前端檢測到識別符號之後,需要將這個識別符號轉換成一個 input 輸入框並且進行資料輸入和繫結功能。

問題描述

就比如現在有這樣一個字串:

你好,我是{name},我今年{age} 歲,我喜歡的運動是{play}。

前端需要把 {xxx} 及其包裹的內容轉變成一個輸入框渲染出來,並且呢,當在輸入框輸入資料的時候,需要對輸入的內容進行獲取。即,轉變成下面的樣子進行展示:

當然可以再此基礎上進行一些其他功能的開發,今天主要說一下這個功能的實現。

{ xxx } 標識字元渲染Dom

元件設計

首先我們把這個功能編寫成一個簡單的元件,這個元件的功能很簡單,就是接受父元件傳進來的字串,檢測到 { } 包裹的資料,把對應的部分渲染為 input 輸入框,並且可以對這個父元件傳進來的字串資料進行修改。

元件開發

OK,我們先編寫一個元件。首先先實現一個曉得功能,接受父元件傳遞進來的字串,然後把 { } 包裹的資料解析成 input 輸入框展示出來。

元件很簡單,html 標籤的話,就是使用一個簡單的 p 標籤,因為我們是使用的 vue 開發,我們需要動態的渲染 dom 節點的話,我們可以使用 vue 的 v-html 進行渲染。

<p class="title" v-html="domRender(strData)"></p>

這段程式碼很簡單,但是一定要注意是 v-html,然後繫結了一個方法 domRender,其中回撥傳進去的 strData 引數是父元件傳進子元件的字串資料物件。

比如說父元件中有一個陣列:

dataList: [{
  index: 1,
  data: "你好,我是{name},我今年{age} 歲,我喜歡的運動是{play}。"
}],

我們需要把這個列表的第一個物件傳遞給我們的處理子元件。

首先子元件需要一個 props 接受父元件傳進的字串物件:

  props: {
    str: {
      type: Object,
      required: false,
    },
  },

因為我們後期可能需要修改這個字串內容,所以說呢,我們藉助計算屬性,來處理一下這個字串物件。提前宣告一個 currData 變數為 null 。

  computed: {
    strData: {
      get() {
        if (this.currData) {
          return this.currData
        } else {
          return this.str
        }
      },
      set(value) {
        this.currData = value
      }
    }
  },

OK,上面這個程式碼都很簡單,就不需要過多的解釋了哈。上面這一部分和我們單純渲染 input 關係不大。

重點

最重要的部分來了,就是將 { } 的部分,渲染成 input 輸入框,首先呢,我們肯定是使用正規表示式,獲取到 { } 部分,然後用 input 替換一下就可以了。

domRender(str) {
  let strData = str
  var reg = /{.*?}/g
  strData = strData.replace(reg, '<input class="emptyOut" type="text" />');
  return strData
},

OK,就上面四行程式碼,就成功的把 { } 渲染成 input 輸入框了。

但是!有問題!

【思考】我們成功的把資料渲染成了 dom 顯示在頁面了,但是渲染的目的是啥?資料的輸入啊!我有一個表單,我想把 你好,我是{name},我今年{age} 歲,我喜歡的運動是{play}。 中 {name} 渲染成的輸入框中輸入的資料,繫結到表單的 name 欄位,{age} 渲染成的輸入框中輸入的資料,繫結到表單的 age欄位,play 欄位同理。這時候就發現,我們可以輸入內容,但是沒法系結啊!怎麼辦!

【解答】對嘍!一下就反應過來了吧,我們給這個輸入框繫結一個屬性值,然後我們在輸入框輸入完資料之後,比如焦點消失,我們就可以獲取這個輸入框物件,然後根據繫結的屬性,就可以獲取要在表單中繫結的欄位和值是什麼了。

OK,這個時候,我們就需要遍歷每一個輸入框,然後獲取這個 { } 中的欄位,然後繫結成 input 輸入框繫結的屬性值就可以了。

    domRender(str) {
      let strData = str
      var reg = /{.*?}/g
      let result = str.match(reg)
      if (!result) {
        return strData
      }
      for (let i = 0; i < result.length; i++) {
        let a = result[i]
        if (a == '{}') {
          continue
        }
        let r = str.match(a)[0]
        let id = r.slice(1, -1)
        strData = strData.replace(r, '<input idData=' + id + ' class="emptyOut" type="text" />');
      }
      return strData
    },

好的,這樣的話,我們就給輸入框繫結了一個屬性,屬性值就是要繫結的表單欄位。

好!完成!已經成功繫結。

接下來,就是我們輸入資料之後,獲取輸入框資料的值,然後把內容返回給父元件就可以了。

輸入完成事件

首先,在父元件有一個表單資料:

form:{}

子元件輸入完成之後,子元件把輸入好的資料傳遞給父元件,父元件將子元件傳遞回來的資料儲存到 fom 就可以啦!

其實很簡單的我們只需要監聽輸入框輸入完成就可以了吧!怎麼監聽呢,其實很麻煩,我也是試了好幾種方案。

首先我們介面有一個按鈕,點選按鈕的時候執行一個方法,獲取繫結的值。

<el-button type="success" @click="printData()" size="mini">列印資料</el-button>

關鍵是 printData() 方法裡面怎麼寫?

我們在之前動態渲染的時候都給 input 設定了一個 class 屬性對吧?我們點選事件裡面,肯定可以獲取這些 input 框吧!那麼我們就可以獲取這些輸入框繫結的屬性和輸入的值吧?

    printData() {
      let data = {}
      const elements = document.getElementsByClassName("emptyOut");
      for (let i = 0; i < elements.length; i++) {
        const item = elements[i]
        data[item.attributes.idData.value] = item.value
      }
      console.log('資料---->> ', data)
    }

好,這樣的話我們就可以獲取到輸入框輸入的值了。然後子元件把資料傳遞給父元件就可以了,父元件怎麼處理在寫響應的邏輯就可以了吧!OK,就這樣。

OK,這是一個方式哈。還有一種哈,稍微說一下。

上面是點選按鈕獲取資料,還有一個是使用 @input 方法。

<p class="title"  @input="addComment($event)" v-html="domRender(strData)"></p>

在相應的標籤上新增 input 事件。

	// 修改輸入框文字資料
    addComment(event) {
      console.log("--->> ", event.target.attributes.idData.value, event.target.value)
    },

這樣的話,我們每次修改輸入框內容的時候,都會列印出我們這個輸入框的資料值。

看效果,還可以哈!拿到資料值了,怎麼使用就看具體業務了。

動態編輯文字

上面我們說了,給一個字串,把關鍵內容使用 dom 輸入框渲染,現在在做一個小功能,就是可以手動編輯文字。

上面我們接受父元件傳進來資料是使用計算屬性得到的值 strData。所以我們寫一個輸入框繫結要輸入的內容,也就是這個 strData 。在寫一個按鈕,點選按鈕的時候切換編輯和預覽就可以了。很簡單沒啥好說的。

<template>
  <div class="dom-item">
    <el-input v-show="!preview" type="textarea" :rows="2" placeholder="請輸入內容" v-model="strData">
    </el-input>
    <p class="title" v-show="preview" @input="addComment($event)" v-html="domRender(strData)"></p>
    <button class="dom-btn" @click="preview = !preview"> {{ preview ? '編輯' : '預覽' }}</button>
  </div>
</template>

然後看一下效果。

然後需要處理什麼邏輯自己去根據需求實現就可以了。

完成!!!

其實還有一些細節或者是優化的地方,因為在實際開發過程中,會發現我寫的這些並不是所有的功能都能實現,或者是實現的不是很好,因為還有一部分我沒有說,不想說了,這一塊描述起來太複雜,但是呢,如果真的想實現的話,自己寫的話就會發現這個問題自己能解決了也就,我說有點多餘。

到此這篇關於Vue通過字串關鍵字元實現動態渲染input輸入框的文章就介紹到這了,更多相關Vue動態渲染input輸入框 內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com