暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Vue.JS 3:样例「数据表」

Nephilim 2024-03-11
57

Tips:一些记录,一些笔记



2024/03/11

MONDAY

JMOE proficient and trades.

门门精通,样样稀松。





01

一个「数据表」的样例


通过这个样例的演示,你可以看到Vue.JS 3中的以下技巧的具体实现:

  • Vite配置:服务器配置、代理配置(如何避免跨域问题)

  • AXIOS请求远端接口

  • REF函数

  • ELEMENT PLUS中的组件EL-TABLE的数据绑定

  • 如何将页面上的数据传递给后端处理逻辑

  • Vue.JS 3:组件之间的数据传递、方法调用、事件声明与使用


前提:


本项目仅展示前端项目的代码,后端项目很简单,不予说明,仅描述接口文档;

这也符合日常编程的时候的场景,后端项目只会提供接口给你,你并不能去修改后端的代码,只需要通过对方提供的API进行交互即可。


后端代码在我本地的运行地址:

'http://127.0.0.1:5174/'

后端代码提供了三个接口:

  • 获取数据:/list

  • 删除数据:/del/:id

  • 编辑数据:/edit/:id


02

代码「vite.config.js」


文件「vite.config.js」

    // Vite的配置文件


    import { fileURLToPath, URL } from 'node:url'


    import { defineConfig } from 'vite'
    import vue from '@vitejs/plugin-vue'


    // https://vitejs.dev/config/
    export default defineConfig({
    plugins: [
    vue(),
    ],
    resolve: {
    alias: {
    '@': fileURLToPath(new URL('./src', import.meta.url))
    }
    },
    server: {
    port: 5173, // 启动本地服务显示IP
    host: "0.0.0.0",
    open: true,
    cors: true,


    proxy: {
    '/list': {
    target: 'http://127.0.0.1:5174/list',
    changeOrigin: true,
    rewrite: (path) => path.replace(/^\/list/, ""),
    },
    '/del': {
    target: 'http://127.0.0.1:5174/del',
    changeOrigin: true,
    rewrite: (path) => path.replace(/^\/del/, ""),
    },
    '/edit': {
    target: 'http://127.0.0.1:5174/edit',
    changeOrigin: true,
    rewrite: (path) => path.replace(/^\/edit/, ""),
    }
    }
    },
    })



    当前的前端项目是通过「vite」创建的,因此,要修改项目的运行相关的配置,需要在Vite的配置文件中进行。


    通过上面的配置文件的源码可以看到:

    • 该项目启动后的运行端口是「5173」

    • 在项目启动后,自动打开浏览器

    • 开启了「跨域CORS」

    • 设置了三个代理:

      • /list

      • /del

      • /edit


    代理的目标(Target)就是对应的后端数据接口的地址;

    用这种方式,将不在同一个域名内的远端地址进行转换,就可以有效的避免「跨域问题」


    03

    Vue组件「DataTable.vue」


    这是一个父组件;

    文件「DataTable.vue」

      <script setup>
      import { onMounted, ref } from 'vue';
      import axios from 'axios';
      import DataTableEdit from './DataTableEdit.vue'


      // TODO:数据源渲染


      // 声明变量:响应式LIST
      const dataList = ref([])


      // 调用接口:获取数据
      const getDataList = async () => {
      // 接口调用
      const res = await axios.get(
      // 代理中定义的路由
      '/list',
      // 代理中定义的路由 + 当前项目的域名
      // 'http://127.0.0.1:5173/list',
      // {
      // headers: {
      // 'Cache-Control': 'no-cache'
      // }
      // }
      )


      // 后端数据 赋值给 LIST对象
      dataList.value = res.data
      }


      onMounted(() => getDataList())


      // TODO:删除功能
      const onDelete = async (id) => {
      // 测试
      // console.log(" 当前选中的是「" + id + "」");
      // console.log(id);


      // 执行删除
      await axios.delete(
      // `http://127.0.0.1:5173/del/${id}`,
      `/del/${id}`,
      )


      // 更新数据渲染
      getDataList()
      }


      // TODO:编辑功能
      const DataTableEditRef = ref(null)
      const onEdit = (row) => {
      DataTableEditRef.value.open(row);
      }
      </script>


      <template>
      <div class="app">
      <!-- <el-table :data="[{
      id: 1,
      name: 'leviathan',
      place: 'China'
      }]"> -->


      <!-- 绑定Table组件 -->
      <el-table :data="dataList">
      <el-table-column label="ID" prop="id"></el-table-column>
      <el-table-column label="姓名" prop="name" width="150"></el-table-column>
      <el-table-column label="所在地" prop="place"></el-table-column>
      <el-table-column label="操作" width="150">
      <template #default="{ row }">
      <el-button type="primary" @click="onEdit(row)" link>编辑</el-button>
      <el-button type="danger" @click="onDelete(row.id)" link>删除</el-button>
      </template>
      </el-table-column>

      </el-table>
      </div>


      <DataTableEdit ref="DataTableEditRef" @on-update="getDataList" >
      </template>


      <style scoped>
      .app{
      width: 980px;
      /* margin: 100px auto 0; */
      }
      </style>



      04

      Vue组件「DataTableEdit.vue


      这是一个子组件;

      文件「DataTableEdit.vue」

        <script setup>
        import { ref } from 'vue';
        import axios from 'axios';


        const form = ref({
        id: '',
        name: '',
        place: ''
        })


        // 是否显示弹窗
        const dialogVisible = ref(false)


        const open = (row) => {
        console.log("当前行数据:",row);
        form.value.id = row.id;
        form.value.name = row.name;
        form.value.place = row.place;


        dialogVisible.value = true;
        }


        const emit = defineEmits([
        'on-update'
        ])


        const onUpdate = async () => {


        // 接口调用
        await axios.patch(
        // `/edit/${form.value.id}`,
        `http://127.0.0.1:5173/edit/${form.value.id}`,
        {
        name: form.value.name,
        place: form.value.place
        }
        )
        // 关闭弹窗
        dialogVisible.value = false


        // 通知父组件
        emit('on-update')


        }


        defineExpose({
        open,
        })
        </script>


        <template>
        <el-dialog v-model="dialogVisible" title="编辑" width="400px">
        <el-form label-width="50px">
        <el-form-item label="姓名">
        <el-input placeholder="请输入姓名" v-model="form.name" >
        </el-form-item>
        <el-form-item label="地区">
        <el-input placeholder="请输入所在地" v-model="form.place" >
        </el-form-item>
        </el-form>
        <template #footer>
        <span class="dialog-footer">
        <el-button @click="dialogVisible = false">取消</el-button>
        <el-button type="primary" @click="onUpdate">确认</el-button>
        </span>
        </template>
        </el-dialog>
        </template>


        <style scoped>
        .el-input {
        width: 290px;
        }
        </style>



        05

        运行效果






        END




        温馨提示



        如果你喜欢本文,请分享到朋友圈,想要获得更多信息,请关注我。


        文章转载自Nephilim,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

        评论