实现装修页面组件拖拽(热区)

1,174 阅读8分钟

图片热区是在一张图片上,制作任意尺寸的四边形区域,并添加链接的一种方式,可以实现在一张图片上,点击不同区域跳转不同页面的效果。

优点:

www.zjhejiang.com/site/news-d…

借鉴项目一:

demo.buhuida.com/vue-hot-zon… image.png 地址: toscode.gitee.com/sync-github…

项目二:

github.com/Mochen07/im…

image.png

imgHotpost 组件

体验地址:github.com/tukideng/im…

image.png

image.png

光标呈现为十字线
cursor: crosshair;
ondragstart - 用户开始拖动元素时触发

return false 就是禁止拖动

ondragstart="return false;"
当用户在 <div> 元素 上右击鼠标时执行 JavaScript :
禁止右击
oncontextmenu="return false;"
当文本被选中时,执行一段 Javascript代码:
document.selection.empty() 让选中的内容不选中 
onselect="document.selection.empty();"

Mouse Down是鼠标按下触发的动作;Mouse Up是鼠标抬起触发的动作;Mouse Click就是按下又抬起的动作;click是激活,包含了MouseClick,MouseClick是鼠标点击; click不只是鼠标点击,当焦点在该控件上,按回车时也激发此事件,MouseClick应该有鼠标点击坐标属性成员。

mousedown 事件当鼠标指针移动到元素上方,并按下鼠标按键时触发 因为mousedown事件会在click事件之前触发

stop - 阻止冒泡

例子:

www.w3school.com.cn/tags/tag_ma…

image.png

image.png

image.png

document.onmousemove www.runoob.com/try/try.php…

image.png

image.png

image.png

image.png

用area方法:

ebook.wanggege.cn/html/5-%E5%…

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>图像热区</title>
    <style>
        body{
            padding: 0;
            margin: 0;
        }
        #rect{
            display: inline-block;
            position: absolute;
            left: 338px;
            top: 147px;
            width: 120px;
            height: 450px;
            border: 1px solid #f00;
            z-index: 1;
        }
        #circle{
            display: inline-block;
            position: absolute;
            left: 150px;
            top: 0;
            width: 150px;
            height: 150px;
            border: 1px solid #f00;
            border-radius: 50%;
            z-index: 1;
        }
    </style>
</head>
<body>
    <img src="./onepiec.jpg" width="800px" title="海贼王" usemap="#map" />

    <map id="map" name="map">
        <area id="rect" shape="rect" coords="338,147,458,597" href="https://www.baidu.com/?tn=78040160_5_pg&ch=1" />
        <area id="circle" shape="circle" coords="225,75,75" href="https://www.baidu.com/?tn=78040160_5_pg&ch=1" target="_blank" />
    </map> 
</body>
</html>

那个坐标是对角 image.png

热图

越界的问题:

image.png

合并对象写法:

image.png

每个组件都至少添加一个图片 链接 还有热区

getBoundingClientRect()方法 可以拿到自身元素的宽高

image.png

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        div {
            width: 100px;
            height: 200px;
            background-color: rgb(109, 27, 141);
            position: absolute;
            left: 100px;
            top: 200px;
        }
    </style>

</head>

<body>
    <div id="box"></div>
    <script>
        var object = document.getElementById('box');
        rectObject = object.getBoundingClientRect();
        console.log('rectObject',rectObject);
        console.log("rectObject.top", rectObject.top);
        console.log("rectObject.bottom", rectObject.bottom);
        console.log("rectObject.right", rectObject.right);
        console.log("rectObject.left", rectObject.left);
        console.log("rectObject.width", rectObject.width);
        console.log("rectObject.height", rectObject.height);
        console.log("rectObject.x", rectObject.x);
        console.log("rectObject.y", rectObject.y);



        // rectObject.top: 元素上边到视窗上边的距离;
        // rectObject.right: 元素右边到视窗左边的距离;
        // rectObject.bottom: 元素下边到视窗上边的距离;
        // rectObject.left: 元素左边到视窗左边的距离;
        // rectObject.width: 是元素自身的宽
        // rectObject.height是元素自身的高
    </script>

</body>

</html>

image.png

image.png

image.png

image.png

image.png

bug

image.png

鼠标在规定范围外松开的话 那么你重新点击 原来的热区会定位到新点击的那个位置

处理: 鼠标在外面松开 要把这个宽高给确定下来

image.png

vue子盒子距离父盒子的距离

热区保存的数据:

image.png

热区图片上传的宽度和高度是不确定的 怎么拿到这个宽高呢?

image.png

layerX 与 layerY

www.pipipi.net/questions/1…

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        #box {
            width: 500px;
            height: 400px;
            margin: 0px auto;
            background: blue;
        }

        #middle {
            width: 300px;
            height: 200px;
            margin: 0px auto;
            background: green;
            position: relative;
            overflow: hidden;
        }

        #inner {
            width: 100px;
            height: 100px;
            background: #000000;
            margin: 0px auto;
            margin-top: 10px;
            text-align: center;
            line-height: 100px;
            color: white;
        }
    </style>
</head>

<body>

    layerX:鼠标相比较于当前坐标系的位置,即如果触发元素没有设置绝对定位或相对定位,
    以页面为参考点,如果有,将改变参考坐标系,从触发元素盒子模型的border区域的左上角为参考点
    也就是当触发元素设置了相对或者绝对定位后。
    <div id="box">
        <div id="middle">
            <div id="inner"></div>
        </div>
    </div>

    <script>
        window.onload = function () {
            var odiv = document.getElementById("inner");
            odiv.onclick = function (ev) {
                odiv.innerHTML = `layerX:${ev.layerX},layerY:${ev.layerY}`;
            }
        }
    </script>
</body>

</html>

找到距离最近设置了position: relative;相对定位的元素开始计算

image.png

image.png

image.png

自身加了position

image.png image.png

自身与父元素取消了position 父元素没有设置position还是相对于父元素(如果自身没有设置position) image.png

image.png 如果触发元素设置了position ( position: absolute;/relative ),则offsetX等于layerX 从内容区域左上角开始定位,不是从border左上角开始!有时候会比layerX多了1像素

image.png

clientX clientY image.png

image.png

移动到左侧的坐标:

image.png

image.png

变形的解释:

image.png

(变化后的距离 - 变化前的距离 )+ 原本的自身 = 后来的自身

是负数变短 是正数就变长了

initX + ev.clientX - this.star1X = 改变后的距离(会变长或短)

问题: vue怎样控制热区在图片上移动

length老是找不到

image.png

报错:

image.png

image.png “翻译的白话就是:“list”已经在prop声明了.

关于key的正解:

image.png blog.csdn.net/qq_35473192…

image.png

即在同一个dom节点中包含了两个v-for也就出现了两个key,而这两个key都是遍历的索引,所以两个key的值会是相同的,违反了类似唯一约束的原则。

ps:很多资料说产生的原因是key的名字重复,这很扯淡。

加div包裹是可以的 image.png

解决方案

1、我们可以不让他们在同一个dom节点内,用一个盒子来隔离他们。

2、我们可以修改其中一个key,让他和遍历索引可以区分开,比如修改为item.id。

修改el-select的高 不是有size = small

elementUI的el-select下拉加载更多及远程搜索

解决vue该页面调用别的页面方法 this.bus.bus.on 执行多次

image.png

image.png blog.csdn.net/ZJ159818370…

image.png

js 0在if判断中算是false 0 != null

下拉框加载更多

blog.csdn.net/LiNGY0110/a… 解读:

image.png

image.png

if(this.pageRemote > 1){
    this.optionsList = [...this.optionsList,...val] 
}else{
    this.optionsList = val
}

计算属性不能被修改

image.png

vue.runtime.esm.js?2b0e:619 [Vue warn]: Computed property "classifyNameChecked" was assigned to but it has no setter.

同宽不同高的下拉刷新瀑布流,并带有懒加载和淡入特效的

瀑布流 # vue实现商品列表瀑布流(上拉加载)

Module build failed: Error: Node Sass version 6.0.1 is incompatible with ^4.0.0.

blog.csdn.net/Mr_XG/artic… image.png

image.png 不是指定你去下载这个版本 而是去看你的项目 这里显示的是什么版本 上面的提示不一定是说你的版本太高 只是不对应当前项目的版本

image.png image.png

解决瀑布流 把数据拆成两半

方法优秀备注写法:

image.png

封装el-table 插槽怎么处理

注:v-solt只能在template标签内使用(2.6.0版本以后才有v-solt),也可用solt,在普通html标签内使用,用法:<span slot="right">右边 image.png

带子组件数据的插槽

image.png

image.png

表头可以拖拉的

image.png

image.png

image.png

image.png

image.png

image.png 名字一样

image.png

image.png

Vue Element UI 之使用 Notification 组件 不生效

image.png

js 数组遍历把里面子项的数组删除

image.png

隐藏表头

image.png

dom 还没有出来怎么拿到子组件的数据

dialog 子组件 mounted 里面的方法还是先会执行的 即使他还没弹出来

这个时候是ref拿不到里面的dom节点的 要用this.$children【index】

也不行 $children 并不保证顺序,也不是响应式的。 行不通

最后解决是在等弹窗打开了然后 再请求中this.nextTick(中this.nextTick(中this.ref)

table 点击行勾选 再次点击取消勾选

vue父组件调用孙组件的方法 携带值过去 不要再用什么props + watch传了

image.png

css 中1px等于多少像素

页面加载进来 但是数据还没有返回 又发送网络请求

image.png 一开始使用的是防抖

image.png 但是来回切换还是发送两次请求

vue页面首次加载进来调用接口 数据还没有返回 又去请求接口 第一次页面加载回来的数据很多还没有回来 第二次请求数据很快回来了 然后第二次最新的请求数据会被第一次请求的数据覆盖掉

由于一个接口响应时间比较长,第一次法访问结果未返回时,用户又一次进行请求.
第二次请求结果先返回,第一次的结果再返回会直接妨碍掉第二次的结果.
请问如果只想获取第二次请求的结果应该怎么做?

先发起的请求覆盖后发起的请求数据问题?

image.png pengshiyu.blog.csdn.net/article/det…

还是用定时器解决吧!!!

v-model 不要绑定有数组的

image.png

vue.runtime.esm.js?2b0e:619 [Vue warn]: Error in render: "TypeError: Cannot read property '0' of und

image.png 这是因为 数据还没到先显示了

img url 是网络地址做背景

blog.csdn.net/u013302168/… www.freesion.com/article/723…

设置背景图 huaweicloud.csdn.net/638eaba2dac…

vue dialog 条状到别的页面 返回需要保留当前页面

vue怎么跳转到另一个页面 不关闭el-dialog弹框?

弹窗备注:// 控制弹框是否展示标识

image.png 注意子组件渲染只会执行一次created生命周期,如果非要将更改内容写在created中,就要配合 v-if 使用,将子组件用 v-if 包裹起来,每次都重新加载子组件。

Vue 组件自己调用自己 ( 递归组件)

弹窗调用弹窗组件

嵌套的弹层 Vue +Element UI 前端写假分页,不请求后台数据接口

遇到的问题:# vue element table 递归组件插槽

vue 拖拉组件 拉到不是该接受区域 报错

image.png

postman 成功 项目配置了/api 跨域处理确报404

vue 前台访问多个后台接口

前端本地对接后端多个本地接口 blog.csdn.net/m0_57108418…

缺点: 以前很多api接口都需要修改了

可以这样设计:

image.png 在/api的接口上可以多加识别的标志

image.png

404

image.png

image.png

image.png www.onlinedown.net/article/100… image.png

瀑布流分隔成两半 如果右侧高度很高 会导致很难看

image.png

发现是写错了:

image.png 将一个数组中的奇偶数划分为两组,其中奇数在前面,偶数在后面

用网格布局处理就行 image.png

blog.csdn.net/WLK654321/a…

<template>
  <div class="product-content">
    <div class="content">
      <div style="margin-bottom: 28px">
        <p>最多展示商品数量</p>
        <el-select
          v-if="
            list.componentPropertyList && list.componentPropertyList.length > 0
          "
          v-model="list.componentPropertyList[0].propertyValue"
          clearable
          placeholder="请选择(没有商品不可选)"
          size="small"
          class="select"
          :disabled="isDisable"
          @change="showGoodsNumber"
        >
          <el-option
            v-for="item in goodsNumberOptions"
            :key="item.value"
            :label="item.value"
            :value="item.value"
          >
          </el-option>
        </el-select>
      </div>
      <div style="margin-bottom: 28px">
        <p>展示分类</p>
        <el-select
          v-loadmore="selectEnd"
          v-if="
            list.componentPropertyList && list.componentPropertyList.length > 0
          "
          v-model="list.componentPropertyList[1].propertyValue"
          clearable
          placeholder="请选择"
          size="small"
          class="select"
          @change="categoryIdChange"
          ref="selectLabel"
        >
          <el-option
            v-for="item in goodsClassifyOptions"
            :key="item.id"
            :label="item.name"
            :value="item.id"
          >
          </el-option>
        </el-select>
      </div>
      <div style="margin-bottom: 28px">
        <div style="margin-bottom: 4px">
          <el-checkbox
            :disabled="
              !list.componentPropertyList[1].propertyValue ||
              list.componentPropertyList[6].propertyName.length <= 0
            "
            v-if="
              list.componentPropertyList &&
              list.componentPropertyList.length > 0
            "
            @change="checkboxChange"
            v-model="list.componentPropertyList[2].propertyValue"
            >展示分类名称</el-checkbox
          >
        </div>
        <el-radio-group
          v-if="
            list.componentPropertyList && list.componentPropertyList.length > 0
          "
          v-model="list.componentPropertyList[3].propertyValue"
        >
          <el-radio
            :disabled="!list.componentPropertyList[2].propertyValue"
            :label="0"
            >白色</el-radio
          >
          <el-radio
            :disabled="!list.componentPropertyList[2].propertyValue"
            :label="1"
            >黑色</el-radio
          >
        </el-radio-group>
      </div>
      <div style="margin-bottom: 28px">
        <p>排序规则</p>
        <el-select
          v-if="
            list.componentPropertyList && list.componentPropertyList.length > 0
          "
          @change="sortChange"
          v-model="list.componentPropertyList[4].propertyValue"
          clearable
          placeholder="请选择"
          size="small"
          class="select"
        >
          <el-option
            v-for="item in sortRuleOptions"
            :key="item.value"
            :label="item.label"
            :value="item.value"
          >
          </el-option>
        </el-select>
      </div>
      <div class="item-bgc">
        <p>模块背景</p>
        <span>宽度750像素,高度460像素</span>
        <Upload
          v-if="
            list.componentPropertyList && list.componentPropertyList.length > 0
          "
          style="margin-top: 8px"
          :list="list.componentPropertyList[5]"
          :isLink="false"
        ></Upload>
      </div>

      <div class="line"></div>
      <el-checkbox style="font-size: 16px" v-model="list.gapType"
        >露出模块下方间隙</el-checkbox
      >
    </div>
  </div>
</template>

<script>
// import { searchProduct } from '@/api/pageDecoration.js'
import { filterInquiryEmpty } from "@/utils/util";
import { getProductData } from "@/api/goodsManage";
import vuedraggable from "vuedraggable";
import Upload from "./Upload.vue";
import { tenantGoodsClassifyData } from "@/api/tenantGoodClassify";
export default {
  name: "Classify",
  components: {
    vuedraggable,
    Upload,
  },
  props: {
    data: {
      type: Object,
      default: () => {},
    },
  },
  computed: {
    isDisable() {
      return (
        this.list.componentPropertyList &&
        this.list.componentPropertyList[6] &&
        this.list.componentPropertyList[6].propertyName.length == 0
      );
    },
  },
  watch: {},
  data() {
    return {
      goodsQuery: {
        pageNum: 1,
        pageSize: 10,
        sortField: "",
        sortOrder: "",
        publishStatus: 1, //展示的都是上架商品
      },
      // goodsTableData: [],
      // classifyNameChecked: true,
      // showClassifyName: 0,
      PageNum: 1,
      pullDown: true,
      goodsNumberOptions: [
        {
          value: 2,
        },
        {
          value: 4,
        },
        {
          value: 6,
        },
        {
          value: 8,
        },
        {
          value: 10,
        },
      ],
      // numberValue: "", //可选2、4、6、8、10
      /* 展示分类 */
      goodsClassifyOptions: [],
      // categoryId: "",
      /* 排序规则 */
      sortRuleOptions: [
        {
          value: 1,
          label: "按照新品上架时间排序",
        },
        {
          value: 2,
          label: "按照销量排序",
        },
        {
          value: 3,
          label: "按价格从高到低排序",
        },
        {
          value: 4,
          label: "按价格从低到高排序",
        },
      ],
      // sortRuleValue: "",
      list: {},
      productList: [],
      loading: false,
      show: false,

      selectItem: null,
      selectProduct: "",

      loadingOption: false,
    };
  },
  created() {
    this.getGoodsList();
    this.getClassifyList();
  },
  mounted() {
    this.list = this.data;
    if (!this.data.tabType) {
      // this.$emit('changeTab', 2)
      // this.$emit('changeTab', 1)
      this.$emit("changeTab", 3);
    }
    this.loadingOption = true;
  },
  methods: {
    showGoodsNumber(value) {
      // 再次点击自身是不会触发的
      this.list.componentPropertyList[6].propertyValue = [];
      const length = this.list.componentPropertyList[6].propertyName.length;
      if (value === 2) {
        if (length >= 2) {
          this.list.componentPropertyList[6].propertyValue = this.dealData(
            this.list.componentPropertyList[6].propertyName.slice(0, 2)
          );
        } else {
          this.list.componentPropertyList[6].propertyValue = this.dealData(
            this.list.componentPropertyList[6].propertyName.slice(0, length)
          );
        }
      } else if (value === 4) {
        if (length >= 4) {
          this.list.componentPropertyList[6].propertyValue = this.dealData(
            this.list.componentPropertyList[6].propertyName.slice(0, 4)
          );
        } else {
          this.list.componentPropertyList[6].propertyValue = this.dealData(
            this.list.componentPropertyList[6].propertyName.slice(0, length)
          );
        }
      } else if (value === 6) {
        if (length >= 6) {
          this.list.componentPropertyList[6].propertyValue = this.dealData(
            this.list.componentPropertyList[6].propertyName.slice(0, 6)
          );
        } else {
          this.list.componentPropertyList[6].propertyValue = this.dealData(
            this.list.componentPropertyList[6].propertyName.slice(0, length)
          );
        }
      } else if (value === 8) {
        if (length >= 8) {
          this.list.componentPropertyList[6].propertyValue = this.dealData(
            this.list.componentPropertyList[6].propertyName.slice(0, 8)
          );
        } else {
          this.list.componentPropertyList[6].propertyValue = this.dealData(
            this.list.componentPropertyList[6].propertyName.slice(0, length)
          );
        }
      } else if (value === 10) {
        if (length >= 10) {
          this.list.componentPropertyList[6].propertyValue = this.dealData(
            this.list.componentPropertyList[6].propertyName.slice(0, 10)
          );
        } else {
          this.list.componentPropertyList[6].propertyValue = this.dealData(
            this.list.componentPropertyList[6].propertyName.slice(0, length)
          );
        }
      }
    },
    categoryIdChange(id) {
      console.log("id", id);
      // if(!id){
      //   this.list.componentPropertyList[3].propertyValue = 0;
      //   this.list.componentPropertyList[1].propertyValue = "";
      //   return
      // }
      this.list.componentPropertyList[6].propertyValue = [];
      this.goodsQuery.categoryId = id;
      this.getGoodsList();
      this.$nextTick(() => {
        this.list.componentPropertyList[1].propertyName =
          this.$refs.selectLabel.selectedLabel;
        /* 都可以拿到 */
        // console.log(this.$refs.selectLabel.selectedLabel);
        // console.log(this.$refs.selectLabel.selected.label);
      });
    },
    sortChange(value) {
      this.list.componentPropertyList[6].propertyValue = [];
      if (value === 1) {
        //后续加
        this.goodsQuery.sortField = "";
        this.goodsQuery.sortOrder = "";
        // this.goodsQuery.publishStatus = 1;
        this.getGoodsList();
      } else if (value === 2) {
        this.goodsQuery.sortField = "sale";
        this.goodsQuery.sortOrder = 2;
        this.getGoodsList();
      } else if (value === 3) {
        this.goodsQuery.sortField = "price";
        this.goodsQuery.sortOrder = 2;
        this.getGoodsList();
      } else if (value === 4) {
        this.goodsQuery.sortField = "price";
        this.goodsQuery.sortOrder = 1;
        this.getGoodsList();
      }
    },
    checkboxChange(value) {
      if (!value) {
        // this.showClassifyName = 0;
        this.list.componentPropertyList[3].propertyValue = 0;
      }
    },
    selectEnd() {
      if (this.pullDown) {
        this.PageNum++;
        this.getClassifyList();
      }
    },
    // 瀑布流分隔数据
    dealData(list) {
      let data = {
        goodsListR: [],
        goodsListL: [],
      };
      list.forEach((item, index) => {
        if (index % 2 == 0) {
          data.goodsListL.push(item);
        } else {
          data.goodsListR.push(item);
        }
      });
      return data;
    },
    async getGoodsList() {
      try {
        let tempObj = JSON.parse(JSON.stringify(this.goodsQuery));
        let obj = filterInquiryEmpty(tempObj);
        const res = await getProductData(obj);
        if (res.code === 200) {
          let { list, pageNum, pageSize, total, totalPage } = res.data;

          list.forEach((item, index) => {
            item.pic = this.$store.getters.imagePrefix + item.pic;
          });

          /* propertyName  存的是总数据 propertyValue 存的是展示数据 是裁剪后的 */
          this.list.componentPropertyList[6].propertyName = list;
          if (
            list.length > 0 &&
            !this.list.componentPropertyList[0].propertyValue
          ) {
            //默认展示两个 有一个就展示一个
            this.list.componentPropertyList[0].propertyValue = 2;
          }
          let cutOutTempArr = [];
          if (list.length < this.list.componentPropertyList[0].propertyValue) {
            // 默认展示2条 那么返回只有一条 默认显示还是展示两条 还是需要显示一条数据
            // this.list.componentPropertyList[0].propertyValue = ""; 有多少展示多少 1<2 4 6 8 10
            cutOutTempArr = list;
            if (list.length > 0) {
              this.list.componentPropertyList[0].propertyValue = 2;
            } else {
              this.list.componentPropertyList[0].propertyValue = "";
            }
          } else {
            cutOutTempArr = list.slice(
              0,
              this.list.componentPropertyList[0].propertyValue
            );
          }
          /* 截成两半 */
          this.list.componentPropertyList[6].propertyValue =
            this.dealData(cutOutTempArr);
          console.log(
            "goodsTableData",
            this.list.componentPropertyList[6].propertyValue
          );
        } else {
          this.$message.error(res.message);
        }
      } catch (error) {
        console.log(error);
      }
    },
    async getClassifyList() {
      try {
        const query = {
          level: 0,
          pageNum: this.PageNum,
          pageSize: 10,
        };
        //第二个参数传多少条过去就返回多少数据
        const res = await tenantGoodsClassifyData(query);
        if (res.code === 200) {
          let { total, list } = res.data;
          this.goodsClassifyOptions = [...this.goodsClassifyOptions, ...list];
          console.log("goodsClassifyOptions", this.goodsClassifyOptions);
          /* 预防多次刷新 */
          if (list.length < 10 || this.goodsClassifyOptions.length >= total) {
            this.pullDown = false;
          }
        } else {
          this.$message.error(res.message);
        }
      } catch (error) {
        console.log(error);
      }
    },
  },
};
// 模拟产品列表
var productList = [
  {
    productId: 3601,
    productName: "驼大大新疆正宗骆驼奶粉初乳骆驼乳粉蓝罐礼盒装120g*4罐",
    productImg:
      "https://img.quanminyanxuan.com/excel/f6860885547648d9996474bbf21fdca9.jpg",
    productPrice: 299,
    originalPrice: 598,
    volumeStr: "741",
    goodRatio: 98,
  },
  {
    productId: 3268,
    productName: "百合28件套新骨质瓷餐具",
    productImg:
      "https://img.quanminyanxuan.com/excel/185e7365f65543f2b4ebc67036d6a78f.jpg",
    productPrice: 370,
    originalPrice: 1388,
    volumeStr: "400",
    goodRatio: 99,
  },
  {
    productId: 3343,
    productName: "和商臻品槐花蜜250克/瓶",
    productImg:
      "https://img.quanminyanxuan.com/excel/4626c8c628d04935b0262d04991416b2.jpg",
    productPrice: 34.5,
    originalPrice: 72,
    volumeStr: "258",
    goodRatio: 98,
  },
  {
    productId: 3330,
    productName: "鲍参翅肚浓羹350g袋装",
    productImg:
      "https://img.quanminyanxuan.com/excel/58a0c968dc7d42c3ac21e09d1862aa6f.jpg",
    productPrice: 75,
    originalPrice: 128,
    volumeStr: "258",
    goodRatio: 98,
  },
];
</script>

<style lang="scss">
.product-content {
  .content {
    padding: 20px 40px 0 40px;
    .select {
      margin-top: 8px;
      width: 100%;
    }
  }
}
.item-bgc {
  margin-top: 28px;
  p {
    font-size: 16px;
    margin-bottom: 4px;
  }
  span {
    font-size: 14px;
    color: #bcbcbc;
  }
}

.line {
  margin: 24px auto;
  //   padding: 0 40px;
  height: 1px;
  width: 100%;
  background-color: #e4e4e4;
}
</style>
  <div class="root">
          <div class="item">
            <div
              class="good"
              v-for="(item, index) in data.componentPropertyList[6]
                .propertyValue.goodsListL"
              :key="index"
            >
              <img :src="item.pic" />
              <p class="title">
                {{ item.productName }}
              </p>
              <p class="assess">10万+ 评价 | 95.9%好评率</p>
              <div class="price">
                <span> ¥{{ item.price }} </span>
                <span> ¥0 </span>
              </div>
            </div>
          </div>
          <div class="item">
            <div
              class="good"
              v-for="(item, index) in data.componentPropertyList[6]
                .propertyValue.goodsListR"
              :key="index + ' '"
            >
              <img :src="item.pic" />
              <p class="title">
                {{ item.productName }}
              </p>
              <p class="assess">10万+ 评价 | 95.9%好评率</p>
              <div class="price">
                <span> ¥{{ item.price }} </span>
                <span> ¥0 </span>
              </div>
            </div>
          </div>
        </div>

vue ref如何拿到所有子元素的高度

:style="cssVars"

放在计算属性里面或者在data里面的变量都可以

vue dom父元素拿到子元素的高度

vue html 中使用var变量的css

 :style="`grid-row: var(--item-span-${index})`"

vue 往对象里面添加属性

image.png

控制图片宽高:

image.png

Error: EBUSY: resource busy or locked, symlink 'C:\Users\Administrator\Desktop\新建文件夹 (2)\dw-mall-admin-web\node_modules\_accepts@1.3.8@accepts' -> 'C:\Users\Administrator\Desktop\新建文件夹 (2)\dw-mall-admin-web\node_modules\_express@4.18.2@express\node_modules\accepts'

报错:把电脑管家退出了 也没有

image.png

Install fail! Error: EBUSY: resource busy or locked, symlink

后面用的是 npm i 没有用cnpm

// "!!" ——两个叹号表示把目标值转化为布尔值,相当于使用Boolean()方法 image.png

js 将一个数据复制成两份 深拷贝

提交的数据中 必填数据提示(有多个的情况下怎么提示好?) 但不是作用在表单

拖拉组件如何判断当前拖拉的组件 放在已有的组件上面怎么知道是否是 在组件的上方还是下方?

+= =+

zhuanlan.zhihu.com/p/491519217

delect 删除数组里面的item 会是null

image.png

image.png

www.cnblogs.com/clear93/p/7…

拿到select的值

 this.$nextTick(() => {
        this.list.componentPropertyList[1].propertyName =
          this.$refs.selectLabel.selectedLabel;
        /* 都可以拿到 */
        // console.log(this.$refs.selectLabel.selectedLabel);
        // console.log(this.$refs.selectLabel.selected.label);
      });

js 除法 NaN

image.png 如果设置了 type 数字是不会改成string的

SELECET 远程查询

image.png

js for 是同步的吗

是的

  for (var i = 0; i < 10; i++)
            console.log(i)
        for (var i = 10; i < 20; i++)
            console.log(i)

            console.log("sssssssssss");
        //  以上两个for循环,第一个打印1-10,第二个打印10-20,结果是1-20按顺序输出
        // 
        //   js中代码是同步执行的,只有在ajax的情况下,会导致代码执行顺序改变,是因为ajax的请求时间导致

element 上传图片控制图片的上传高度

参考: www.cnblogs.com/luoxuemei/p…

www.cnblogs.com/fairy62/p/9… www.cnblogs.com/foxcharon/p…

www.cnblogs.com/baozhengrui…

发现一个 多文件传file给后台的

www.cnblogs.com/luoxuemei/p…

vue中获取图片url中的真实宽高

blog.csdn.net/EnidChann/a…

     // 获取图片尺寸 商品的图片尺寸 不能用来控制盒子的大小
     getImgSize (url) {
      return new Promise((resolve, reject) => {
        let imgObj = new Image()
        imgObj.src = url
        // console.log("imgObj",imgObj.width,imgObj.height);
        imgObj.onload = () => {
          resolve({
            width: imgObj.width,
            height: imgObj.height
          })
        }
      })
    },
获取数据后传入图片url获取尺寸(宽高)
          cutOutTempArr.map(async item => {
	           item.imgSize = await this.getImgSize(item.pic)
	        })

在vue中解决提示警告 for循环报错的方法 **

image.png

:data-index="index"

e.target.dataset.index 可以拿到