vue3 TS elementplus项目总结

主要工具

elementplus
mitt
pinia

这里以页面新增弹窗举例

主页面

<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++; 了
        }
    },
})

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值