基于vue+element ui 实现商城 商品详情配置功能 封装组件

  1. 组件背景 :  商城项目 实现配置商品详情列表配置 不能用富文本 列表内只能上传文字描述和图片

  2. 实现 :  基于vue+element ui

  1. <template>
      <div class="phone look_my_phone">
        <div class="phone_shadow">
          <div class="nav">
            <vab-icon class="two" :icon="['fas', 'wifi']"></vab-icon>
            <vab-icon
              class="three"
              :icon="['fas', 'battery-three-quarters']"
            ></vab-icon>
          </div>
          <div class="nav_s">
            <div class="span_title">商品详情页配置</div>
            <div class="left">
              <i class="el-icon-arrow-left"></i>
            </div>
            <div class="right"></div>
          </div>
          <!-- 内容区域 -->
          <div class="phone_conts">
            <div class="my_phones">
              <div class="my_phones_cont_w">
                <div class="conts_w">
                  <div class="conts">
                    <div
                      v-for="(item, index) in myList"
                      :key="index"
                      class="phone_item"
                    >
                      <img v-if="item.type == 'img'" :src="item.conts" alt="" />
                      <p v-else-if="item.type == 'text'">{{ item.conts }}</p>
                      <div class="config_w">
                        <div class="config">
                          <div class="config_item" @click="topGo(index)">上移</div>
                          <div class="config_item" @click="bottomGo(index)">
                            下移
                          </div>
                          <div
                            v-if="item.type == 'text'"
                            class="config_item"
                            @click="editShow(item, index)"
                          >
                            编辑
                          </div>
                          <div class="config_item" @click="delItem(index)">
                            删除
                          </div>
                        </div>
                      </div>
                    </div>
                  </div>
                  <div v-if="show" class="input_add_w">
                    <div>
                      <el-input
                        v-model="inputVlue"
                        type="textarea"
                        resize="none"
                        :rows="3"
                        placeholder="请输入内容..."
                      ></el-input>
                    </div>
                    <div class="btns">
                      <el-button
                        v-if="showType == 'add'"
                        size="mini"
                        type="primary"
                        @click="addSubmit()"
                      >
                        添加
                      </el-button>
                      <el-button
                        v-else-if="showType == 'edit'"
                        size="mini"
                        type="primary"
                        @click="editSubmit()"
                      >
                        修改
                      </el-button>
                      <el-button size="mini" @click="hides()">取消</el-button>
                    </div>
                  </div>
                </div>
              </div>
              <div class="my_phones_btns">
                <div class="edits">
                  <i class="el-icon-plus"></i>
                  <div class="text">编辑</div>
                </div>
                <div class="my_phones_btns_show_w">
                  <div class="my_phones_btns_show">
                    <div class="lefts">
                      <i class="el-icon-picture"></i>
                      <span class="text">图片</span>
                      <input
                        class="files"
                        accept="image/*"
                        type="file"
                        @change="changeFile"
                      />
                    </div>
                    <div class="rights" @click="addShow()">
                      <i class="el-icon-edit"></i>
                      <div class="text">文本</div>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
        <div class="volume"></div>
        <div class="bang">
          <div class="yuan"></div>
        </div>
        <div class="power"></div>
        <div class="power1"></div>
        <div class="receiver">
          <div></div>
        </div>
      </div>
    </template>
    
    <script>
      import axios from 'axios'
      export default {
        name: 'Phones',
        props: {
          lists: {
            type: Array,
            default() {
              return []
            },
          },
        },
        data() {
          return {
            myList: this.lists,
            inputVlue: '',
            show: false,
            showType: '',
            INDEX: 0,
          }
        },
        methods: {
          // 添加文字显示
          addShow() {
            this.showType = 'add'
            this.show = true
          },
          // 添加文字提交
          addSubmit() {
            this.myList.push({
              type: 'text',
              conts: this.inputVlue,
            })
            this.inputVlue = ''
            this.show = false
          },
          // 编辑文字显示
          editShow(row, index) {
            this.INDEX = index
            this.inputVlue = row.conts
            this.showType = 'edit'
            this.show = true
          },
          // 修改文字提交
          editSubmit() {
            this.myList[this.INDEX].conts = this.inputVlue
            this.inputVlue = ''
            this.show = false
          },
          // 上移
          topGo(index) {
            const that = this
            if (index == 0) {
              this.$message.error(`当前已在第一位`)
              return
            }
            this.myList.splice(
              index,
              1,
              ...that.myList.splice(index - 1, 1, that.myList[index])
            )
          },
          // 下移
          bottomGo(index) {
            const that = this
            if (index == this.myList.length - 1) {
              this.$message.error(`当前已在最后一位`)
              return
            }
            this.myList.splice(
              index,
              1,
              ...that.myList.splice(index + 1, 1, that.myList[index])
            )
          },
          // 删除
          delItem(index) {
            this.myList.splice(index, 1)
          },
          // 获取文件信息 e.target.files
          async changeFile(e) {
            let nums = 0
            this.myList.forEach((item) => {
              if (item.type == 'img') {
                nums++
              }
            })
            let file = e.target.files[0]
            if (!file) {
              this.$message.error('请选择图片')
              return
            }
            if (nums >= 20) {
              this.$message.error('最多上传20张图片')
              return
            }
            let formData = new FormData()
            formData.append('file', file)
            formData.append('type', 'image')
            axios
              .post('上传图片地址', formData)
              .then(({ data: res }) => {
                if (res.code != 200000) {
                  this.$message.error(res.message)
                  return
                }
                this.myList.push({
                  type: 'img',
                  conts: res.data[0],
                })
                this.$message.success(res.message)
              })
          },
          // 关闭
          hides() {
            this.inputVlue = ''
            this.show = false
          },
        },
      }
    </script>
    
    <style scoped lang="scss">
      .my_phones {
        width: 100%;
        height: 600px;
        height: 559px;
        .my_phones_cont_w {
          width: 100%;
          height: 500px;
          box-sizing: border-box;
          .conts {
            width: 100%;
            height: 500px;
            box-sizing: border-box;
            overflow-y: scroll;
            position: relative;
            padding-bottom: 140px;
          }
          .conts_w {
            width: 100%;
            height: 500px;
            box-sizing: border-box;
            position: relative;
          }
          .conts::-webkit-scrollbar {
            display: none;
          }
        }
        .my_phones_btns {
          width: 100%;
          height: 60px;
          box-sizing: border-box;
          border-top: 1px solid #dcdfe6;
          background-color: #f5f5f5;
          display: flex;
          align-items: center;
          justify-content: center;
          position: relative;
          cursor: pointer;
          .edits {
            text-align: center;
            font-size: 22px;
            .text {
              font-size: 16px;
            }
          }
          .my_phones_btns_show_w {
            display: none;
            position: absolute;
            left: 0;
            top: 0;
            width: 100%;
            height: 100%;
            .my_phones_btns_show {
              width: 100%;
              height: 100%;
              background-color: #f5f5f5;
              display: flex;
              .lefts {
                flex: 1;
                height: 100%;
                display: flex;
                align-items: center;
                justify-content: center;
                position: relative;
                cursor: pointer;
                transition: all 1s;
                .text {
                  font-size: 16px;
                  margin-left: 10px;
                }
              }
              .lefts:hover {
                background-color: #e6e6e6;
                .text {
                  font-size: 18px;
                  font-weight: 700;
                }
              }
              .rights {
                flex: 1;
                height: 100%;
                display: flex;
                align-items: center;
                justify-content: center;
                cursor: pointer;
                transition: all 1s;
                .text {
                  font-size: 16px;
                  margin-left: 10px;
                }
              }
              .rights:hover {
                background-color: #e6e6e6;
                .text {
                  font-size: 18px;
                  font-weight: 700;
                }
              }
              i {
                font-size: 22px;
              }
              .items {
                display: inline-block;
                text-align: center;
              }
            }
          }
        }
        .phone_item {
          position: relative;
          img {
            width: 100%;
            height: auto;
            vertical-align: bottom;
          }
          p {
            margin: 0;
            line-height: 36px;
            font-size: 16px;
          }
        }
      }
      .my_phones_btns:hover .my_phones_btns_show_w {
        display: block;
      }
      .phone_item:hover .config_w {
        display: block;
      }
      .config_w {
        display: none;
        position: absolute;
        top: 0;
        right: 0;
        .config {
          display: flex;
          .config_item {
            background-color: #f5f5f5;
            padding: 10px 20px;
            cursor: pointer;
          }
          .config_item:hover {
            background-color: #e6e6e6;
          }
        }
      }
      .input_add_w {
        width: 100%;
        padding: 10px;
        box-sizing: border-box;
        position: absolute;
        left: 0;
        bottom: -2px;
        background-color: #f5f5f5;
        border: 1px solid #dcdfe6;
        border-right: none;
        border-left: none;
        .btns {
          display: flex;
          justify-content: flex-end;
          margin-top: 10px;
        }
      }
      .files {
        position: absolute;
        width: 100%;
        height: 100%;
        opacity: 0;
        cursor: pointer;
      }
    </style>
    

 下面是手机样式的css

 .phone {
    position: relative;
    width: 370px;
    height: 650px;
    border: 15px solid #000;
    border-radius: 60px;
    box-sizing: border-box;
  }
  .phone_shadow {
    content: '';
    position: absolute;
    width: 350px;
    height: 634px;
    box-shadow: 0px 0px 24px #fff;
    border-radius: 51px;
    left: -5px;
    top: -7px;
    background: #fff;
    border: 10px solid #000;
    box-sizing: border-box;
    overflow: hidden;
    .nav {
      height: 25px;
      color: #333333;
      font-size: 16px;
      display: flex;
      align-items: center;
      justify-content: flex-end;
      box-sizing: border-box;
      padding-right: 27px;
      .three {
        font-size: 20px;
        margin-left: 8px;
      }
      .two {
        margin-left: 5px;
      }
    }
    .nav_s {
      height: 30px;
      display: flex;
      align-items: center;
      justify-content: space-between;
      position: relative;
      background-color: #f4f4f5;
      box-sizing: border-box;
      padding: 0 10px;
      font-size: 16px;
      .span_title {
        position: absolute;
        font-size: 16px;
        left: 50%;
        top: 50%;
        transform: translate(-50%, -50%);
        color: #000;
      }
      .left {
        color: #000;
        font-size: 20px;
      }
      .right {
        color: #83878d;
        .one {
          margin-right: 5px;
        }
      }
    }
    .phone_conts {
      height: 559px;
      overflow-y: scroll;
      box-sizing: border-box;
      padding: 10px;
      color: #000;
      .titles {
        font-size: 16px;
        font-weight: 700;
        line-height: 30px;
      }
      .data {
        color: #666769;
        border-bottom: 1px dashed #c6c6c6;
        line-height: 26px;
      }
      .html_conts {
        margin-top: 20px;
        color: #666769;
        line-height: 30px;
        word-break: break-all;
      }
    }
  }
  .phone_conts::-webkit-scrollbar {
    display: none;
  }
  .volume {
    width: 9px;
    height: 100px;
    border: #000 1px solid;
    background: linear-gradient(#8c8c8c, #000 9%, #222, #000 94%, #353535 100%);
    position: absolute;
    right: -21px;
    top: 120px;
    z-index: -1;
    border-radius: 20px;
  }

  .power {
    width: 9px;
    height: 46px;
    border: #000 1px solid;
    background: linear-gradient(#8c8c8c, #000 9%, #222, #000 94%, #353535 100%);
    position: absolute;
    left: -21px;
    top: 100px;
    z-index: -1;
    border-radius: 20px;
  }
  .power1 {
    width: 9px;
    height: 46px;
    border: #000 1px solid;
    background: linear-gradient(#8c8c8c, #000 9%, #222, #000 94%, #353535 100%);
    position: absolute;
    left: -21px;
    top: 160px;
    z-index: -1;
    border-radius: 20px;
  }
  .receiver {
    position: absolute;
    top: 4px;
    left: 50%;
    transform: translateX(-50%);
    background: #000000;
    border: #484848 1px solid;
    width: 50px;
    height: 8px;
    z-index: 9;
    border-radius: 20px;
  }

  .receiver ul {
    list-style: none;
    display: flex;
    flex-wrap: wrap;
    margin: 1px;
    justify-content: space-around;
  }

  .receiver ul li {
    background: #303030;
    width: 1px;
    height: 1.5px;
    float: left;
    transform: skewX(-38deg);
  }
  .bang {
    width: 150px;
    height: 25px;
    background-color: #000;
    position: absolute;
    left: 50%;
    transform: translateX(-50%);
    border-radius: 0 0 13px 13px;
    top: 0;
  }
  .yuan {
    width: 10px;
    height: 10px;
    background-color: #070e21;
    box-sizing: border-box;
    position: absolute;
    top: 4px;
    right: 18px;
    border-radius: 50%;
  }
  .look_my_phone .phone_conts {
    overflow: hidden !important;
    padding: 0 !important;
  }

样式如果有错乱 请自行修改

组件使用

<my-phones :lists="phoneList"></my-phones>

数据格式

phoneList: [
          {
            type: 'text',
            conts: '1212',
          },
          {
            type: 'img',
            conts: '图片路径',
          },
        ],

别忘了注册组件 可以全局/局部注册

上传图片 用的formData 你们后端要什么参数 就传什么参数  

代码很简单 请自行阅读

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue + Element是一种在Vue项目中使用Element UI框架的组合。Element是一个基于Vue 2.0的桌面端组件库,为开发者、设计师和产品经理提供了丰富的组件和样式。\[1\] 要在Vue项目中使用Element UI,首先需要引入Element UI。可以通过两种方法引入:一种是通过安装Node包,另一种是通过CDN引入。如果选择安装Node包的方式,可以使用命令`cnpm i element-ui --save`进行安装。如果选择CDN引入的方式,需要在HTML文件中引入Element UI的样式和组件库的链接。\[3\] 在main.js文件中,需要注册Element UI。可以通过`import ElementUI from 'element-ui'`和`Vue.use(ElementUI)`来注册Element UI。这样就可以在Vue项目中使用Element UI组件了。\[2\]\[3\] 使用Element UI的具体步骤可以参考Element官网提供的例子和代码,根据官网的指引来实现想要的效果。\[3\] 总结起来,Vue + Element是指在Vue项目中使用Element UI框架的组合。通过引入Element UI并在main.js中注册,可以在Vue项目中使用Element UI的丰富组件和样式。具体的使用步骤可以参考Element官网提供的例子和代码。 #### 引用[.reference_title] - *1* *2* [VueElement的使用](https://blog.csdn.net/s_9527_s/article/details/123094193)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [vue中使用element(菜鸟教程)](https://blog.csdn.net/weixin_44727080/article/details/113607189)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值