摘要:項目開發過程中,元件通過render()函數渲染生成,并在元件内部定義了自定義拖拽指令。自定義拖拽指令規定了根據使用者可以進行元素拖拽、縮放等一系列邏輯處理的動作。
本文分享自華為雲社群《【Vue棘手問題解決】項目實作JS向Vue傳值》,原文作者:SHQ5785 。
前言
項目開發過程中,元件通過render()函數渲染生成,并在元件内部定義了自定義拖拽指令。自定義拖拽指令規定了根據使用者可以進行元素拖拽、縮放等一系列邏輯處理的動作。
另一個邏輯處理頁面由Vue實作,該頁面可以實時展示元素相關屬性資訊(包括size、width、height及left、top等屬性)。
思路
- 監聽器方式實作;
- 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
},
}
效果
拓展閱讀-異步請求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>
點選關注,第一時間了解華為雲新鮮技術~