将 v-for 逻辑移动到计算属性
Posted
技术标签:
【中文标题】将 v-for 逻辑移动到计算属性【英文标题】:Move v-for logic to computed property 【发布时间】:2021-09-02 04:51:29 【问题描述】:我的代码没有错(我希望),尽管我觉得它可以写得更好。我试过移动
从计算属性到计算属性的逻辑但不成功,我认为表结构不正确,但我没有想法。任何人都可以帮忙吗? 不幸的是,“tabl”来自服务器,我无法更改此变量
<template>
<movable-div>
<template #header>
<div class="header">
<h3> name </h3>
<div @mousedown.stop="dragMouseDown">
<input type="text" v-model="search" placeholder="Search..." />
</div>
<div class="button-group">
<svg viewBox="0 0 10240 10240" @click="toggleTable()" :class="[showTable ? 'go' : 'back']">
<path some long svg code... />
</svg>
<p @click="showTableAttributes()">X</p>
</div>
</div>
<table v-if="showTable">
<tr>
<th v-for="head in tableHead" :key="head.Name">
head.Name
</th>
</tr>
<tr
v-for="row in filteredRow"
:key="row.Key"
class="data"
@click="zoomToFeatureExtent(row)"
>
<td v-for="item in tableHead" :key="item.Name">
<p v-html="row.filter((obj) => obj.Key === item.Name)
.map((item) => item.Value)
.join()
.replace(search, `<span style='color:#1D7CA7'><b>$search</b></span>`)">
</p>
</td>
</tr>
</table>
</template>
</movable-div>
</template>
<script>
export default
props: ['olMap', 'LayerStyleName', 'name'],
data()
return
tableHead: null,
rows: null,
table:
ColumnList: [name: "ex1",name: "ex2"],
Name: "Example",
RowList: [Original:[Key: "ex1", Value: "exampleValue"],
Original:[Key: "ex2", Value: "exampleValue"]]
,
showTable: true,
layer: null,
filteredRow: [],
search: null,
;
,
mounted()
this.rows = this.table.RowList;
this.tableHead = this.table.ColumnList.filter((item) => item.Name !== 'geometry');
this.search = '';
,
inject: ['showTableAttributes'],
methods:
toggleTable()
this.showTable = !this.showTable;
,
zoomToFeatureExtent(value)
let extent = value
.filter((item) => item.Key === 'geometry')
.map((item) => item.Value);
let view = this.olMap.getView();
view.fit(extent[0], this.olMap.getSize());
let res = view.getResolution();
if (res < 0.5)
view.setResolution(0.9);
,
,
watch:
search: function (val)
this.filteredRow = [];
for (let row of this.rows)
if (row.Original.map((obj) => obj.Value.toString().includes(val))
.filter((i) => (i === true ? i : null))
.join())
this.filteredRow.push(row.Original);
else null;
,
,
;
</script>
【问题讨论】:
您还可以将<p v-html
中的代码移动到采用row
、item
和search
的方法中。计算属性不能接受参数 AFAIK。
【参考方案1】:
最好让模板不包含任何复杂的逻辑(恕我直言)。它使代码更易于维护,因为您的模板和脚本之间没有功能分离。如果您可以将方法卸载到缓存变量,从而防止代码的静态部分不必要地重新计算,它还可以提高性能。
以下是改进潜力的一个很好的例子
<tr
v-for="row in filteredRow"
:key="row.Key"
class="data"
@click="zoomToFeatureExtent(row)"
>
<td v-for="item in tableHead" :key="item.Name">
<p
v-html="row.filter((obj) => obj.Key === item.Name)
.map((item) => item.Value)
.join()
.replace(search, `<span style='color:#1D7CA7'><b>$search</b></span>`)"
></p>
</td>
</tr>
我发现在模板中阅读此内容比在脚本块(但 YMMV)中更难,但在性能方面,您正在执行额外的循环。这个脚本在这里做了 3 个循环:行(filteredRow
),列(tableHead
),然后再行(row.filter
)。
如果将逻辑移动到computed
,可以简化逻辑并提高性能。 computed
将保持数据缓存并根据需要进行更新,因此,如果您更改 search
的值,它将重新计算,但如果不相关的变量发生更改,则不会更改,并且模板不必更改重新计算值。在您的代码中,其他值似乎没有太大变化,但无论如何都是良好的做法。
这可能看起来像(未经测试的代码)
computed:
tableData()
return this.filteredRow.map(row =>
const cols = [];
this.tableHead.forEach(item =>
let value = "";
if (col.Name === row.Key)
let value = item.Value.replace(search, `<span style='color:#1D7CA7'><b>$search</b></span>`)
cols.push(value)
);
return ...row, cols;
)
,
<table v-if="showTable">
<tr>
<th v-for="head in tableHead" :key="head.Name">
head.Name
</th>
</tr>
<tr
v-for="row in tableData"
:key="row.Key"
class="data"
@click="zoomToFeatureExtent(row)"
>
<td v-for="(cell, i) in row.cols" :key="i">
<p v-html="cell"></p>
</td>
</tr>
</table>
【讨论】:
首先,非常感谢您的帮助。我知道这是从模板中分离逻辑的良好做法,这就是我寻求帮助的原因。我稍微修改了您的代码,现在一切正常。再感谢你的帮助:)以上是关于将 v-for 逻辑移动到计算属性的主要内容,如果未能解决你的问题,请参考以下文章