前端實操案例丨如何實現JS向Vue傳值

華為雲開發者社群發表於2021-05-19
摘要:專案開發過程中,元件通過render()函式渲染生成,並在元件內部定義了自定義拖拽指令。自定義拖拽指令規定了根據使用者可以進行元素拖拽、縮放等一系列邏輯處理的動作。

本文分享自華為雲社群《【Vue棘手問題解決】專案實現JS向Vue傳值》,原文作者:SHQ5785 。

前言

專案開發過程中,元件通過render()函式渲染生成,並在元件內部定義了自定義拖拽指令。自定義拖拽指令規定了根據使用者可以進行元素拖拽、縮放等一系列邏輯處理的動作。

另一個邏輯處理頁面由Vue實現,該頁面可以實時展示元素相關屬性資訊(包括size、width、height及left、top等屬性)。

思路

  1. 監聽器方式實現;
  2. Vuex state實現;

程式碼實現

.js

// 滑鼠按下事件
el.onmousedown = function (e) {
    ...
  document.onmouseup = function (e) {
      document.body.style.cursor = 'pointer';
      document.onmousemove = null;
      document.onmouseup = null;
      isMove = false;
      document.body.removeChild(mask);
      // 元素樣式relative下方位屬性
      let domStyle = {
        width: data.width,
        height: data.height,
        left: data.left,
        top: data.top
      }
      el.style.cssText = setStyle(el, domStyle)
      // Vuex state實現方式
      store.commit('domAzimuth/SET_DOMAZIMUTION', el.style.cssText);
      // 監聽器實現方式
      // window.postMessage({domStyle: domStyle}, '*')
}

}

.vue

 computed: {
      ...mapGetters('dragModule', ['editLayer']),
      ...mapGetters('domAzimuth', ['directProps']),
      domStyle () {
        return this.directProps
      }
    },
    // 監聽器方式中,務必在頁面銷燬前釋放掉監聽器,否則會造成記憶體洩漏!
    beforeDestroy () {
//      window.removeEventListener('message', this.listenerMessage)
    },
    mounted () {
//      window.addEventListener('message', this.listenerMessage)
    },
    watch: {
      domStyle (n) {
        let configs = []
        let model = {}
        for (let name in this.editSoul.model) {
          let config = this.editSoul.model[name]
          model[name] = ''
          config.name = name
           if ('style' === name) {
              config.value = this.directProps
            }
          configs.push(config)
        }
        this.model = model
        this.configs = configs
      },
}

效果

前端實操案例丨如何實現JS向Vue傳值

擴充閱讀-非同步請求Promise導致頁面資料渲染錯誤問題解決措施

場景描述

在Vue專案優化過程中,頁面部分應用JS呼叫promise返回的非同步資料,導致頁面部分始終無法載入後臺返回的資料值。通過觸發其他DOM操作(例如摺疊欄位的操作),後臺資料可以正常渲染展示。處理邏輯大致如下:

<template>
    <div v-for="(items, index) in results" :key="items.itemsID">
        <span v-for="(item, index) in items.appendItems" :key="item.itemID">
            <el-button type="text" @click="handlerClick(item)">
                {{item.itemName}}
            </el-button>
        </span>
    </div>
</template>
<script>
    results.foreach((result, index, results) => {
        results[index].appendItems = []
        aysnMethods(inputParams).then(res => {
            results[index].appendItems = res.returnResults
        })
    })
</script>

問題分析

經過頁面資料輸出及debugger斷點除錯,發現在頁面渲染結束前,非同步資料並未處理完畢,導致頁面資料渲染問題。

當vue例項生成後,再次給物件賦值時,並不會自動更新到檢視上去; 當我們去看vue文件的時候,會發現有這麼一句話:如果在例項建立之後新增新的屬性到例項上,它不會觸發檢視更新。

受 ES5 限制,Vue.js 不能檢測到物件屬性的新增或刪除,即Vue未做到髒資料檢查。因為 Vue.js 在初始化例項時將屬性轉為 getter/setter,所以屬性必須在 data 物件上才能讓 Vue.js 轉換它,才能讓它是響應的。

解決措施

通過以上問題分析,可通過v-if控制頁面渲染、銷燬邏輯,在非同步方法請求前銷燬相應資料段,非同步方法請求成功後新建相應資料段。
程式碼如下:

<template>
    <div v-if="showForm">
        <div v-for="(items, index) in results" :key="items.itemsID">
            <span v-for="(item, index) in items.appendItems" :key="item.itemID">
                <el-button type="text" @click="handlerClick(item)">
                    {{item.itemName}}
                </el-button>
            </span>
        </div>
    </div>
</template>
<script>
    data(): {
        return {
            showForm: false
        }
    }
    results.foreach((result, index, results) => {
        results[index].appendItems = []
        vm.showForm = false
        aysnMethods(inputParams).then(res => {
            results[index].appendItems = res.returnResults
            vm.showForm = false
        })
    })
</script>

 

點選關注,第一時間瞭解華為雲新鮮技術~

相關文章