vue-day11

vue-day11

1-管理员管理

1.1-管理员编辑&删除

pages/admin/List.vue

<template>
  <div>
    <el-table :data="adminList" style="width: 100%">
      <el-table-column prop="id" label="id" min-width="80"></el-table-column>
      <el-table-column prop="rolename" label="角色" min-width="180"></el-table-column>
      <el-table-column prop="username" label="账号" min-width="180"></el-table-column>
      <el-table-column prop="status" label="状态" min-width="180">
         <template v-slot="props">
           <el-tag type="success" v-if="props.row.status===1">正常</el-tag>
           <el-tag type="danger" v-else>禁用</el-tag>
         </template>
      </el-table-column>
      <el-table-column label="操作" min-width="180">
        <template v-slot="props">
          <el-button @click="edit(props.row)" size="mini" circle type="success" icon="el-icon-edit"></el-button>
          <el-button @click="del(props.row.uid)" size="mini" circle type="danger" icon="el-icon-delete"></el-button>
        </template>
      </el-table-column>

    </el-table>
    <!-- 
      total:数据总条数
      page-size: 每页显示的数据条数
      current-change: 分页按钮点击事件
    -->
    <el-pagination @current-change="pageUpdate" :page-size="size" background layout="prev, pager, next" :total="adminTotal"></el-pagination>
  </div>
</template>

<script>
// 导入事件中心
import vm from '../../utils/vm';
export default {
  props:['adminTotal','adminList','size','page'],
  data() {
    return {}
  },
  methods:{
    //  分页按钮被点击的处理函数
    // page: 分页按钮的页码, 系统自动注入
    pageUpdate(page){
      // 通过this.$emit()将最新页码值传递给父组件Index
      this.$emit('updatePage',page);
    },
    // 编辑
    edit(row){
      // 通过自定义事件将数据传递给兄弟组件Modal
      vm.$emit('sendData',{...row});
    },
    // 删除
    del(uid){
      this.$myConfirm(()=>{
        this.$http.post('/userdelete',{uid}).then(res=>{
          if(res.code===200){
            this.$success(res.msg);
            // 更新数据列表
            this.$emit('updateList');
          }else{
            this.$error(res.msg);
          }
        });
      });
    }
  }
};
</script>

pages/admin/Index.vue

<template>
  <el-card>
    <el-button @click="info.isShow=!info.isShow" icon="el-icon-circle-plus-outline" type="primary">新增</el-button>
    <el-divider />
    <!-- 通过自定义属性, 向子组件传递数据 -->
    <!-- 列表组件 -->
    <List  @updateList="updateList" @updatePage="updatePage" :page="page" :size="size" :adminList="adminList" :adminTotal="adminTotal" />
    <!-- 表单组件 -->
    <Modal @updateList="updateList" :info="info"/>
  </el-card>
</template>

<script>
// 导入vuex的辅助方法
import { mapState, mapActions } from "vuex";
// 导入列表组件
import List from "./List";
import Modal from "./Modal";

export default {
  data() {
    return {
      info: {
        // 控制对话框组件的显示状态
        isShow: false
      },
      // 页码
      page: 1,
      // 每页显示的数据条数
      size: 2
    };
  },
  computed: {
    ...mapState({
      adminList: state => state.admin.adminList,
      adminTotal: state => state.admin.adminTotal
    })
  },
  methods: {
    ...mapActions("admin", ["getAdminListAction", "getAdminTotalAction"]),
    // 自定义事件updatePage处理函数
    updatePage(page) {
      // 1-更新页码
      this.page = page;
      // 2-重新请求数据列表
      this.getAdminListAction({ page: this.page, size: this.size });
    },
    // 自定义事件updateList的处理方法
    updateList(){
        // 更新数据列表
        this.getAdminListAction({page:this.page,size:this.size});
        // 更新数据总条数
        this.getAdminTotalAction();
    }
  },
  components: { List, Modal },
  created() {
    this.getAdminListAction({ page: this.page, size: this.size });
    this.getAdminTotalAction();
  }
};
</script>

pages/admin/Modal.vue

<template>
  <el-dialog @close="reset" :title="formData.id>0?'编辑':'新增'" :visible.sync="info.isShow">
    <el-form ref="formRef" label-width="80px" :model="formData" :rules="rules">
      <el-form-item label="角色" prop="roleid">
        <el-select v-model="formData.roleid">
          <el-option
            v-for="item in roleList"
            :key="item.id"
            :label="item.rolename"
            :value="item.id"
          ></el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="账号" prop="username">
        <el-input placeholder="账号" v-model="formData.username" disabled></el-input>
      </el-form-item>
      <el-form-item label="密码" prop="password">
        <el-input placeholder="密码" v-model="formData.password" type="password"></el-input>
      </el-form-item>
      <el-form-item label="状态" prop="status">
        <el-radio-group v-model="formData.status">
          <el-radio :label="1">正常</el-radio>
          <el-radio :label="2">禁用</el-radio>
        </el-radio-group>
      </el-form-item>
    </el-form>
    <div slot="footer" class="dialog-footer">
      <el-button>取 消</el-button>
      <el-button type="primary" @click="submit">确 定</el-button>
    </div>
  </el-dialog>
</template>

<script>
// 导入事件中心
import vm from '../../utils/vm';
// 导入辅助方法
import { mapState, mapActions } from "vuex";
export default {
  computed: {
    ...mapState({
      roleList: state => state.role.roleList
    })
  },
  props: ["info"],
  data() {
    return {
      // 表单数据模型
      formData: {
        // 角色id
        roleid: '',
        //  账号
        username: "",
        // 密码
        password: "",
        // 状态
        status: ""
      },
      // 表单校验规则对象
      rules: {
        roleid: { required: true, message: "请选择角色", trigger: "blur" },
        username: { required: true, message: "请输入账号", trigger: "blur" },
        // password: { required: true, message: "请输入密码", trigger: "blur" },
        status: { required: true, message: "请选择状态", trigger: "blur" }
      }
    };
  },
  methods: {
    ...mapActions("role", ["getRoleListAction"]),
    submit(){
        this.$refs.formRef.validate(valid=>{
            if(valid){
                const url=this.formData.id>0?'/useredit':'/useradd';
                // 发请求
                this.$http.post(url,this.formData).then(res=>{
                    if(res.code===200){
                        this.$success(res.msg);
                        // 更新数据列表: 通知父组件更新数据列表
                        this.$emit('updateList');
                        // 重置信息
                        this.reset();
                    }else{
                        this.$error(res.msg);
                    }
                    
                })
            }
        });
    },
    // 数据重置
    reset(){
        // 重置表单状态
        this.$refs.formRef.resetFields();
        // 隐藏对话框组件
        this.info.isShow=false;
    }
  },
  created() {
    this.getRoleListAction();
    // 监听自定义事件sendData
    vm.$on('sendData',(obj)=>{
      obj.password='';
      // 更新表单数据模型
      this.formData=obj;
      // 显示对话框组件
      this.info.isShow=true;
    });
  }
};
</script>

2-文件上传

2.1-FormData对象的使用

  • FormData是前端和后端进行数据交互的一种数据格式
  • FormData是以一种类似于二进制数据流的方式, 进行数据包装
  • 一般在实现文件上传的时候, 需要使用FormData数据格式
2.1.1-使用步骤
  1. 创建实例对象

    const fd=new FormData();
    
  2. 追加数据

    fd.append(key,value);
    
  3. 获取数据

    fd.get(key);
    
  4. 删除数据

    fd.delete(key);
    

3-分类管理

3.0-数据层封装

/request/cate.js

// 数据请方法
// 导入axios
import axios from '../utils/http';
// 获取分类列表的树形结构
export async function getCateList(){
    const res=await axios.get('/catelist',{
        params:{
            istree:1
        }
    });
    if(res.code===200){
        return res.list;
    }
    return false;
}

/store/modules/cate.js

// 导入数据请求方法
import { getCateList } from '../../request/cate';
export default {
    // 开启独立命名空间
    namespaced:true,
    state(){
        return {
            // 分类列表
            cateList:[]
        }
    },
    mutations:{
        // 初始化cateList数据
        cateListInit(state,list){
            state.cateList=list;
        }
    },
    actions:{
        // 获取分类列表
        getCateListAction({commit}){
            getCateList().then(list=>{
                if(list){
                    // 通过commit方法调用cateListInit
                    commit('cateListInit',list);
                }
            });
        }
    }
}

3.1-列表展示

/pages/cate/Index.vue

<template>
  <el-card>
      <el-button @click="info.isShow=!info.isShow" type="primary" icon="el-icon-circle-plus-outline">新增</el-button>
      <el-divider/>
      <!-- 调用子组件List -->
      <List :cateList="cateList"  @updateList="updateList"/>
      <!-- 调用子组件Modal -->
      <Modal :info="info" @updateList="updateList"/>
  </el-card>
</template>

<script>
// 导入子组件List
import List from './List';
import Modal from './Modal';

// 导入辅助方法
import { mapState,mapActions } from 'vuex';
export default {
  data(){
    return {
      info:{
        isShow:false
      }
    }
  },
  computed:{
    ...mapState({
      // state: 系统自动注入, 数据存储对象
      cateList:function(state){
        return state.cate.cateList;
      }
    })
  },
  components:{List,Modal},
  methods:{
    ...mapActions('cate',['getCateListAction']),
    // 自定义事件updateList的处理函数
    updateList(){
      this.getCateListAction();
    }
  },
  created(){
    // 请求数据列表
    this.getCateListAction();
  }
}
</script>

pages/cate/List.vue

<template>
  <el-table
    :data="cateList"
    style="width: 100%;margin-bottom: 20px;"
    row-key="id"
    :tree-props="{children: 'children', hasChildren: 'hasChildren'}"
  >
    <el-table-column prop="id" label="id" min-width="80"></el-table-column>
    <el-table-column prop="img" label="分类图片" min-width="180">
        <template v-slot="props">
            <img v-if="props.row.img!==''" style="height:80px" :src="$imgBaseUrl+props.row.img" alt="">
        </template>
    </el-table-column>
    <el-table-column prop="catename" label="分类名称" min-width="180"></el-table-column>
    <el-table-column prop="status" label="状态" min-width="180">
        <template v-slot="props">
            <el-tag type='success' v-if="props.row.status===1">正常</el-tag>
            <el-tag type='danger' v-else>禁用</el-tag>
        </template>
    </el-table-column>
    <el-table-column label="操作" min-width="180">
        <template v-slot="props">
            <el-button  @click="edit(props.row)" size="mini" circle  type="success" icon="el-icon-edit"></el-button>
            <el-button @click="del(props.row.id)" size="mini" circle  type="danger" icon="el-icon-delete"></el-button>
        </template>
    </el-table-column>

  </el-table>
</template>

<script>
// 导入事件中心
import vm from '../../utils/vm';
export default {
  props: ["cateList"],
  data() {
    return {};
  },
  methods:{
    // 编辑
    edit(row){
      // 1-通过自定义事件将数据对象传递给兄弟组件Modal
      // 2-显示Modal组件
      vm.$emit('sendData',{...row});
    },
    // 删除
    del(id){
      this.$myConfirm(()=>{
        // 发请求, 删除数据
        this.$http.post('/catedelete',{id}).then(res=>{
          if(res.code===200){
            this.$success(res.msg);
            // 更新数据列表
            this.$emit('updateList');
          }else{
            this.$error(res.msg);
          }
        })
      });
    }
  }
};
</script>

3.2-分类添加&编辑

/pages/cate/Modal.vue

<template>
  <el-dialog @close="reset" title="新增" :visible.sync="info.isShow">
    <el-form ref="formRef" :model="formData" :rules="rules" label-width="80px">
      <el-form-item label="上级" prop="pid">
        <el-select v-model="formData.pid">
          <el-option :value="0" label="顶级分类"></el-option>
          <el-option
            v-for="item in cateList"
            :key="item.id"
            :value="item.id"
            :label="item.catename"
          ></el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="名称" prop="catename">
        <el-input placeholder="名称" v-model="formData.catename"></el-input>
      </el-form-item>
      <el-form-item label="图片" prop="img" v-if="formData.pid!==0">
        <!-- 
             action: 指定图片上传的数据接口 
             auto-upload: 是否自动上传图片, 默认自动上传
             on-preview: 图片预览事件
             on-change: 当用户选择文件的时候, 自动触发
             limit: 最大允许上传个数
             on-exceed:文件超出个数限制时的钩子
             file-list: 设置默认需要展示的图片列表, 需要一个数组[{name: 'food.jpg', url: 'https://xxx.cdn.com/xxx.jpg'}]
        -->
        <el-upload
          action="#"
          list-type="picture-card"
          :on-preview="handlePictureCardPreview"
          :auto-upload="false"
          :on-change="fileChange"
          :limit="1"
          :on-exceed="limitTips"
          :file-list="fileList"
        >
          <i class="el-icon-plus"></i>
        </el-upload>
        <el-dialog :visible.sync="dialogVisible">
          <img width="100%" :src="dialogImageUrl" alt />
        </el-dialog>
      </el-form-item>
      <el-form-item label="状态" prop="status">
        <el-radio-group v-model="formData.status">
          <el-radio :label="1">正常</el-radio>
          <el-radio :label="2">禁用</el-radio>
        </el-radio-group>
      </el-form-item>
    </el-form>
    <div slot="footer" class="dialog-footer">
      <el-button @click="reset">取 消</el-button>
      <el-button type="primary" @click="submit">确 定</el-button>
    </div>
  </el-dialog>
</template>

<script>
// 导入事件中心
import vm from "../../utils/vm";
import { mapState } from "vuex";
export default {
  created() {
    // 监听自定义事件
    vm.$on("sendData", row => {
      // 1-显示对话框组件
      this.info.isShow = true;
      // 2-更新数据formData
      this.formData = row;
      // 更新fileList
      this.fileList = [{ url: this.$imgBaseUrl + row.img }];
    });
  },
  computed: {
    ...mapState({ cateList: state => state.cate.cateList })
  },
  props: ["info"],
  data() {
    return {
      // 上传组件所需属性
      dialogImageUrl: "",
      dialogVisible: false,
      // upload组件默认需要展示的图片列表
      fileList: [],
      //   和表单进行绑定的数据对象
      formData: {
        pid: 0,
        catename: "",
        img: "",
        status: ""
      },
      // 表单校验规则对象
      rules: {
        pid: { required: true, message: "请选择上级", trigger: "blur" },
        catename: {
          required: true,
          message: "请输入分类名称",
          trigger: "blur"
        },
        status: { required: true, message: "请选择状态", trigger: "blur" }
      }
    };
  },
  methods: {
    // 上传组件相关方法
    handlePictureCardPreview(file) {
      this.dialogImageUrl = file.url;
      this.dialogVisible = true;
    },
    // 监听用户选择文件
    // file: 系统自动注入, 表示用户选择的文件对象
    fileChange(file) {
      // 手动更新数据
      this.formData.img = file.raw;
    },
    // 图片数量超过上限的提示
    limitTips() {
      this.$error("最多只能上传一张");
    },
    // 提交方法
    submit() {
      this.$refs.formRef.validate(valid => {
        if (valid) {
          // 将this.formData数据对象, 转换成FormData对象
          // 创建FormData实例对象
          const fd = new FormData();
          // 删除多余的数据: delete删除对象的属性
          delete this.formData.children;
          for (let key in this.formData) {
            fd.append(key, this.formData[key]);
          }
          const url = this.formData.id > 0 ? "/cateedit" : "/cateadd";
          this.$http.post(url, fd).then(res => {
            if (res.code === 200) {
              this.$success(res.msg);
              // 更新数据列表: 通知父组件更新数据列表
              this.$emit("updateList");
              // 重置数据
              this.reset();
            } else {
              this.$error(res.msg);
            }
          });
        }
      });
    },
    // 重置数据
    reset() {
      // 重置表单
      this.$refs.formRef.resetFields();
      // 重置数据对象formData
      this.formData = {
        pid: 0,
        catename: "",
        img: "",
        status: ""
      };
      // 关闭对话框组件
      this.info.isShow = false;
    }
  }
};
</script>

3.3-分类删除

pages/cate/List.vue

    <el-table-column label="操作" min-width="180">
        <template v-slot="props">
            <el-button @click="del(props.row.id)" size="mini" circle  type="danger" icon="el-icon-delete"></el-button>
        </template>
    </el-table-column>
export default{
    methods:{
         // 删除
        del(id){
          this.$myConfirm(()=>{
            // 发请求, 删除数据
            this.$http.post('/catedelete',{id}).then(res=>{
              if(res.code===200){
                this.$success(res.msg);
                // 更新数据列表
                this.$emit('updateList');
              }else{
                this.$error(res.msg);
              }
            })
          });
        }
    }
}

4-规格管理

4.0-数据层封装

request/specs.js

// 导入axios
import axios from '../utils/http';
// 获取数据列表
// parmas={page:'页码',size:'每一页的数据条数'}
export async function getSpecsList(params) {
  const res = await axios.get('/specslist', {
    params
  });
  if (res.code === 200) {
    return res.list;
  }
  return false;
}


// 获取商品规格总数
export async function getSpecsTotal() {
  const res = await axios.get('/specscount');
  if (res.code === 200) {
    return res.list[0].total;
  }
  return false;
}

store/modules/specs.js

// 导入数据请求方法
import { getSpecsList,getSpecsTotal } from '../../request/specs';
export default {
    // 启用独立命名空间
    namespaced:true,
    state(){
        return {
            // 规格列表
            specsList:[],
            // 规格总条数
            specsTotal:0,   
        }
    },
    mutations:{
        // 初始化specsList
        specsListInit(state,list){
            state.specsList=list;
        },
        // 初始化specsTotal
        specsTotalInit(state,count){
            state.specsTotal=count;
        }
    },
    actions:{
        // 请求规格列表
        // params={page:'页码',size:'每页数据条数'}
        getSpecsListAction({commit},params){
            getSpecsList(params).then(list=>{
                if(list){
                    // 通过调用commit触发同步方法specsListInit
                    commit('specsListInit',list);
                }
            })
        },
        // 请求规格总数
        getSpecsTotalAction({commit}){
            getSpecsTotal().then(count=>{
                if(count){
                    // 通过调用commit触发同步方法specsListInit
                    commit('specsTotalInit',count);
                }
            })
        },
    }
}

4.1-列表展示

pages/specs/Index.vue

<template>
  <el-card>
      <el-button @click="info.isShow=!info.isShow" type="primary" icon="el-icon-circle-plus-outline">新增</el-button>
      <el-divider/>
      <!-- 调用子组件List -->
      <List @updateList="updateList" @sendData="sendData" :specsList="specsList" :specsTotal="specsTotal" :size="size"/>
      <!-- 调用子组件Modal -->
      <Modal @updateList="updateList" :info="info"/>
  </el-card>
</template>

<script>
// 导入vuex辅助方法
import { mapState,mapActions } from 'vuex';
// 导入子组件List
import List from './List';
import Modal from './Modal';
export default {
  data(){
    return {
      info:{
        // 控制对话框组件的显示状态
        isShow:false
      },
      page:1,   // 页码
      size:3   // 每页显示数据条数
    }
  },
  created(){
    // 请求数据列表
    this.getSpecsListAction({page:this.page,size:this.size});
    this.getSpecsTotalAction();
  },
  computed:{
    ...mapState({
      specsList:state=>state.specs.specsList,
      specsTotal:state=>state.specs.specsTotal
    })
  },
  methods:{
    ...mapActions('specs',['getSpecsListAction','getSpecsTotalAction']),
    // 自定义事件sendData处理方法
    sendData(page){
      // 更新page
      this.page=page;
      // 更新数据列表
      this.getSpecsListAction({page:this.page,size:this.size});
    },
    // 自定义事件updateList的处理函数
    updateList(){
      this.getSpecsListAction({page:this.page,size:this.size});
      this.getSpecsTotalAction();
    }
  },
  components:{
    List,
    Modal
  }
}
</script>

<style>

</style>

pages/specs/List.vue

<template>
  <div>
    <el-table :data="specsList" style="width: 100%">
      <el-table-column prop="id" label="id" min-width="80"></el-table-column>
      <el-table-column prop="specsname" label="规格名称" min-width="180"></el-table-column>
      <el-table-column prop="attrs" min-width="180" label="规格可选值">
        <template v-slot="props">
          <el-tag type="success" v-for="(item,index) in props.row.attrs" :key="index">{{item}}</el-tag>
        </template>
      </el-table-column>
      <el-table-column prop="status" min-width="180" label="状态">
        <template v-slot="props">
          <el-tag type="success" v-if="props.row.status===1">正常</el-tag>
          <el-tag type="danger" v-else>禁用</el-tag>
        </template>
      </el-table-column>
      <el-table-column min-width="180" label="操作">
        <template v-slot="props">
          <el-button @click="edit(props.row)" type="success" size="mini" circle icon="el-icon-edit"></el-button>
          <el-button @click="del(props.row.id)" type="danger" size="mini" circle icon="el-icon-delete"></el-button>
        </template>
      </el-table-column>
    </el-table>
    <el-pagination @current-change="pageChange" :page-size="size" background layout="prev, pager, next" :total="specsTotal"></el-pagination>
  </div>
</template>

<script>
// 导入事件中心
import vm from '../../utils/vm';
export default {
  props: ["specsList",'specsTotal','size'],
  methods:{
    // 监听分页按钮的点击, page为页码
    pageChange(page){
      // 通过this.$emit()将page传递给父组件Index
      this.$emit('sendData',page);
    },
    // 编辑
    edit(row){
      // 1-将待编辑的数据传递给兄弟组件Modal
      vm.$emit('sendData',{...row});
    },
    del(id){
      this.$myConfirm(()=>{
        this.$http.post('/specsdelete',{id}).then(res=>{
          if(res.code===200){
            this.$success(res.msg);
            // 更新数据列表
            this.$emit('updateList');
          }else{
            this.$error(res.msg);
          }
        })
      });
    }
  }
};
</script>

<style scoped>
.el-tag {
  margin: 0 5px;
}
</style>

4.2-规格添加&编辑

pages/specs/Modal.vue

<template>
  <el-dialog @close="reset" title="新增" :visible.sync="info.isShow">
  <el-form ref="formRef" :model="formData" :rules="rules" label-width="100px">
      <el-form-item label="规格名称" prop="specsname">
          <el-input v-model="formData.specsname" placeholder="规格名称"></el-input>
      </el-form-item>
       <el-form-item label="规格可选值" prop="attrs">
          <div class="item" v-for="(item,index) in attrs" :key="index">
              <el-input v-model.trim="attrs[index]" placeholder="规格可选值"></el-input>
              <el-button v-if="index===0" @click="addAttr" type="success" size="mini">新增</el-button>
              <el-button v-else @click="delAttr(index)" type="danger" size="mini">删除</el-button>   
          </div>
      </el-form-item>
      <el-form-item label="状态" prop="status">
          <el-radio-group v-model="formData.status">
              <el-radio :label="1">正常</el-radio>
              <el-radio :label="2">禁用</el-radio>
          </el-radio-group>
      </el-form-item>
  </el-form>
  <div slot="footer" class="dialog-footer">
    <el-button @click="reset">取 消</el-button>
    <el-button type="primary" @click="submit">确 定</el-button>
  </div>
</el-dialog>
</template>

<script>
// 导入事件中心
import vm from '../../utils/vm';
export default {
    created(){
        // 监听自定义事件sendData
        vm.$on('sendData',(obj)=>{
            // 1-更新this.formData
            this.formData=obj;
            this.attrs=obj.attrs;
            // 2-显示对话框组件
            this.info.isShow=true;
        });
    },
    props:['info'],
    data(){
        // 自定义表单校验方法
        const validAttrs=(rule,value,callback)=>{
            // 假设表单元素都输入了内容
            var flag=true;
            this.attrs.forEach(item=>{
                if(item===''){
                    flag=false;
                }
            });
            if(!flag){
               return callback(new Error('请输入规格属性可选值')); 
            }
            // 表示表单校验通过
            callback();
        }
        return {
            // 规格可选值
            attrs:[''],
            // 表单数据模型
            formData:{
                // 规格名称
                specsname:'',
                // 规格可选值
                attrs:'',
                // 状态
                status:''    
            },
            // 表单校验规则
            rules:{
                specsname:{required:true,message:'请输入规格名称',trigger:'blur'},
                status:{required:true,message:'请选择状态',trigger:'blur'},
                attrs:{validator:validAttrs,trigger:'blur'}
            }
        }
    },
    methods:{
        submit(){
            this.$refs.formRef.validate(valid=>{
                if(valid){
                    // 提交表单数据
                    // 转换规格属性的数据类型
                    this.formData.attrs=this.attrs.join(',');   
                    const url=this.formData.id>0?'/specsedit':'/specsadd';
                    this.$http.post(url,this.formData).then(res=>{
                        if(res.code===200){
                            this.$success(res.msg);
                            // 更新数据列表
                            this.$emit('updateList');
                            // 数据重置
                            this.reset();
                        }else{
                            this.$error(res.msg);
                        }
                    }) 
                }
            })
        },
        // 重置方法
        reset(){
            // 重置数据
            this.formData={specsname:'',status:'',attrs:''};
            this.attrs=[''];
            // 重置表单状态
            this.$refs.formRef.resetFields();
            // 关闭对话框组件
            this.info.isShow=false;

        },
        // 新增属性可选值
        addAttr(){
            if(this.attrs.length>=5){
                return this.$error('最多只能添加5个属性值');
            }
            this.attrs.push('')
        },
        // 删除属性可选值
        delAttr(index){
            // 根据索引删除数组元素
            this.attrs.splice(index,1);
        }
    }
}
</script>

<style scoped>
.item{
    display: flex;
    margin: 5px 0;
}
.item .el-button{
    margin-left: 10px;
}
</style>

4.3- 规格删除

pages/specs/List.vue

<el-table-column min-width="180" label="操作">
    <el-button @click="del(props.row.id)" type="danger" size="mini" circle icon="el-icon-delete"></el-button>
    </template>
</el-table-column>
export default {
    methods:{
        del(id){
          this.$myConfirm(()=>{
            this.$http.post('/specsdelete',{id}).then(res=>{
              if(res.code===200){
                this.$success(res.msg);
                // 更新数据列表
                this.$emit('updateList');
              }else{
                this.$error(res.msg);
              }
            })
          });
        }
    }
}

5-数据可视化

5.1-echarts数据报表

  • 一个基于HTML5中canvas的图表库
5.1.1-安装
npm i echarts -S
5.1.2-使用
<template>
    <!--图表渲染的容器: 一定要指定高度-->
  <div id="container"></div>
</template>

<script>
// 1-导入echarts
import * as echarts from "echarts";
export default {
  mounted() {
    // 1-获取容器对应的dom对象
    const dom = document.querySelector("#container");
    // 2-初始化
    const instance = echarts.init(dom);
    // 3-设置配置对象
    instance.setOption(this.barOptions);
  },
  data() {
    return {
      // 柱状图需要的配置对象
      barOptions: {
        //   图表标题
        title: {
          text: "柱状图"
        },
        // 鼠标悬浮的提示
        tooltip: {
          trigger: "axis",
          axisPointer: {
            type: "shadow"
          }
        },
        xAxis: {
          type: "category",
          data: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
        },
        yAxis: {
          type: "value"
        },
        series: [
          {
            data: [120, 200, 150, 80, 70, 110, 130],
            type: "bar", // 控制图表形状
            showBackground: true,
            backgroundStyle: {
              color: "rgba(220, 220, 220, 0.8)"
            }
          }
        ]
      }
    };
  }
};
</script>

<style scoped>
#container {
  height: 400px;
}
</style>

5-参考文档

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值