ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2021-10-20 20:01:37  阅读:398  来源: 互联网

标签:vue 树结构 params result fid 组件 localStorage data id


 

  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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有