Vue element商品列表的增删改功能实现

目录
  • 介绍
  • 基本信息
  • 上传主图
  • 商品信息vue富文本编辑器的配置
  • 最后提交数据

介绍

整体和用户列表 类似 功能步骤有:

  • 面包屑导航
  • 外部是大的卡片组件
  • 搜索商品 添加商品
  • 表格渲染数据
  • 作用域插槽用于 操作按钮
  • 分页器组件的使用

不一样的点:之前编辑信息 新增信息是 弹出对话框编辑 但商品信息内容较多 我们跳转到一个组件、并且进行商品编辑的时候要进行路由传参 来渲染初始数据

点击添加商品按钮时跳转到新增商品组件对应路径:

addGoods(){
this.$router.push('/goods/add')
}

点击编辑商品按钮时跳转到编辑商品组件对应路径 并且传入id

ToEditGoods(id){
this.$router.push(`/goods/edit/${id}`)
}

新增商品和编辑商品组件布局一致只是新增商品 不用 传参请求数据

我们以编辑商品为例

在设置路由对应关系的时候 预留占位符

{
  path:'/goods',
  component:GoodsList
},
{
  path:'/goods/add',
  component:GoodsAdd
},
{
  path:'/goods/edit/:id',
  component:GoodsEdit
}

第一步 先使用组件进行页面布局:

主要使用到了 el-steps 步骤条组件 和 el-tabs 标签页组件的联动 使他们步长一致 使用共同的

active 步骤条的active 动态绑定 到 activeIndex上

当标签页发生切换时 根据name 赋值给 activeIndex

async handleClick(){
   this.activeIndex = this.activeName * 1
   // 选择了商品(动态)参数选项
 },

这样 两个组件就可以联动展示了

标签页组件其实是包裹在 el-form 当中方便统一提交给服务器

接下来就是表单内部 组件渲染 表单验证了

基本信息

组件渲染el-input 数据绑定 v-model 类型限制 tpye=‘number’ prop合法值验证

这里需要自定义验证的是 商品价格不能小于0 商品数量必须是整数

必填就可以直接使用自带的

基本信息中还有一个要点:分类选择

          <el-form-item label="选择商品分类">
el-cascader 级联选择器
            <el-cascader
默认选定的值是根据id请求过来的分类数组
              v-model="AddGoodsForm.goods_cat"
              style="width: 400px"
数据来源:cateLists 一进入页面请求过来的
              :options="cateLists"
有清空按钮
              clearable
禁用 编辑页面 不让修改分类
              disabled
级联选择器的相关规则
              :props="CSet"
选择发生改变时 执行的回调
              @change="handleChange"></el-cascader>
          </el-form-item>
<script>
数据来源:
      async getAllCate(){
        const {data:res} = await this.$http.get('categories')
        if (res.meta.status !==200) return this.$Msg.error('获取商品分类列表失败!')
        this.cateLists = res.data
      }
级联选择器的规则
        CSet:{
展示下一级触发方式 鼠标悬浮
          expandTrigger: 'hover',
指定选项的子选项为选项对象的某个属性值
          children:'children',
显示的文本
          label:'cat_name',
文本对应的value
          value:'cat_id',
        }
选择发生改变时 执行的回调  只让选择第三级  不是的话就清空 选择不进去
      handleChange(){
        if (this.AddGoodsForm.goods_cat.length !== 3){
          this.AddGoodsForm.goods_cat = []
        }
        console.log(this.AddGoodsForm.goods_cat)
      }
<script>

如果是新增商品页面的话 也大体一致 把 disabled 去掉即可

并且在切换标签页时可以验证AddGoodsForm.goods_cat 的长度

      leaveTabs(activeName, oldActiveName){
        if(oldActiveName === '0' && this.AddGoodsForm.goods_cat.length !== 3){
          this.$Msg.error('请先选择商品分类!')
          return false
        }

根据服务器返回的数据

渲染商品参数-attr.many 和商品属性-attr.only

分别渲染 多选框组和输入框组来v-for 循环

上传主图

        <el-tab-pane label="4.商品图片" name="3">
          <el-upload
            class="upload-demo"
            :action="actionToUrl"
            :on-preview="handlePreview2"
            :on-remove="handleRemove"
            :on-success="handleSuccess"
            :headers="UploadHeaders"
            list-type="picture-card">
            <el-button size="small" type="primary">点击上传</el-button>
            <div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div>
          </el-upload>
        </el-tab-pane>
    <el-dialog
      title="预览图片"
      :visible.sync="Preview"
      width="45%">
      <img :src="PreviewPic" alt="" style="width: 100%">
      <span slot="footer" class="dialog-footer">
    <el-button type="primary" @click="Preview = false">确 定</el-button>
  </span>
    </el-dialog>
<script>
action	必选参数,上传的地址 这里用的是本地服务器
actionToUrl:'http://127.0.0.1:8888/api/private/v1/upload'
on-preview 点击文件列表中已上传的文件时的钩子 点击出现对话框显示放大预览图
      handlePreview2(file){
        this.PreviewPic=file.response.data.url // 显示图片的地址
        this.Preview = true // 决定对话框显示的布尔值
      }
on-remove 文件列表移除文件时的钩子
      handleRemove(file){
      //1.获取将要删除的图片临时路径
        const fileUrl = file.response.data.tmp_path
      //2.从pics 数组中,找到这个图片对应的索引值
        let aaa = this.AddGoodsForm.pics.findIndex(value => value === fileUrl)
        console.log(aaa)
      //3.调用数组 splice 方法 把图片信息对象从pics 数组中移除
        this.AddGoodsForm.pics.splice(aaa,1)
        console.log(this.AddGoodsForm.pics)
      }
on-success 文件上传成功时的钩子
      async handleSuccess(response){
       // 找出定义一下 新上传文件的路径地址
       const NewPicUrl = response.data.tmp_path
       // push 到预留表单位中
        this.AddGoodsForm.pics.push(NewPicUrl)
        console.log(this.AddGoodsForm.pics)
        // const {data:res} = await this.$http.put(`goods/${this.NowEditId}/pics`,this.AddGoodsForm.pics)
        // if (res.meta.status !==200) return this.$Msg.error('更新主图失败!')
        // this.$Msg.success('更新主图成功!')
      }
headers 设置上传的请求头部
        UploadHeaders:{
          Authorization:window.sessionStorage.getItem('token')
        },
</script>

商品信息vue富文本编辑器的配置

先执行安装语句:

在main.js 中注册 并引入样式

npm install vue-quill-editor
import VueQuillEditor from 'vue-quill-editor'
import 'quill/dist/quill.core.css' // import styles
import 'quill/dist/quill.snow.css' // for snow theme
import 'quill/dist/quill.bubble.css' // for bubble theme
Vue.use(VueQuillEditor, /* { default global options } */)

在组件中使用

        <el-tab-pane label="5.商品内容" name="4">
          <quill-editor
            ref="myQuillEditor"
数据双向绑定 便于发送请求
            v-model="AddGoodsForm.goods_introduce"
富文本编辑器的核心配置
            :options="editorOption"
          />
        </el-tab-pane>
<script>
// 此处定义在data外
  const toolbarOptions = [
    ['insertMetric'],
    ['bold', 'italic', 'underline', 'strike'],        // 加粗,斜体,下划线,删除线
    ['blockquote', 'code-block'],                     //引用,代码块
    [{ 'header': 1 }, { 'header': 2 }],               // 几级标题
    [{ 'list': 'ordered' }, { 'list': 'bullet' }],    // 有序列表,无序列表
    [{ 'script': 'sub' }, { 'script': 'super' }],     // 下角标,上角标
    [{ 'indent': '-1' }, { 'indent': '+1' }],         // 缩进
    [{ 'direction': 'rtl' }],                         // 文字输入方向
    [{ 'size': ['small', false, 'large', 'huge'] }],  // 字体大小
    [{ 'header': [1, 2, 3, 4, 5, 6, false] }],        // 标题
    [{ 'color': [] }, { 'background': [] }],          // 颜色选择
    [{ 'font': ['SimSun', 'SimHei', 'Microsoft-YaHei', 'KaiTi', 'FangSong', 'Arial'] }], // 字体
    [{ 'align': [] }],    // 居中
    ['clean'],            // 清除样式,
    ['link', 'image']   // 上传图片、上传视频
  ]
  // toolbar标题
  const titleConfig = [
    { Choice: '.ql-insertMetric', title: '跳转配置' },
    { Choice: '.ql-bold', title: '加粗' },
    { Choice: '.ql-italic', title: '斜体' },
    { Choice: '.ql-underline', title: '下划线' },
    { Choice: '.ql-header', title: '段落格式' },
    { Choice: '.ql-strike', title: '删除线' },
    { Choice: '.ql-blockquote', title: '块引用' },
    { Choice: '.ql-code', title: '插入代码' },
    { Choice: '.ql-code-block', title: '插入代码段' },
    { Choice: '.ql-font', title: '字体' },
    { Choice: '.ql-size', title: '字体大小' },
    { Choice: '.ql-list[value="ordered"]', title: '编号列表' },
    { Choice: '.ql-list[value="bullet"]', title: '项目列表' },
    { Choice: '.ql-direction', title: '文本方向' },
    { Choice: '.ql-header[value="1"]', title: 'h1' },
    { Choice: '.ql-header[value="2"]', title: 'h2' },
    { Choice: '.ql-align', title: '对齐方式' },
    { Choice: '.ql-color', title: '字体颜色' },
    { Choice: '.ql-background', title: '背景颜色' },
    { Choice: '.ql-image', title: '图像' },
    { Choice: '.ql-video', title: '视频' },
    { Choice: '.ql-link', title: '添加链接' },
    { Choice: '.ql-formula', title: '插入公式' },
    { Choice: '.ql-clean', title: '清除字体格式' },
    { Choice: '.ql-script[value="sub"]', title: '下标' },
    { Choice: '.ql-script[value="super"]', title: '上标' },
    { Choice: '.ql-indent[value="-1"]', title: '向左缩进' },
    { Choice: '.ql-indent[value="+1"]', title: '向右缩进' },
    { Choice: '.ql-header .ql-picker-label', title: '标题大小' },
    { Choice: '.ql-header .ql-picker-item[data-value="1"]', title: '标题一' },
    { Choice: '.ql-header .ql-picker-item[data-value="2"]', title: '标题二' },
    { Choice: '.ql-header .ql-picker-item[data-value="3"]', title: '标题三' },
    { Choice: '.ql-header .ql-picker-item[data-value="4"]', title: '标题四' },
    { Choice: '.ql-header .ql-picker-item[data-value="5"]', title: '标题五' },
    { Choice: '.ql-header .ql-picker-item[data-value="6"]', title: '标题六' },
    { Choice: '.ql-header .ql-picker-item:last-child', title: '标准' },
    { Choice: '.ql-size .ql-picker-item[data-value="small"]', title: '小号' },
    { Choice: '.ql-size .ql-picker-item[data-value="large"]', title: '大号' },
    { Choice: '.ql-size .ql-picker-item[data-value="huge"]', title: '超大号' },
    { Choice: '.ql-size .ql-picker-item:nth-child(2)', title: '标准' },
    { Choice: '.ql-align .ql-picker-item:first-child', title: '居左对齐' },
    { Choice: '.ql-align .ql-picker-item[data-value="center"]', title: '居中对齐' },
    { Choice: '.ql-align .ql-picker-item[data-value="right"]', title: '居右对齐' },
    { Choice: '.ql-align .ql-picker-item[data-value="justify"]', title: '两端对齐' }
  ]
// 此处书写在data当中
        editorOption: {
          placeholder: '请在这里输入......',
          theme: 'snow', //主题 snow/bubble
          modules: {
            history: {
              delay: 1000,
              maxStack: 50,
              userOnly: false
            },
            toolbar: {
              container: toolbarOptions,
              handlers: {
                insertMetric: this.showHandle
              }
            }
          }
        }
// 此处书写在 methods 中
 // 配置富文本编辑器
      initTitle () {
        document.getElementsByClassName('ql-editor')[0].dataset.placeholder = ''
        for (let item of titleConfig) {
          let tip = document.querySelector('.quill-editor ' + item.Choice)
          if (!tip) continue
          tip.setAttribute('title', item.title)
        }
      },
      showHandle () {
        this.$Msg.error('这是自定义工具栏的方法!')
      },
      // 自定义按钮内容初始化
      initButton () {
        const editorButton = document.querySelector('.ql-insertMetric')
        editorButton.innerHTML = '<i class="el-icon-link" style="font-size: 18px;color:black"></i>'
      },
      // 失去焦点
      onEditorBlur (editor) { },
      // 获得焦点
      onEditorFocus (editor) { },
      // 开始
      onEditorReady (editor) { },
      // 值发生变化
      onEditorChange (editor) {
        // 如果需要手动控制数据同步,父组件需要显式地处理changed事件
        // this.content = editor.html;
        console.log(editor);
      },
</script>

最后提交数据

        <el-tab-pane label="6.提交商品" name="5">
          <el-empty image="http://www.wsg3096.com/gangback/pub/asdc1.png" :image-size="320" description="确定所有数据添加完毕后就可以提交啦!">
            <el-button type="primary" icon="el-icon-success" @click="ToGoods">上传商品</el-button>
          </el-empty>
        </el-tab-pane>
<script>
      // 确定上传的按钮
      async ToGoods(){
        this.$refs.AddGoodsFormRef.validate(async valid =>{
          if (!valid)  return this.$Msg.error('请检查下各项数据是否规范!')
          // 执行添加业务的逻辑 先深拷贝一下 防止改变 级联选择器
          const form = _.cloneDeep(this.AddGoodsForm)
          // 处理当前商品所属ID 服务器要求 ,分割的字符串
          form.goods_cat = form.goods_cat.join(',')
          // 请求过来的数据保存到ManyData OnlyData 展示 返回去的时候 还用服务器的数据就行
          form.attrs = [...this.ManyData,...this.OnlyData]
         // console.log(form)
          const {data : res} = await this.$http.put(`goods/${this.NowEditId}`,form)
          if (res.meta.status !== 200) return this.$Msg.error('编辑商品失败!')
          this.$Msg.success('编辑商品成功!')
          await this.$router.push('/goods')
        })
      }
</script>

到此这篇关于Vue element商品列表的增删改功能实现的文章就介绍到这了,更多相关Vue element商品列表内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Vue组件库ElementUI实现表格列表分页效果

    ElementUI实现表格列表分页效果教程,供大家参考,具体内容如下 Element UI 是一套采用 Vue 2.0 作为基础框架实现的组件库,一套为开发者.设计师和产品经理准备的基于 Vue 2.0 的组件库,提供了配套设计资源,帮助网站快速成型 <el-pagination>加上@size-change="handleSizeChange.@current-change="handleCurrentChange"处理当前页和当前页数的改变事件 <!--

  • 利用vue+elementUI设置省市县三级联动下拉列表框的详细过程

    目录 前言 实现过程 总结 前言 在前端项目开发中,经常会遇到省市县三级联动的下拉列表框组的问题,分享以下实现方法,以下内容为具体的实现过程: 实现过程 1.静态页面组件搭建:使用elementUI的form表单,并做一下基本的修改,得到以下结果: 2.然后是组件的数据配置: 表单的基本数据存放在form对象里面,至于省市县三个下拉菜单的数据,则以数组的形式存放,分别为provinceList[];cityList[];countyListp[]. 3.接下来处理重点数据:三级下拉菜单的联动:

  • Vue Element前端应用开发之表格列表展示

    1.列表查询界面效果 在介绍任何代码处理逻辑之前,我们先来做一个感官的认识,贴上一个效果图,在逐一介绍其中处理的步骤和注意事项. 常规的列表展示界面,一般分为几个区域,一个是查询区域,一个是列表展示区域,一个是底部的分页组件区域.查询区域主要针对常规条件进行布局,以及增加一些全局或者批量的操作,如导入.导出.添加.批量添加.批量删除等按钮:而其中主体的列表展示区域,是相对比较复杂一点的地方,需要对各项数据进行比较友好的展示,可以结合Tag,图标,按钮等界面元素来展示,其中列表一般后面会包括一些对

  • Vue Element UI自定义描述列表组件

    本文实例为大家分享了Vue Element UI自定义描述列表组件的具体代码,供大家参考,具体内容如下 效果图 写在前面 写后台管理经常从列表点击查看详情,展示数据信息,Element UI虽然有表格组件,但是描述组件并没有,之前团队的成员遇到这种情况都自己去写样式,写起来也麻烦,而且每个人写出来的样式也不统一,破坏了项目的整体风格. 像是Ant Design UI就有描述组件,用起来特别舒服,所以索性自己结合Element UI的el-row和el-col自己写了一个. 实现哪些功能 1.每行

  • Vue中使用elementui与Sortable.js实现列表拖动排序

    本文实例为大家分享了使用elementui与Sortable.js实现列表拖动排序的具体代码,供大家参考,具体内容如下 一.安装使用Sortable.js 1.安装 cnpm install sortablejs --save 2.在需要的vue页面单独引入 <script>     import Sortable from 'sortablejs'     export default{         .........         data() {             retur

  • Vue+elementUI实现动态展示列表的数据

    目录 Vue elementUI动态展示列表的数据 需求描述 Vue elementUI注意事项 多选框对应List<object> 输入框判断条件 自定义弹窗格式 Vue elementUI动态展示列表的数据 需求描述 活动查看的时候,根据后台返回的数据,动态渲染列和每行数据. 后台返回的数据结构如下 html <!-- 弹出的查看数据 --> <el-dialog width="1200px" :title="activityName&quo

  • Vue Element前端应用开发之树列表组件

    1.常规树列表控件的使用 众所周知,一般界面很多情况涉及到树列表的处理,如类型展示,如果是一层的,可以用下拉列表代替,如果是多个层级的,采用树控件展示会更加直观. 在Element里面也有一个el-tree的控件,如下所示,这里主要对它的各种属性和方法进行介绍. 简单的代码如下所示 <el-tree :data="data" @node-click="handleNodeClick"></el-tree> 主要在script部分里面指定它的d

  • Vue element商品列表的增删改功能实现

    目录 介绍 基本信息 上传主图 商品信息vue富文本编辑器的配置 最后提交数据 介绍 整体和用户列表 类似 功能步骤有: 面包屑导航 外部是大的卡片组件 搜索商品 添加商品 表格渲染数据 作用域插槽用于 操作按钮 分页器组件的使用 不一样的点:之前编辑信息 新增信息是 弹出对话框编辑 但商品信息内容较多 我们跳转到一个组件.并且进行商品编辑的时候要进行路由传参 来渲染初始数据 点击添加商品按钮时跳转到新增商品组件对应路径: addGoods(){ this.$router.push('/good

  • vue实现表单数据的增删改功能

    本文实例为大家分享了vue实现表单数据增删改功能的具体代码,供大家参考,具体内容如下 图示如下: <!DOCTYPE html> <html lang="en">   <head>     <meta charset="UTF-8">     <meta name="viewport" content="width=device-width, initial-scale=1.0&qu

  • VUE饿了么树形控件添加增删改功能的示例代码

    本文介绍了VUE饿了么树形控件添加增删改功能的示例代码,分享给大家,具体如下: element-ui树形控件:地址 在原文档中有个案例是有新增和删除功能,但是后来发现其修改的数据并不能直接影响到树形数据,所以采用了 render-content 的API重新写了个组件. 写个开发的步骤,所以文章比较长emmm 大致效果如图: 1.省市API 在网上复制了个省市的list,有两个属性是新增的 isEdit :控制编辑状态 maxexpandId :为现下id的最大值 export default{

  • vue中使用elementui实现树组件tree右键增删改功能

    功能描述: 1.右击节点可进行增删改 2.可对节点数据进行模糊查询 3.右击第一级节点可以进行同级节点增加 4.双击节点或点击修改节点 都可以对节点获取焦点并进行修改,回车修改成功 5.可对节点进行拖拽,实现节点移动功能 效果图: 完整代码: <template> <div class="lalala tree-container"> <el-input placeholder="输入关键字进行过滤" v-model="fil

  • vue实现节点增删改功能

    本文实例为大家分享了vue实现节点增删改功能的具体代码,供大家参考,具体内容如下 效果: 增删改功能 tree.vue组件代码: <template> <div> <div class="all-div" v-if="model.name"> <div class="itemRow" :style="{ marginLeft:model.level*20+'px' }"> <

  • python列表的增删改查实例代码

    names=["zhao00","qian01","sun02","li03","li03","li03","zhou04"] #print(names[]) 打印错误 print(names) 增 names.append("wu05") #增加到最后 names.insert(1,"zheng06") #增加到指定位置 改

  • vue实现商品列表的添加删除实例讲解

    我们首先来看下代码: <div id="app"> <div class="container"><form class="form-inline"> <div class="form-group"><label for="exampleInputName2">ID:</label> <input id="example

  • vue实现表格数据的增删改查

    在管理员的一些后台页面里,个人中心里的数据列表里,都会有对这些数据进行增删改查的操作.比如在管理员后台的用户列表里,我们可以录入新用户的信息,也可以对既有的用户信息进行修改.在vue中,我们更应该专注于对数据的操作和处理. 比如我们有一个这样的页面: 我们在这个页面里,就实现了增删改查4个功能,点击链接查看demo[http://www.xiabingbao.com/demo/vue-curd/index.html]. 我们把这些用户信息保存到list的数组中,然后增删改查就在这个数组上进行:

  • VUE+element开发后台管理的搜索功能

    本文实例为大家分享了VUE element后台管理搜索功能的具体代码,供大家参考,具体内容如下 先看看样式图: 实现上面这种简单搜索简单的三步走: 1.页面样式:在页面中使用form表单的校验功能来实现输入搜索.给表单的数据放入搜索请求的data数组中,也就是searchParams这个大集合中. 备注:如果给每个输入框添加了搜索按钮的click方法,则会在输入完成后直接执行列表搜索.所以考虑自己使用的具体位置. <div class="search">     <e

  • Vue+Element UI 实现视频上传功能

    一.前言 项目中需要提供一个视频介绍,使用户能够快速.方便的了解如何使用产品以及注意事项. 前台使用Vue+Element UI中的el-upload组件实现视频上传及进度条展示,后台提供视频上传API并返回URL. 二.具体实现 1.效果图展示 2.HTML代码 <div class="album albumvideo"> <div> <p class="type_title"> <span>视频介绍</spa

随机推荐