其他分享
首页 > 其他分享> > vue 数据树结构 无限递归 组件调用本身 父组件监听子组件 高亮

vue 数据树结构 无限递归 组件调用本身 父组件监听子组件 高亮

作者:互联网

 

  1. 传入的数据结构   需要这种数据类型 使用父组件向子组件传值
    1. { "id": 0, "name": "", "children": [ { "children": [ { "children": [ { "fid": 2, "id": 3, "levar": null, "name": "python自动化", "params": "0" }, { "fid": 2, "id": 4, "levar": null, "name": "python web开发", "params": "0" } ], "fid": 1, "id": 2, "levar": null, "name": "python歌词", "params": "0" }, { "fid": 1, "id": 11, "levar": null, "name": "lang课程", "params": "{\"lanuage\":\"语言\",\"editor\":\"编辑器\",\"pc\":\"电脑型号\"}" } ], "fid": 0, "id": 1, "levar": null, "name": "编程课程", "params": "0" }, { "children": [ { "children": [ { "fid": 6, "id": 8, "levar": null, "name": "炒菜类", "params": "0" } ], "fid": 5, "id": 6, "levar": null, "name": "粤菜", "params": "0" }, { "fid": 5, "id": 7, "levar": null, "name": "鲁菜", "params": "0" } ], "fid": 0, "id": 5, "levar": null, "name": "烹饪课程", "params": "0" }, { "children": [ { "fid": 9, "id": 10, "levar": null, "name": "黄老师", "params": "{\"lanuage\":\"盆\",\"editor\":\"碗\",\"pc\":\"锅\"}" } ], "fid": 0, "id": 9, "levar": null, "name": "瑜伽课程", "params": "0" } ] }

        2 子组件 递归调用自己


        

<template>
      
  <div>
    
    <div
      v-if="data.id != 0"
      @click="getfid(data.id)"
      :id="data.id"
      :class="cid == data.id?'bg':''"
      
    >
      {{ data.name }}
    </div>
    <li>
      <ul v-if="data.children && data.children.length > 0">
        <Reply v-for="child in data.children" :key="child.id" :data="child" />
      </ul>
    </li>

        
  </div>
</template>

<script>
import axios from "axios";
import bus from "./bus.js";
export default {
  //声明名称
  name: "Reply",
  props: ["data"],
  components: {},
  data() {
    return {
        fid:0,
        cid:0
    };
  },
  // 声明方法
  methods: {
    //点选分类id
    getfid: function (fid) {
      this.fid = fid;
      // console.log(fid)

      bus.$emit("msg", fid);

      // 取消说有高亮
      var divs = document.getElementsByClassName("bg");

      // 遍历选择器
      for (var i = divs.length - 1; i >= 0; i--) {
        //取消高亮
        divs[i].classList.remove("bg");
      }

      //首先将当前元素高亮显示
      var mydiv = document.getElementById(fid);
      // 动态添加高亮类选择器
      mydiv.classList.add("bg");
    },
  },
  mounted() {
      this.cid = localStorage.getItem("cateid")

  },
  created() {},
};
</script>

<style scoped>
ul {
  padding-left: 10rem;
  list-style: none;
}
.bg {
  background: orange;
  color: white;
}
</style>

3 实现父住键点击子组件数据高亮 显示颜色


 首先创建一个bus.js文件(文件名随意)

        文件写入

import Vue from "vue"

export default new Vue();

 在子组件导入bus.js文件 利用子传参传给bus.js

 bus.$emit("msg", fid);

父组件用on监听

  created() {
    // 监听
    bus.$on("msg", (target) => {
      this.fid = target;
    });
  },

我的父组件效果

 

 父组件代码:

        

<template>
  <div>
    <myheader />

    <Repel :data="mydata" />

    <van-cell-group>
      <van-field label="课程标题" v-model="title" />
      <van-field label="课程描述" v-model="desc" rows="5" type="textarea" />

      <van-field
        v-show="show_course"
        v-for="(item, index) in params"
        :label="item.label"
        :key="index"
        v-model="info[item.key]"
      />

      <van-field
        v-show="show_cate"
        v-for="(value, key, index) in params_cate"
        :label="value"
        :key="index"
        v-model="info_cate[key]"
      />

      <van-button color="pink" @click="editcourse">保存修改课程</van-button>

      单视频上传<van-uploader :after-read="afterRead" /> 多视频上传<van-uploader
        v-show="cid"
        multiple
        :after-read="afterRead_list"
      />
    </van-cell-group>

    <van-button
      color="yellow"
      @click="
        show_choice == false ? (show_choice = true) : (show_choice = false)
      "
      >多选</van-button
    >
    <van-button v-show="show_choice" color="red" @click="delvideos()"
      >批量删除</van-button
    >
    <div v-for="(item, index) in srcs" :key="index">
      <van-button @click="play(item, index)">
        第 {{ index + 1 }} 集
      </van-button>
      <input
        v-show="show_choice"
        type="checkbox"
        :value="item"
        v-model="checkbox_list"
      />
    </div>

    <div v-if="src !== ''">
      <!-- 视频展示 -->
      <video
        v-show="src"  
        width="400rem"
        height="200rem"
        :src="upload_dir + src"
        controls="controls"
        autoplay="autoplay"
        muted
      ></video>

      修改:<van-uploader :after-read="newafterRead" />
      <van-button color="red" @click="delvideo()">删除视频</van-button>
    </div>



    <footers />
  </div>
</template>

<script>
//导入头部尾部组件
import myheader from "./myheader.vue";
import footers from "./footers.vue";
import Repel from "./Reply.vue";
import bus from "./bus.js";
import axios from "axios";
export default {
  //声明组件
  components: {
    myheader: myheader,
    footers: footers,
    Repel: Repel,
  },
  data() {
    return {
      title: "", // 标题
      desc: "", // 描述
      cid: 0, // 课程id
      fid: 0, // 分类id
      mydata: [], //数据展示
      params: [], // 特定参数
      info: [], // 字典容器,动态生成容器
      info_cate: [],
      srcs: [], // 商品展示列表
      video_item: "", // 选中视频集
      video_index: 0, // 视频下标
      src: "", // 视频
      params_cate: {},
      show_course: true,
      show_cate: false,
      checkbox_list: [], // 删除商品列表
      show_choice: false, // 删除 多选 展示
    };
  },
  methods: {





    // 根据value进行删除
    myremove: function (vals, val) {
      //拿到删除目标删除的下标
      var index = vals.indexOf(val);
      if (index > -1) {
        // 删除操作
        this.srcs.splice(index, 1);
      }
    },


    // 批量删除
    delvideos: function () {
      var videolist = JSON.stringify(this.checkbox_list);
      this.$dialog
        .confirm({ title: "删除视频操作,删除后不可恢复" })
        .then(() => {
          this.axios
            .delete("http://localhost:5000/delvideos/", {
              params: {
                id: this.cid,
                uid: localStorage.getItem("id"),
                token: localStorage.getItem("token"),
                videolist: videolist,
              },
            })
            .then((result) => {
              for (let i = 0; i < this.checkbox_list.length; i++) {
                this.myremove(this.srcs, this.checkbox_list[i]);
              }
              this.$toast.success(result.data.msg);
            });
        });
    },

    // 删除视频
    delvideo: function () {
      this.$dialog
        .confirm({ title: "删除视频操作,删除后不可恢复" })
        .then(() => {
          this.axios
            .delete("http://localhost:5000/delvideo/", {
              params: {
                id: this.cid,
                uid: localStorage.getItem("id"),
                token: localStorage.getItem("token"),
                index: this.video_index,
              },
            })
            .then((result) => {
              this.$toast.success(result.data.msg);
              // 删除
              this.srcs.splice(this.srcs[this.video_index], 1);
            });
        });
    },

    // 封装,解析字符串
    myparse: function (mystr) {
      var myparams = mystr;
      if (myparams == "") {
        myparams = null;
      }
      // 解析
      myparams = JSON.parse(myparams);

      return myparams;
    },

    // 修改视频
    newafterRead: function (file) {
      // 声明表单
      let data = new FormData();
      data.append("file", file.file);
      data.append("uid", localStorage.getItem("id"));
      data.append("id", localStorage.getItem("cid"));
      data.append("index", this.video_index);
      const myaxios = this.axios.create({ withCredentials: false });
      myaxios({
        method: "post",
        url: "http://localhost:5000/updatavideo/",
        data: data,
      }).then((result) => {
        if (result.data.code == 200) {
          //视频替换
          this.srcs[this.video_index] = result.data.filename;
          this.$toast.success(result.data.msg);
        } else {
          this.$toast.fail(result.data.msg);
        }
      });
    },

    //选集
    play: function (src, index) {
      this.src = this.upload_dir + src;
      this.src = src;
      this.video_index = index;
    },

    // 获取我的视频
    get_video() {
      //发送请求
      this.axios
        .get("http://localhost:5000/mycourse/", {
          params: {
            id: localStorage.getItem("id"),
            cid: localStorage.getItem("cid"),
            token: localStorage.getItem("token"),
          },
        })
        .then((result) => {
          // 解析
          this.srcs = this.myparse(result.data.video);
        });
    },

    // 修改
    editcourse: function () {
      var lists = [];

      //遍历取值
      for (var key in this.info) {
        lists.push({
          key: key,
          value: this.info[key],
          label: this.params[key],
        });
      }

      //序列化操作
      var lists_str = JSON.stringify(lists);

      var data_post = {
        fid: this.fid,
        title: this.title,
        desc: this.desc,
        id: localStorage.getItem("cid"),
      };

      //判断是否有特需参数
      if (lists.length > 0) {
        var data_post = {
          fid: this.fid,
          title: this.title,
          desc: this.desc,
          id: localStorage.getItem("cid"),
          params: lists_str,
        };
      }

      //发送请求
      this.axios
        .put(
          "http://localhost:5000/modifycourse/",
          this.qs.stringify(data_post)
        )
        .then((result) => {
          console.log(result);

          if (result.data.code == 200) {
            this.$toast.success("课程修改成功");
          } else {
            this.$toast.fail(result.data.msg);
          }
        });
    },

    //获取课程分类
    get_cate: function (fid) {
      //判断展示表单
      if (fid === localStorage.getItem("cateid")) {
        //选择的分类和默认课程的分类,一致,展示课程回填表单
        this.show_course = true;
        this.show_cate = false;
      } else {
        this.show_course = false;
        this.show_cate = true;
      }

      //发送请求
      this.axios
        .get("http://localhost:5000/getcate/", { params: { fid: fid } })
        .then((result) => {
          // 解析
          this.params_cate = this.myparse(result.data.params);

          //动态生成data对应表单变量

          for (var key in this.params_cate) {
            //动态声明
            this.$set(this.info_cate, key, "");
          }
        });
    },

    //获取分类数据递归展示数据
    get_data: function () {
      this.axios.get("http://localhost:5000/catelist/").then((result) => {
        //声明根节点
        var mytree = { id: 0, name: "" };
        mytree["children"] = result.data;
        this.mydata = mytree;

        //获取课程详情
        this.axios
          .get("http://localhost:5000/getcourse/", {
            params: {
              fid: this.cid,
              token: localStorage.getItem("token"),
            },
          })
          .then((result) => {
            //赋值操作
            this.title = result.data.title;
            this.desc = result.data.desc;
            this.fid = result.data.cid;
            // 课程分类id
            localStorage.setItem("cateid", this.fid);

            this.params = this.myparse(result.data.params);
            // 生产动态data对应表单遍历
            if (this.params != null) {
              for (let i = 0; i < this.params.length; i++) {
                // 动态声明
                this.$set(
                  this.info,
                  this.params[i]["key"],
                  this.params[i]["value"]
                );
              }
            }
          });
      });
    },

    // 多视频上传
    afterRead_list: function (file) {
      //  遍历文文件列表
      for (let i = 0; i <= file.length; i++) {
        this.afterRead(file[i]);
      }
    },

    // 上传视频方法
    afterRead: function (file) {
      // 声明表单
      let data = new FormData();
      data.append("file", file.file);
      data.append("id", localStorage.getItem("id"));
      data.append("cid", localStorage.getItem("cid"));
      data.append("type", 1);
      const myaxios = this.axios.create({ withCredentials: false });
      myaxios({
        method: "post",
        url: "http://localhost:5000/upload/",
        data: data,
      }).then((result) => {
        if (result.data.code == 200) {
          //将地址添加到视频地址列表中
          this.srcs.push(result.data.filename);
          this.$toast.success(result.data.msg);
        } else {
          this.$toast.fail(result.data.msg);
        }
      });
    },
  },
  mounted() {
    this.cid = this.$route.query.fid; //课程id
    localStorage.setItem("cid", this.cid);
    this.get_data();
    this.get_video();
  },
  created() {
    // 监听
    bus.$on("msg", (target) => {
      this.fid = target;
      this.get_cate(target);
    });
  },
};
</script>

<style scoped>
ul {
  padding-left: 10rem;
  list-style: none;
}
</style>

标签:vue,树结构,params,result,fid,组件,localStorage,data,id
来源: https://blog.csdn.net/weixin_56482316/article/details/120873310