欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

vue3?使用setup語(yǔ)法糖實(shí)現(xiàn)分類(lèi)管理功能

 更新時(shí)間:2022年08月18日 15:14:21   作者:Holyzq  
這篇文章主要介紹了vue3?使用setup語(yǔ)法糖實(shí)現(xiàn)分類(lèi)管理,本次模塊使用 vue3+element-plus 實(shí)現(xiàn)一個(gè)新聞?wù)镜暮笈_(tái)分類(lèi)管理模塊,其中新增、編輯采用對(duì)話(huà)框方式公用一個(gè)表單,需要的朋友可以參考下

setup語(yǔ)法糖簡(jiǎn)介

直接在 script 標(biāo)簽中添加 setup 屬性就可以直接使用 setup 語(yǔ)法糖了。

使用 setup 語(yǔ)法糖后,不用寫(xiě) setup 函數(shù),組件只需要引入不需要注冊(cè),屬性和方法也不需要再返回,可以直接在 template 模板中使用。

setup語(yǔ)法糖中新增的api

  • defineProps:子組件接收父組件中傳來(lái)的 props
  • defineEmits:子組件調(diào)用父組件中的方法
  • defineExpose:子組件暴露屬性,可以在父組件中拿到

模塊簡(jiǎn)介

本次模塊使用 vue3+element-plus 實(shí)現(xiàn)一個(gè)新聞?wù)镜暮笈_(tái)分類(lèi)管理模塊,其中新增、編輯采用對(duì)話(huà)框方式公用一個(gè)表單。

分類(lèi)模塊路由

添加分類(lèi)模塊的路由

import { createRouter, createWebHistory } from "vue-router";
import Layout from "@/views/layout/IndexView";

const routes = [
  {
    path: "/sign_in",
    component: () => import("@/views/auth/SignIn"),
    meta: { title: "登錄" },
  },
  {
    path: "/",
    component: Layout,
    children: [
      {
        path: "",
        component: () => import("@/views/HomeView"),
        meta: { title: "首頁(yè)" },
      },
      // 分類(lèi)管理
      {
        path: "/categories",
        component: () => import("@/views/categories/ListView"),
        meta: { title: "分類(lèi)列表" },
      },
    ],
  },
];

const router = createRouter({
  history: createWebHistory(process.env.BASE_URL),
  routes,
});

export default router;

分類(lèi)列表組件

views/categories/ListView.vue

<template>
  <div>
    <el-breadcrumb separator="/">
      <el-breadcrumb-item :to="{ path: '/' }">首頁(yè)</el-breadcrumb-item>
      <el-breadcrumb-item>內(nèi)容管理</el-breadcrumb-item>
      <el-breadcrumb-item>分類(lèi)列表</el-breadcrumb-item>
    </el-breadcrumb>

    <el-divider />

    <el-button type="primary">新增</el-button>

    <el-table :data="categories" style="width: 100%" class="set-top">
      <el-table-column prop="id" label="編號(hào)" width="180" />
      <el-table-column label="名稱(chēng)" width="180">
        <template #default="scope">
          <el-tag>{{ scope.row.name }}</el-tag>
        </template>
      </el-table-column>
      <el-table-column label="排序" width="180">
        <template #default="scope">
          {{ scope.row.sort }}
        </template>
      </el-table-column>
      <el-table-column label="創(chuàng)建日期" width="180">
        <template #default="scope">
          {{ formatter(scope.row.createdAt) }}
        </template>
      </el-table-column>
      <el-table-column label="操作">
        <template #default="scope">
          <el-button size="small" @click="handleEdit(scope.row)"
            >編輯
          </el-button>
          <el-popconfirm
            title="確定要?jiǎng)h除么?"
            confirm-button-text="確定"
            cancel-button-text="取消"
            @confirm="handleDelete(scope.row)"
          >
            <template #reference>
              <el-button size="small" type="danger">刪除 </el-button>
            </template>
          </el-popconfirm>
        </template>
      </el-table-column>
    </el-table>
  </div>
</template>

獲取分類(lèi)列表數(shù)據(jù)

<script setup>
  import { ref } from "vue"; // 5、導(dǎo)入 ref
  import { fetchCategoryList } from "@/api/categories"; // 6、導(dǎo)入接口 api
  import moment from "moment"; // 7、導(dǎo)入 moment 包
  import { ElMessage, ElNotification } from "element-plus"; // 9、導(dǎo)入消息通知包
  
  // 4、定義分類(lèi)列表數(shù)組
  const categories = ref([]);

  // 1、獲取分類(lèi)列表數(shù)據(jù)
  const init = async () => {
      const res = await fetchCategoryList();
      // 3、賦值
      categories.value = res.data.categories;
  };

  // 2、調(diào)用 init 方法
  init();

  // 8、時(shí)間格式化
  const formatter = (date) => {
      if (!date) {
        return "";
      }
      moment.locale("zh-cn");
      return moment(date).format("LL");
  };

  const handleEdit = (row) => {
    console.log(row);
  };
  
  // 10、點(diǎn)擊刪除按鈕
  const handleDelete = (row) => {
      try {
          const res = await deleteCategory(row.id);
          if (res.code === 20000) {
              init();
              ElNotification({
                  title: "成功",
                  message: res.message,
                  type: "success",
              });
          }
      } catch (e) {
          if (e.Error) {
            ElMessage.error(e.Error);
          }
      }
  };
</script>

分類(lèi)表單組件

1、新建 src/views/categories/components/CategoryForm.vue

<template>
  <el-dialog v-model="dialogFormVisible" title="新增分類(lèi)">
    <el-form :model="form" :rules="rules" ref="ruleFormRef">
      <el-form-item label="名稱(chēng)" :label-width="formLabelWidth" prop="name">
        <el-input v-model="form.name" autocomplete="off" size="large" />
      </el-form-item>
      <el-form-item label="排序" :label-width="formLabelWidth" prop="sort">
        <el-input v-model.number="form.sort" autocomplete="off" size="large" />
      </el-form-item>
    </el-form>
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="dialogFormVisible = false">取消</el-button>
        <el-button type="primary" @click="submitForm(ruleFormRef)">立即創(chuàng)建</el-button>
      </span>
    </template>
  </el-dialog>
</template>

<script setup>
  import { reactive, ref } from "vue";

  // 1、定義對(duì)話(huà)框?qū)傩?,默認(rèn)值為 false
  const dialogFormVisible = ref(false);

  // 2、定義表單對(duì)象和屬性
  const form = ref({
    name: "",
    sort: 0,
  });
  
  const formLabelWidth = "140px";

  // 3、表單驗(yàn)證
  const ruleFormRef = ref();
  const rules = reactive({
    name: [
      { required: true, message: "請(qǐng)輸入分類(lèi)名稱(chēng)", trigger: "blur" },
      { min: 2, max: 20, message: "長(zhǎng)度在 2 ~ 20 位", trigger: "blur" },
    ],
    sort: [
      { required: true, message: "請(qǐng)輸入排序", trigger: "blur" },
      { type: "number", message: "排序必須為數(shù)字值" },
    ],
  });
  
  // 4、表單提交
  const submitForm = async (formEl) => {
    await formEl.validate(async (valid) => {
      if (valid) {
        console.log('submit');
      }
    }
  } 
</script>

2、在 categories/ListView.vue 中引入上述表單組件

<template>
  <div>
    .
    .
    <!--表單對(duì)話(huà)框-->
    <CategoryForm ref="dialogShow" />
  </div>
</template>

<script setup>
  import CategoryForm from "./components/CategoryForm"; // 導(dǎo)入對(duì)話(huà)框組件
</script>

ref=“dialogShow”:給表單對(duì)話(huà)框起別名

3、給新增、編輯按鈕分別綁定事件,點(diǎn)擊后彈出對(duì)話(huà)框

<el-button type="primary" @click="handleCreate">新增</el-button>

<el-button size="small" @click="handleEdit(scope.row)">編輯</el-button>
// 點(diǎn)擊新增按鈕觸發(fā)子組件的 showForm 方法,并傳參 create,代表新增
const dialogShow = ref(null);
const handleCreate = async () => {
  dialogShow.value.showForm("create");
};

// 點(diǎn)擊編輯按鈕鈕觸發(fā)子組件的 showForm 方法,并傳參 edit 和編輯所需的 id 值,代表編輯
const handleEdit = async (row) => {
  dialogShow.value.showForm("edit", { id: row.id });
};

4、在表單組件中

<script setup>
  // 顯示對(duì)話(huà)框
  const showForm = async (type, data) => {
    console.log(type);
    console.log(data);
  }
</script>  

測(cè)試:此時(shí)點(diǎn)擊新增或編輯按鈕,發(fā)現(xiàn)無(wú)法觸發(fā) showForm 方法。原因在于我們要在父組件中調(diào)用子組件的方法,需導(dǎo)出子組件的方法后才能調(diào)用

<script setup>
  import { defineExpose } from "vue";

  defineExpose({
    showForm,
  });
</script>

此時(shí)再次點(diǎn)擊新增或編輯按鈕,發(fā)現(xiàn)已經(jīng)拿到了 type 和 data 的值了。

5、完成新增和編輯的對(duì)話(huà)框正常顯示

// 定義表單類(lèi)型的默認(rèn)值為 create
const formType = ref("create");

// 完成新增和編輯正常對(duì)話(huà)框顯示
const showForm = async (type, data) => {
  dialogFormVisible.value = true;
  formType.value = type;
  if (type == "create") {
    form.value = {};
  } else {
    fetchCategory(data.id).then((res) => {
      form.value = res.data.category;
    });
  }
};

對(duì)話(huà)框字體顯示

根據(jù) formType 的值判斷顯示新增或編輯

<template>
  <el-dialog
    v-model="dialogFormVisible"
    :title="formType == 'create' ? '新增分類(lèi)' : '編輯分類(lèi)'"
  >
    <el-form :model="form" :rules="rules" ref="ruleFormRef">
      <el-form-item label="名稱(chēng)" :label-width="formLabelWidth" prop="name">
        <el-input v-model="form.name" autocomplete="off" size="large" />
      </el-form-item>
      <el-form-item label="排序" :label-width="formLabelWidth" prop="sort">
        <el-input v-model.number="form.sort" autocomplete="off" size="large" />
      </el-form-item>
    </el-form>
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="dialogFormVisible = false">取消</el-button>
        <el-button type="primary" @click="submitForm(ruleFormRef)">{{
          formType == "create" ? "立即創(chuàng)建" : "立即更新"
        }}</el-button>
      </span>
    </template>
  </el-dialog>
</template>

完成新增和編輯功能

import {
  createCategory,
  fetchCategory,
  updateCategory,
} from "@/api/categories";
import { ElMessage, ElNotification } from "element-plus";

// 表單提交
const submitForm = async (formEl) => {
  await formEl.validate(async (valid) => {
    if (valid) {
      let res;
      try {
        if (formType.value == "create") {
          res = await createCategory(form.value);
        } else {
          res = await updateCategory(form.value.id, form.value);
        }
        if (res.code === 20000) {
          ElNotification({
            title: "成功",
            message: res.message,
            type: "success",
          });
          dialogFormVisible.value = false;
        }
      } catch (e) {
        if (e.Error) {
          ElMessage.error(e.Error);
        }
      }
    }
  });
};

當(dāng)新增或編輯表單提交后,新的數(shù)據(jù)要同步渲染到頁(yè)面,根據(jù)思路,我們需要調(diào)用父組件的 init 方法即可,所以這里涉及到子組件調(diào)用父組件的方法

修改父組件引用子組件的代碼,增加 @init 事件,綁定 init 方法

<!--表單對(duì)話(huà)框-->
<CategoryForm ref="dialogShow" @init="init" />

在子組件中調(diào)用,注意注釋中的代碼

// eslint-disable-next-line no-undef
const emit = defineEmits(["init"]); // 引入父組件的 init 方法
const submitForm = async (formEl) => {
  await formEl.validate(async (valid) => {
    if (valid) {
      let res;
      try {
        if (formType.value == "create") {
          res = await createCategory(form.value);
        } else {
          res = await updateCategory(form.value.id, form.value);
        }
        if (res.code === 20000) {
          ElNotification({
            title: "成功",
            message: res.message,
            type: "success",
          });
          dialogFormVisible.value = false;
          emit("init"); // 調(diào)用 init
        }
      } catch (e) {
        if (e.Error) {
          ElMessage.error(e.Error);
        }
      }
    }
  });
};

到此這篇關(guān)于vue3 使用setup語(yǔ)法糖實(shí)現(xiàn)分類(lèi)管理的文章就介紹到這了,更多相關(guān)vue3 setup語(yǔ)法糖內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • vue?使用el-table循環(huán)生成表格的過(guò)程

    vue?使用el-table循環(huán)生成表格的過(guò)程

    這篇文章主要介紹了vue?使用el-table循環(huán)生成表格的過(guò)程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-04-04
  • vue3利用store實(shí)現(xiàn)記錄滾動(dòng)位置的示例

    vue3利用store實(shí)現(xiàn)記錄滾動(dòng)位置的示例

    這篇文章主要介紹了vue3利用store實(shí)現(xiàn)記錄滾動(dòng)位置的示例,幫助大家更好的理解和學(xué)習(xí)使用vue框架,感興趣的朋友可以了解下
    2021-04-04
  • vue3.0 vant popup渲染不出來(lái)問(wèn)題及解決

    vue3.0 vant popup渲染不出來(lái)問(wèn)題及解決

    這篇文章主要介紹了vue3.0 vant popup渲染不出來(lái)問(wèn)題及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-01-01
  • vue實(shí)現(xiàn)動(dòng)態(tài)列表點(diǎn)擊各行換色的方法

    vue實(shí)現(xiàn)動(dòng)態(tài)列表點(diǎn)擊各行換色的方法

    今天小編就為大家分享一篇vue實(shí)現(xiàn)動(dòng)態(tài)列表點(diǎn)擊各行換色的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-09-09
  • 基于Vue + Axios實(shí)現(xiàn)全局Loading自動(dòng)顯示關(guān)閉效果

    基于Vue + Axios實(shí)現(xiàn)全局Loading自動(dòng)顯示關(guān)閉效果

    在vue項(xiàng)目中,我們通常會(huì)使用Axios來(lái)與后臺(tái)進(jìn)行數(shù)據(jù)交互,而當(dāng)我們發(fā)起請(qǐng)求時(shí),常常需要在頁(yè)面上顯示一個(gè)加載框(Loading),然后等數(shù)據(jù)返回后自動(dòng)將其隱藏,本文介紹了基于Vue + Axios實(shí)現(xiàn)全局Loading自動(dòng)顯示關(guān)閉效果,需要的朋友可以參考下
    2024-03-03
  • Vue中渲染系統(tǒng)模塊的實(shí)現(xiàn)詳解

    Vue中渲染系統(tǒng)模塊的實(shí)現(xiàn)詳解

    想要實(shí)現(xiàn)一個(gè)簡(jiǎn)潔版的Mini-Vue框架,應(yīng)該包含三個(gè)模塊:分別是:渲染系統(tǒng)模塊、可響應(yīng)式系統(tǒng)模塊、應(yīng)用程序入庫(kù)模塊,本文主要介紹的是渲染系統(tǒng)模塊的實(shí)現(xiàn),需要的可以參考一下
    2023-07-07
  • 詳解Vue基于 Nuxt.js 實(shí)現(xiàn)服務(wù)端渲染(SSR)

    詳解Vue基于 Nuxt.js 實(shí)現(xiàn)服務(wù)端渲染(SSR)

    直接使用 Vue 構(gòu)建前端單頁(yè)面應(yīng)用,頁(yè)面源碼時(shí)只有簡(jiǎn)單的幾行 html,這并不利于網(wǎng)站的 SEO,這時(shí)候就需要服務(wù)端渲染,本篇文章主要介紹了詳解Vue基于 Nuxt.js 實(shí)現(xiàn)服務(wù)端渲染(SSR),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-04-04
  • Vue鼠標(biāo)點(diǎn)擊事件和鍵盤(pán)事件舉例詳解

    Vue鼠標(biāo)點(diǎn)擊事件和鍵盤(pán)事件舉例詳解

    在Vue框架中我們經(jīng)常需要綁定各種JS事件,如"點(diǎn)擊事件"、"鼠標(biāo)移動(dòng)事件"、"鍵盤(pán)事件"等等,這篇文章主要給大家介紹了關(guān)于Vue鼠標(biāo)點(diǎn)擊事件和鍵盤(pán)事件的相關(guān)資料,需要的朋友可以參考下
    2024-01-01
  • vue實(shí)現(xiàn)城市列表選擇功能

    vue實(shí)現(xiàn)城市列表選擇功能

    這篇文章主要介紹了vue實(shí)現(xiàn)城市列表選擇功能,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2018-07-07
  • Vue動(dòng)態(tài)生成el-checkbox點(diǎn)擊無(wú)法賦值的解決方法

    Vue動(dòng)態(tài)生成el-checkbox點(diǎn)擊無(wú)法賦值的解決方法

    這篇文章主要給大家介紹了關(guān)于Vue動(dòng)態(tài)生成el-checkbox點(diǎn)擊無(wú)法賦值的解決方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-02-02

最新評(píng)論