• vue后台(一)


    一,项目准备工作

    1.拿到已经是二次开发的代码, npm i , 安装依赖包

    ES6模块暴露和导入复习
        1. 导出方式一: 默认一次性导出 (只能有一个)
                export default xxx
                本质: 整个模块是一个对象, 对象中有default属性, 即: {default: xxx}
        2. 导出方式二: 非默认分别导出 (可以有多个)
                export yyy
                export zzz
                本质: 整个模块是一个对象, 对象中有yyy和zzz属性, 即: {yyy, zzz}
        3. 导出方式三: 非默认统一导出 (可以有多个)
                export {yyy, zzz}
                本质:  整个模块是一个对象, 对象中有yyy和zzz属性, 即: {yyy, zzz}  
            
        4. 导入方式一: 导入默认导出的模块
                简洁写法: import xxx from './test' // 可以是任意名称
                完整写法: import {default as xxx} from './test'
        5. 导入方式二: 导入分别导出的模块
                import {yyy, zzz} from './test'  // 必须是指定的名称
        6. 导入方式三: 导入整个/所有模块(包括默认与非默认导出的)
                import * as obj from './test' // 可以是任意名称
            obj的结构: {default, yyy, zzz}
    
        7. 导入并导出: 对导入的模块同时做导出的操作
               export {default as xxx} from './test'
            export {yyy, zzz} from './test'

    2.在api中新建trademark文件夹(index.js),封装品牌分页管理的接口函数,post请求是新增数据,请求体不需要带id的,put请求是改数据,请求体需要加id

    封装商品增,删,改,查四个接口

    import request from '@/utils/request'
    
    //截取公共路径
    const api_name = '/admin/product'
    
    export default {
      /*
      获取品牌分页列表(带搜索)
      GET /admin/product/baseTrademark/{page}/{limit}
    
      */
      getPageList(page, limit) {
        //对象写法
        return request({
          url: `${api_name}/baseTrademark/${page}/${limit}`,
          method: 'get',
        })
      },
    
      /*
      增加或者修改品牌
      POST /admin/product/baseTrademark/save
      PUT /admin/product/baseTrademark/update
    
    trademark是个对象,请求体
      {
      "id": 0,
      "logoUrl": "string",
      "tmName": "string"
    }
      */ 
      addOrUpdate(trademark){
        if(trademark.id){
          //修改put请求需要有id
          return request({
            url:`${api_name}/baseTrademark/update`,
            method:'put',
            //请求体
            data:trademark
          })
        }else{
          //增加数据不需要id,post请求
          return request({
            url:`${api_name}/baseTrademark/save`,
            method:'post',
            data:trademark
          })
        }
      },
      /*
      删除 DELETE /admin/product/baseTrademark/remove/{id}
      */
      delete(id){
        return request({
          url:`${api_name}/baseTrademark/remove/${id}`,
          method:'delete'
        })
      }
      
    }

    3.然后在api(index.js)中,引入该封装接口函数的对象,然后在暴露出去

    export {default as login} from './acl/login'
    export {default as user} from './acl/user'
    export {default as role} from './acl/role'
    export {default as permission} from './acl/permission'
    export {default as category} from './category'
    export {default as clientUser} from './clientUser'
    export {default as order} from './order'
    export {default as trademark} from './trademark' //先把trademark的默认暴露引入进来

    4.在入口文件main.js引入这些接口模块

    // 引入包含所有接口请求函数模块的API对象
    import * as API from '@/api'
    Vue.prototype.$API = API
    // this.$API.trademark.getPageList

    5.在tradmark组件中发送请求,获取页面数据

    响应数据

    {
      "code": 200,
      "message": "成功",
      "data": {
        "records": [
          {
            "id": 245,
            "tmName": "摩托罗拉",
            "logoUrl": "http://182.92.128.115:8080/group1/M00/00/49/rBFUDF9I276APAugAAAV9aU5b64934.png"
          },
          {
            "id": 246,
            "tmName": "诺基亚",
            "logoUrl": "http://182.92.128.115:8080/group1/M00/00/2D/rBFUDF8hkeCAVX2oAAEGp0OpqNA105.png"
          },
          {
            "id": 247,
            "tmName": "苹果(Apple)",
            "logoUrl": "http://182.92.128.115:8080/group1/M00/00/34/rBFUDF8sAE2AACP7AAAPN5YrVxw528.jpg"
          }
        ],
        "total": 32,
        "size": 3,
        "current": 1,
        "pages": 11
      },
      "ok": true
    }
     data(){
        return {
          page:1,
          limit:5,
          total:100,
          trademarkList:[]
        }
      },
    
      mounted(){
        this.getreqPageList()
      },
    
      methods:{
        async  getreqPageList(){
          let result = await  this.$API.trademark.getPageList(this.page, this.limit)
          if(result.code ===200){
            this.trademarkList= result.data.records
            this.total= result.data.total
          }
        }
      }
    };

    6.利用element-ui框架搭建静态页面

    注;

    <!-- border 表格边框,     stripe隔行变色,-->
    <el-table :data="trademarkList" border stripe style=" 100%;margin:20px 0">


    <!-- label是每列顶部的文字说明 align="center" 每行文字居中-->
    <el-table-column align="center" label="序号" type="index" width="80"></el-table-column>

     table的每一列都是暗含了遍历我们的trademarkList 
            默认情况下,你只需要给这个列指定要显示的,对象的对应属性,然后就会展示对应这个属性的属性值,比如每列用prop="tmName",就是trademarkList 数组遍历每个对象的tmName属性
     
    <el-table-column 中的prop属性为:data="trademarkList"数组的每一个对象的属性
            但是如果你要修改这个数据的结构,那么必须使用作用域插槽的用法
     
    
           row为trademarkList的每一个对象,暗含遍历

    slot-scope="{row,$index}是固定写法,row为trademarkList的每一个对象,暗含遍历,$index为索引

    <template slot-scope="{row,$index}">
    <img :src="row.logoUrl" style="height:80px;" />
    </template>

     
    <template>
      <div>
        <el-button type="primary"  icon="el-icon-plus">添加</el-button>
        
        <el-table  :data="trademarkList" border stripe  style="100%; margin:20px 0">
          <el-table-column 
    
            label="序号"
            align="center"
            type="index"
            width="80">
          </el-table-column>
           <el-table-column 
            align="center"
            label="品牌名称"
            prop="tmName"
            width="width">
          </el-table-column>
           <el-table-column 
          
            label="品牌Logo"
            
            width="width">
            <template slot-scope="{row, $index}">
              <img :src="row.logoUrl"  style="height:80px;">
            </template>
    
          </el-table-column>
           <el-table-column 
          
           label="操作"
            
            width="width">
            <template  slot-scope="{row, $index}">
                <el-button type="warning" size="mini"   icon="el-icon-edit"></el-button>
                <el-button type="danger" size="mini"  icon="el-icon-delete" ></el-button>
                
            </template>
    
          </el-table-column>
        </el-table>
        <el-pagination
         style="text-align:center"
          :current-page="page"
          :page-sizes="[3, 5, 7, 9]"
          :page-size="limit"
          layout=" prev, pager, next, jumper ,->, sizes,total "
           @current-change="getreqPageList"
           @size-change="handleSizeChange"
          :total="total">
        </el-pagination>
        
      </div>
    </template>
    @current-change="getreqPageList" ,点击当前页的事件,重新发送请求,获取数据
     @size-change="handleSizeChange" , 点击每页的多少条事件,重新发送请求,获取数据
     
    js代码
     methods:{
        //发送请求,获取数据,点击当前页,发送请求
        async  getreqPageList(page=1){
          this.page = page
          let result = await  this.$API.trademark.getPageList(this.page, this.limit)
          if(result.code ===200){
            this.trademarkList= result.data.records
            this.total= result.data.total
          }
        },
    
        //每页多少条
        handleSizeChange(limit){
          this.limit =limit
          this.getreqPageList()
        }
      }

    7, 点击添加按钮,弹出dialog框

    title="添加"  为弹框顶部的文字
    :visible.sync="isShowDialog"  为控制dialog的框开关,在data中默认设置关闭,isShowDialog:false,
     style="80%"  为控制form表单的宽度
    :label-width="formLabelWidth"  为input的宽度, 在data中设置 formLabelWidth:'100px',
     
    :model="form"   为form表单的一个对象,为每一个el-form-item配置属性, 在data中配置
     
     form:{
            tmName:'',
          }
     
     
     
    模板页面
    :model="form"是个对象,在data中定义了, 而<el-form-item 中的v-model可以获取form的一个属性
      <el-dialog title="添加" :visible.sync="isShowDialog">
          <el-form :model="form"  style="80%">
            <el-form-item label="品牌名称" :label-width="formLabelWidth">
              <el-input v-model="form.tmName" autocomplete="off"></el-input>
            </el-form-item>
            <el-form-item label="品牌LOGO" :label-width="formLabelWidth">
              <!-- el-upload -->
              
            </el-form-item>
          </el-form>
          <div slot="footer" class="dialog-footer">
            <el-button @click="isShowDialog = false">取 消</el-button>
            <el-button type="primary" @click="isShowDialog = false"
              >确 定</el-button
            >
          </div>
        </el-dialog>
     <el-button type="primary" icon="el-icon-plus"  @click="showAddDialog">添加</el-button>
     //点击添加按钮,开启dialog弹框
        showAddDialog(){
          this.isShowDialog=true
        }

    图片

     8,

    Upload 上传

    在官网中,获取他的模板,js代码, css样式

     v-if="form.logoUrl" :src="form.logoUr"   在data中定义该数据
      <!-- el-upload -->
              <el-upload
                class="avatar-uploader"
                action="https://jsonplaceholder.typicode.com/posts/"
                :show-file-list="false"
                :on-success="handleLogoSuccess"
                :before-upload="beforeLogoUpload"
              >
                <img v-if="form.logoUrl" :src="form.logoUr" class="avatar" />
                <i v-else class="el-icon-plus avatar-uploader-icon"></i>
              </el-upload>

    js代码

      //上传成功调用
         handleLogoSuccess(res, file) {
            this.imageUrl = URL.createObjectURL(file.raw);
          },
    
          //上传之前调用,一般都是在上传之前去对要上传的文件做限制用的
          beforeLogoUpload(file) {
            const isJPG = file.type === 'image/jpeg';
            const isLt2M = file.size / 1024 / 1024 < 2;
    
            if (!isJPG) {
              this.$message.error('上传头像图片只能是 JPG 格式!');
            }
            if (!isLt2M) {
              this.$message.error('上传头像图片大小不能超过 2MB!');
            }
            return isJPG && isLt2M;
          }

     

     上传图片

    1.actions为上传图片的管理接口,本地浏览器服务器,需要到http://182.92.128.115服务器,此时需要跨域,配置代理

     
    <el-upload
                class="avatar-uploader"
                
                action="/dev-api/admin/product/fileUpload"
                :show-file-list="false"
                :on-success="handleLogoSuccess"
                :before-upload="beforeLogoUpload"
              >
      proxy: {  //localhost:9528
          // localhost:9528/admin/product/fileUpload    404
          // localhost:9528/dev-api/admin/product/fileUpload
          // http://182.92.128.115/admin/product/fileUpload
          '/dev-api': { // 匹配所有以 '/dev-api'开头的请求路径
            target: 'http://182.92.128.115', // 代理目标的基础路径
            // target: 'http://47.93.148.192',
            changeOrigin: true, // 支持跨域
            pathRewrite: { // 重写路径: 去掉路径中开头的'/dev-api'
              '^/dev-api': ''
            }
          },
        }

     上传的两个回调函数,做下处理

    //上传图片需要用的回调
        //上传成功调用
        handleLogoSuccess(res, file) {
          // this.form.logoUrl = URL.createObjectURL(file.raw);//其实本质还是拿的是本地的文件路径,我们不要这个
          this.form.logoUrl = res.data; //这个存储的就是上传成功服务器返回的真实线上路径
          console.log(this.form.logoUrl);
        },
    
        //上传之前调用,一般都是在上传之前去对要上传的文件做限制用的
        beforeLogoUpload(file) {
          const TypeArr = ["image/jpeg", "image/png"];
          const isJPGOrPNG = TypeArr.indexOf(file.type) !== -1;
          const isLt500K = file.size / 1024 < 500;
    
          if (!isJPGOrPNG) {
            this.$message.error("上传头像图片只能是 JPG或PNG 格式!");
          }
          if (!isLt500K) {
            this.$message.error("上传头像图片大小不能超过 500K");
          }
          return isJPGOrPNG && isLt500K; //返回布尔值,如果为真则上传,如果为假则报错
        },

    9,添加品牌的逻辑

    点击弹框的确定按钮,添加品牌

        <div slot="footer" class="dialog-footer">
            <el-button @click="isShowDialog = false">取 消</el-button>
            <el-button type="primary" @click="addOrupdateTrademark">确 定</el-button>
          </div>
        </el-dialog>

    js代码

     async addOrupdateTrademark() {
          //添加和修改二合一
          //找参数
          let trademark = this.form;
          //发请求,添加品牌
          const result = await this.$API.trademark.addOrUpdate(trademark);
          //成功干啥
          if (result.code === 200) {
            this.$message.success(`${trademark.id ? "修改" : "添加"}品牌成功`);
            this.getTrademarkList(trademark.id ? this.page : 1); //重新加载数据 默认添加的新的品牌在最后
            // 关闭Upload弹框
            this.isShowDialog = false;
          } else {
            //失败干啥
            this.$message.error(`${trademark.id ? "修改" : "添加"}品牌失败`);
          }
        },

    10, 每次点击添加按钮,弹出框,会出现之前的信息,必须每次在每次点击添加时,清空form数据

     //点击添加按钮,开启dialog弹框
        showAddDialog() {
          //每次点开dialog就去把form清空,保证每次弹出来都是新的form,否则就会显示上次上传的图片信息
          // 此时form没有id
          this.form = {
            tmName: "",
            logoUrl: "",
          };
          this.isShowDialog = true;
        },

    11,点击修改按钮,设置form对象,打开弹框,需要传递row,是哪个品牌

    <el-table-column label="操作" width="width">
            <template slot-scope="{row,$index}">
              <el-button
                type="warning"
                icon="el-icon-edit"
                size="mini"
                @click="showUpdateDialog(row)"
              >修改</el-button>

    js代码

      //点击修改按钮
        showUpdateDialog(trademark) {
          // this.form = trademark //添加的时候弹出dialog需要form全局清空,保证是新的,但是修改的时候修改的是哪一条,form就是谁
          // 此时form有id
          this.form = { ...trademark }; //浅拷贝
          this.isShowDialog = true;
        },

    12,删除品牌逻辑

     <el-button
                type="danger"
                size="mini"
                icon="el-icon-delete"
                @click="deleteTrademark(row)"
              >删除</el-button>

    js代码,

    confirm组件在element官网,可以去查看具体配置
      //点击删除按钮
         deleteTrademark(trademark) {
          this.$confirm(`你想删除${trademark.tmName}吗?`, "提示", {
            confirmButtonText: "确定",
            cancelButtonText: "取消",
            type: "warning",
          })
            .then(async () => {
              //点击了确定按钮
              //发送删除请求
              const result = await this.$API.trademark.delete(trademark.id);
              if (result.code === 200) {
                this.$message.success(`删除${trademark.tmName}品牌成功`);
                //重新发送请求,更新数据
                this.getreqPageList(
                  this.trademarkList.length > 1 ? this.page : this.page - 1
                );
              } else {
                this.$message.error("删除品牌失败");
              }
            })
            .catch(() => {
              //点击了取消按钮
              this.$message({
                type: "info",
                message: "已取消删除",
              });
            });
        },
  • 相关阅读:
    [leetcode] Palindrome Number
    [leetcode] Find Minimum in Rotated Sorted Array
    [leetcode] Word Search
    [leetcode] Construct Binary Tree from Preorder and Inorder Traversal
    [leetcode] Flatten Binary Tree to Linked List
    [leetcode] Recover Binary Search Tree
    [leetcode] Unique Binary Search Trees II
    [leetcode summary] Dynamic Programming
    [leetcode] Generate Parentheses
    [leetcode summary] Backtracing
  • 原文地址:https://www.cnblogs.com/fsg6/p/13576035.html
Copyright © 2020-2023  润新知