主要工具
这里以页面新增弹窗举例
主页面
<template>
<QueryForm queryname="名称" @queryfn="queryfn" />
<TableComp
:tableData="tableData"
@queryListFn="queryListFn"
:total="total"
@sendPage="sendPage"
@sendcurrent="sendcurrent"
v-if="tableData.length"
/>
<add-user :shoplistone="shoplistone" @queryListFn="queryListFn" />
</template>
<script lang="ts" setup>
import QueryForm from "@/components/QueryForm.vue";
import TableComp from "@/components/TableComp.vue";
import AddUser from "@/components/AddUser.vue";
import { shoplist } from "@/http/api/login";
import { onMounted, ref } from "vue";
import lodash from "lodash";
import { devicelist } from "@/http/api/login";
onMounted(() => {
getUser1();
shoplist1();
});
const sendPage = (page: number) => {
console.log(page, "pahe");
pageSize = page;
getUser1();
};
const sendcurrent = (current: number) => {
console.log(current, "cuure");
pageNum = current;
getUser1();
};
let query = "";
let pageNum = 1;
let pageSize = 5;
const tableData = ref<any>([]);
const total = ref<number>(0);
const shoplistone = ref<any>([]);
const queryfn = (shopName: string) => {
query = shopName;
getUser1();
};
const queryListFn = () => {
getUser1();
};
const getUser1 = () => {
devicelist({
shopName: query,
pageNum: pageNum,
pageSize: pageSize,
}).then((res: any) => {
console.log(res, "res");
lodash.cloneDeep(res.rows);
tableData.value = lodash.cloneDeep(res.rows);
total.value = res.total;
});
};
const shoplist1 = () => {
shoplist({
pageNum: pageNum,
pageSize: pageSize,
}).then((res: any) => {
lodash.cloneDeep(res.rows);
shoplistone.value = lodash.cloneDeep(res.rows);
});
};
</script>
//这里注意列表页一定要加上v-if="tableData.length"
//否则列表子组件解构时第一次为空值
列表页
<template>
<el-table :data="tableData" style="width: 100%">
<el-table-column label="Date">
<template #default="scope">
<div style="display: flex; align-items: center">
<el-icon><timer /></el-icon>
<span style="margin-left: 10px">{{ scope.row.createTime }}</span>
</div>
</template>
</el-table-column>
<el-table-column label="名称">
<template #default="scope">
<el-popover effect="light" trigger="hover" placement="top" width="auto">
<template #default>
<div>name: {{ scope.row.name }}</div>
</template>
<template #reference>
<el-tag>{{ scope.row.name }}</el-tag>
</template>
</el-popover>
</template>
</el-table-column>
<el-table-column prop="shopName" label="商户" />
<el-table-column prop="sn" label="sn" />
<el-table-column prop="brand" label="品牌" />
<el-table-column label="操作">
<template #default="scope">
<el-button size="small" @click="handleEdit(scope.$index, scope.row)"
>编辑</el-button
>
<el-button
size="small"
type="danger"
@click="handleDelete(scope.$index, scope.row)"
>删除</el-button
>
</template>
</el-table-column>
</el-table>
<div class="demo-pagination-block">
<el-pagination
v-model:currentPage="currentPage4"
v-model:page-size="pageSize4"
:page-sizes="[5, 10, 15, 20]"
:small="small"
:disabled="disabled"
:background="background"
layout="total, sizes, prev, pager, next, jumper"
:total="total"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</div>
<h1 @click="add">{{ counter }}</h1>
</template>
<script lang="ts" setup>
import { Timer } from "@element-plus/icons-vue";
import { onMounted, ref } from "vue";
import { useStore } from "@/store/store";
import { storeToRefs } from "pinia";
import { devicedel } from "@/http/api/login";
import { ElMessage, ElMessageBox } from "element-plus";
import mittBus from "@/hooks/mittBus";
import lodash from "lodash";
const store = useStore();
const { tableData, total } = defineProps<{
tableData: Array<object>;
total: number;
}>();
console.log(tableData, total);
const shoplist = ref<any>([]);
const currentPage4 = ref(1);
const pageSize4 = ref(5);
const small = ref(false);
const background = ref(false);
const disabled = ref(false);
const { counter } = { ...storeToRefs(store) };
interface User {
date: string;
name: string;
address: string;
}
interface Emits {
(event: "queryListFn"): void;
(event: "sendPage", page: number): void;
(event: "sendcurrent", current: number): void;
}
const emit = defineEmits<Emits>();
onMounted(() => {
// shoplist1();
console.log("启动了");
});
const handleSizeChange = (val: number) => {
console.log(`${val} items per page`);
emit("sendPage", val);
// pageSize = val;
};
const handleCurrentChange = (val: number) => {
console.log(`current page: ${val}`);
emit("sendcurrent", val);
};
const handleEdit = (index: number, row: any) => {
console.log(index, row);
mittBus.emit("openEdit", row);
};
const handleDelete = (index: number, row: any) => {
console.log(index, row);
ElMessageBox.confirm("是否确认删除?", "提示", {
confirmButtonText: "确认",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
devicedel(row.id).then((res: any) => {
console.log(res);
console.log("测试");
//子传父
emit("queryListFn");
//手动清空
// form.shopName=""
});
ElMessage({
type: "success",
message: "删除成功!",
});
})
.catch(() => {
ElMessage({
type: "info",
message: "已取消",
});
});
};
const add = () => {
//第一种方法
//store.counter += 10;
//第二种
// store.$patch({
// counter: store.counter + 10,
// });
//第三种
// store.$patch((state) => {
// state.counter += 10;
// });
//第四种 利用actions来修改数据
store.piniaAdd();
};
//常见问题
</script>
mitt的使用
\src\hooks\mittBus.ts
import mitt from 'mitt';
const mittBus = mitt();
export default mittBus;
查询
<template>
<el-form :inline="true" :model="formInline" class="demo-form-inline">
<el-form-item :label="queryname">
<el-input v-model="formInline.shopName" placeholder="请输入名称" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">查询</el-button>
<el-button type="primary" @click="addUser">新增</el-button>
</el-form-item>
</el-form>
</template>
<script lang="ts" setup>
import { reactive } from "vue";
import mittBus from "@/hooks/mittBus";
defineProps<{ queryname: string }>();
interface Emits {
(event: "queryfn", name: string): void;
}
const emit = defineEmits<Emits>();
interface FormInline {
shopName: string;
}
const formInline = reactive<FormInline>({
shopName: "",
});
const onSubmit = () => {
emit("queryfn", formInline.shopName);
};
const addUser = () => {
mittBus.emit("openAdd");
};
</script>
Mitt的使用(兄弟间组件传值)
import mitt from 'mitt';
const mittBus = mitt();
export default mittBus;
新增页面
<script lang="ts" setup>
import { device } from "@/http/api/login";
import { ref, reactive } from "vue";
import type { FormInstance, FormRules } from "element-plus";
import { ElMessage } from "element-plus";
import mittBus from "@/hooks/mittBus";
const dialogFormVisible = ref(false);
const ruleFormRef = ref<FormInstance>();
defineProps<{ shoplistone: Array<Object> }>();
interface Emits {
(event: "queryListFn"): void;
}
const emit = defineEmits<Emits>();
const settleList: any = [
{
value: "1",
label: "测试1",
},
{
value: "2",
label: "测试2",
},
{
value: "3",
label: "测试3",
},
{
value: "4",
label: "测试4",
},
];
const statusList: any = [
{
value: "0",
label: "关闭",
},
{
value: "1",
label: "开启",
},
];
const form = reactive({
id: "",
shopName: "",
shopUid: "",
type: "",
status: "",
sn: "",
brand: "",
title: "新增用户",
btnText: "添加用户",
});
const rules = reactive<FormRules>({
shopName: [
{ required: true, message: "Please input Activity name", trigger: "blur" },
],
shopUid: [
{ required: true, message: "Please input Activity name", trigger: "blur" },
],
type: [
{ required: true, message: "Please input Activity name", trigger: "blur" },
],
status: [
{ required: true, message: "Please input Activity name", trigger: "blur" },
],
sn: [
{ required: true, message: "Please input Activity name", trigger: "blur" },
],
brand: [
{ required: true, message: "Please input Activity name", trigger: "blur" },
],
});
const handleClose = (done: () => void) => {
dialogFormVisible.value = false;
};
mittBus.on("openAdd", () => {
dialogFormVisible.value = true;
form.title = "新增用户";
form.btnText = "确认添加";
(form.id = ""),
(form.shopName = ""),
(form.shopUid = ""),
(form.type = ""),
(form.status = ""),
(form.sn = ""),
(form.brand = "");
});
mittBus.on("openEdit", (row: any) => {
dialogFormVisible.value = true;
form.title = "编辑用户";
form.btnText = "确认修改";
(form.id = row.id),
(form.shopName = row.name),
(form.shopUid = row.shopUid),
(form.type = row.type),
(form.status = row.status),
(form.sn = row.sn),
(form.brand = row.brand);
});
const sureAdd: any = async (formEl: FormInstance | undefined) => {
if (!formEl) return;
await formEl.validate((valid, fields) => {
if (valid) {
console.log("submit!");
console.log(form);
device({
name: form.shopName,
shopUid: form.shopUid,
type: form.type,
status: form.status,
sn: form.sn,
brand: form.brand,
}).then((res: any) => {
console.log(res);
console.log("测试");
ElMessage({
message: "新增成功",
type: "success",
});
//子传父
emit("queryListFn");
//手动清空
// form.shopName=""
formEl.resetFields();
});
dialogFormVisible.value = false;
} else {
console.log("error submit!", fields);
// dialogFormVisible.value = false;
}
});
};
const sureEdit: any = async (formEl: FormInstance | undefined) => {
if (!formEl) return;
await formEl.validate((valid, fields) => {
if (valid) {
console.log("submit!");
console.log(form);
device({
id: form.id,
name: form.shopName,
shopUid: form.shopUid,
type: form.type,
status: form.status,
sn: form.sn,
brand: form.brand,
}).then((res: any) => {
console.log(res);
console.log("测试");
ElMessage({
message: "编辑成功",
type: "success",
});
//子传父
emit("queryListFn");
//手动清空
// form.shopName=""
formEl.resetFields();
});
dialogFormVisible.value = false;
} else {
console.log("error submit!", fields);
// dialogFormVisible.value = false;
}
});
};
</script>
<template>
<el-dialog
v-model="dialogFormVisible"
:title="form.title"
width="30%"
:before-close="handleClose"
>
<el-form :model="form" ref="ruleFormRef" :rules="rules">
<el-form-item label="名称" prop="shopName">
<el-input v-model="form.shopName" placeholder="请输入名称" />
</el-form-item>
<el-form-item label="商户" prop="shopUid">
<el-select
v-model="form.shopUid"
placeholder="请选择"
style="width: 50%"
>
<el-option
v-for="dict in shoplistone"
:key="dict.shopUid"
:label="dict.name"
:value="dict.shopUid"
/>
</el-select>
</el-form-item>
<el-form-item label="类型" prop="type">
<el-select v-model="form.type" placeholder="请选择" style="width: 50%">
<el-option
v-for="dict in settleList"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-select
v-model="form.status"
placeholder="请选择"
style="width: 50%"
>
<el-option
v-for="dict in statusList"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="SN" prop="sn">
<el-input
v-model="form.sn"
style="width: 50%"
placeholder="请输入SN"
></el-input>
</el-form-item>
<el-form-item label="品牌" prop="brand">
<el-input
v-model="form.brand"
style="width: 50%"
placeholder="请输入品牌"
></el-input>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogFormVisible = false">关闭</el-button>
<el-button
type="primary"
@click="sureAdd(ruleFormRef)"
v-if="form.title == '新增'"
>{{ form.btnText }}</el-button
>
<el-button
type="primary"
@click="sureEdit(ruleFormRef)"
v-if="form.title == '编辑'"
>{{ form.btnText }}</el-button
>
</span>
</template>
</el-dialog>
</template>
<style lang="scss" scoped></style>
pinia基本用法
import { defineStore } from 'pinia'
export const useStore = defineStore('storeId', {
state: () => {
//存放的就是模块的变量
return {
counter: 0,
name: 'Eduardo',
isAdmin: true,
}
},
getters: {
//相当于vue里面的计算属性 可以缓存数据
nameLength: (state) => state.name.length,
},
persist: { // 固化插件
enabled: true, // 开启存储
strategies: [ // 指定存储的位置以及存储的变量都有哪些,该属性可以不写,
//在不写的情况下,默认存储到 sessionStorage 里面,默认存储 state 里面的所有数据。
{ storage: localStorage, paths: ["counter"] }
// paths 是一个数组,如果写了 就会只存储 count 变量,当然也可以写多个。
]
},
actions: {
async insertPost(data: string) {
//可以通过actions方法 改变state里面的值
// 可以做异步
// await doAjaxRequest(data);
this.name = data;
},
piniaAdd() {
setTimeout(() => {
this.counter += 50
}, 2000)
// this.counter++
// 特别注意:在这里this指向的就是当前的实例化出来的对象,piniaAdd 该函数如果换成箭头函数的话,this 指向就会发生 改变,不能再使用 this.count++; 了
}
},
})