# 常用函数
提供常用的VUE 的模板函数
# Loading 加载
<script>
const loading = this.$loading({
lock: true,
text: '正在提交数据......',
// text: '正在加载数据......',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.3)'
})
loading.close()
</script>
# El-table 表格
# 序号
<el-table-column label="#" type="index" align="center" width="50">
<template slot-scope="scope">
<span>{{ (queryParams.pageNum - 1) * queryParams.pageSize + scope.$index + 1 }}</span>
</template>
</el-table-column>
# El-input-number 数字输入框
<el-form-item label="建筑面积" prop="buildArea">
<div style="display: flex; width: 100%">
<el-input-number
:min="0"
:precision="2"
style="width: calc(100% - 80px)"
controls-position="right"
v-model="form.buildArea"
placeholder="请输入建筑面积"
/>
<div class="el-input-group__append" style="width: 80px; height: 40px;text-align: center;">平方米</div>
</div>
</el-form-item>
# El-cascader 级联选择器
<!-- 搜索 -->
<el-form-item label="所属区域" prop="gridId">
<el-cascader clearable
placeholder="请选择所属区域"
:props="areaProps"
:show-all-levels="false"
:options="areaTree"
v-model="queryParams.areaCode"
></el-cascader>
</el-form-item>
<!-- 新增 -->
<el-form-item label="所属区域" prop="areaCode">
<el-cascader clearable
ref="cascader"
@change="getNodeChange"
placeholder="请选择所属区域"
style="width: 100%"
:props="areaProps"
:options="areaTree1"
v-model="form.areaCode"
></el-cascader>
</el-form-item>
<script>
export default {
data() {
return {
areaInitCode: '0',
areaInitLevel: 1,
loadingArea:false,
areaTree: [],
areaTree1: [],
areaProps: {
lazy: true,
checkStrictly: true,
emitPath: false,
lazyLoad: (node, resolve) => {
console.log('node==>', node)
if (node.value) {
getAreaTreeApi(node.value).then(res => {
const data = res.data.map(item => {
return {
label: item.areaName,
value: item.areaCode,
...item
}
})
resolve(data)
})
}
}
},
}
},
methods: {
async initArea() {
this.loadingArea = false
try {
const res = await getAreaTreeApi(this.areaInitCode)
this.areaTree = res.data.map(item => {
return {
label: item.areaName,
value: item.areaCode,
...item
}
})
this.loadingArea = true
} catch (e) {
this.$modal.msgError('获取搜索框中的所属区域失败')
}
},
getNodeChange() {
const checkedNodes = this.$refs?.cascader?.getCheckedNodes()
console.log('getCheckedNodes==>', checkedNodes)
this.$set(this.form.company.area, 'areaCode', checkedNodes?.[0].value)
this.$set(this.form.company.area, 'areaName', checkedNodes?.[0].label)
this.$set(this.form, 'gridName', checkedNodes?.[0]?.pathLabels?.join(' / '))
this.$set(this.form.company, 'fullName', checkedNodes?.[0]?.pathLabels?.join(' / '))
this.$refs.cascader.dropDownVisible = false
},
// 以下是修改用到的
async handleUpdate() {
// 获取区域树
if (this.form.gridId) {
this.areaTree1 = await this.getAreaTreeByCode(this.form.gridId)
} else {
this.areaTree1 = [...this.areaTree]
}
},
async getAreaTreeByCode(fullCode) {
// 解析完整代码,获取每一层级的代码
const temp = fullCode.substring(0, 6)
// 完整的层级数组
const fullLevels = ['0', temp.substring(0, 2) + '0000', temp.substring(0, 4) + '00', temp]
// 根据 this.areaInitLevel 截取数组
const levels = fullLevels.slice(this.areaInitLevel)
for (let i = 6; i < fullCode.length; i += 3) {
levels.push(fullCode.substring(0, i + 3))
}
console.log('levels==>', levels)
// 从根代码开始递归构建区域树
return await this.buildTree(levels, 0)
},
async buildTree(levels, currentLevelIndex) {
// 获取当前层级的代码
const currentCode = levels[currentLevelIndex]
// 延迟 500 毫秒
await new Promise((resolve) => setTimeout(resolve, 300))
// 调用 API 获取当前层级的区域数据
const res = await getAreaTreeApi(currentCode)
const currentLevelData = res.data.map((item) => ({
label: item.areaName,
value: item.areaCode,
...item,
children: []
}))
// 如果当前层级是最后一层,直接返回当前层级数据
if (currentLevelIndex === levels.length - 1) {
return currentLevelData
}
// 否则,递归获取下一层级的数据,并将其作为当前层级的 children
for (let i = 0; i < currentLevelData.length; i++) {
const currentArea = currentLevelData[i]
if (currentArea.value === levels[currentLevelIndex + 1]) {
// 找到匹配的子区域,递归获取其子层级
currentArea.children = await this.buildTree(levels, currentLevelIndex + 1)
break // 只处理匹配的子区域
}
}
return currentLevelData
},
}
}
</script>
# $Set
# 对象使用方法
<script>
export default {
setValue() {
// 如果没有使用 this.$set,视图不会更新
this.$set(this.form, '字段名', undefined);
}
}
</script>
# 数组使用方法
<script>
export default {
setValue() {
// 使用索引直接修改数组元素,视图可能不会更新
// this.arr[1] = 'orange'; // 这可能不会触发视图更新
// 使用 this.$set
this.$set(this.arr, 1, 'orange'); // 这会触发视图更新
}
}
</script>
# Computed
<script>
export default {
calcPrice() {
const {pchmNum, pchmUnitPrice} = this.form
if (pchmNum && pchmUnitPrice) {
let price = pchmNum * pchmUnitPrice;
this.form.pchmLumpSum = price
return price;
} else {
return 0
}
}
}
</script>
# Watch
# 基础用法
<script>
export default {
watch: {
id: {
handler(newValue, oldValue) {
console.log('value==>', newValue)
},
deep: true,
immediate: true
},
}
}
</script>
# 搜索框用法
<script>
export default {
watch: {
showSearch: {
handler(value) {
if (value === false) {
this.tableHeight += this.$refs.queryForm?.$el?.clientHeight ?? 0
} else if (value === true) {
this.$nextTick(() => {
this.tableHeight -= this.$refs.queryForm?.$el?.clientHeight ?? 0
})
}
}
}
}
}
</script>
# 路由用法
搭配 路由跳转-JS 使用
<script>
export default {
watch: {
$route: {
handler(value) {
console.log('value==>', value)
if (value.path === ENUM.ROUTE.NOTICE_DESCRIPTION) {
let id = value.query.row
console.log('id==>', id)
if (!id) {
this.$modal.msgError('获取项目ID失败,请关闭当前页面重新进入!')
} else {
this.currentId = id
}
}
},
deep: true,
immediate: true
}
},
}
</script>
# 透传
提示
包含 属性透传
、 具名插槽透传
、事件监听器透传
<template>
<el-dialog v-bind="$attrs" v-on="$listeners">
<slot></slot>
<template v-for="(_, name) in $slots" v-slot:[name]="data">
<slot :name="name" v-bind="data"/>
</template>
</el-dialog>
</template>