vue extend 的基本使用
vue.extend 局部注册 的应用2

请注意,extend创建的是一个组件构造器,而不是一个具体的组件实例。所以他不能直接在new Vue中这样使用: new Vue({components: fuck})

最终还是要通过Vue.components注册才可以使用的。

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>在Vue中注册组件</title>
</head>
<body>
<div id="app">
    <todo :todo-data="groceryList"></todo>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue " type="text/javascript"></script>
<script>
/**
 * 请注意,extend创建的是一个组件构造器,而不是一个具体的组件实例。
 * 所以他不能直接在new Vue中这样使用: new Vue({components: fuck})
 * 最终还是要通过Vue.components注册才可以使用的。 
 */

// 构建一个子组件
var todoItem = Vue.extend({
    template: ` <li> {{ text }} </li> `,
    props: {
        text: {
            type: String,
            default: ''
        }
    }
})

// 构建一个父组件
var todoWarp = Vue.extend({
    template: `
        <ul>
            <todo-item 
                v-for="(item, index) in todoData"
                v-text="item.text"
            ></todo-item>
        </ul>
    `,
    props: {
      todoData: {
          type: Array,
          default: []
      }
    },
    // 局部注册子组件
    components: {
        todoItem: todoItem
    }
})

// 注册到全局
Vue.component('todo', todoWarp)

new Vue({
    el: '#app',
    data: {
        groceryList: [
            { id: 0, text: '蔬菜' },
            { id: 1, text: '奶酪' },
            { id: 2, text: '随便其它什么人吃的东西' }
        ]
    }
})
</script>
</html>

54、vue.extend 局部注册 的应用1

请注意,在实例化extends组件构造器时,传入属性必须是propsData、而不是props哦

另外,无论是Vue.extend还是Vue.component 里面的data定义都必须是函数返回对象,如 Vue.extend({data: function () {return {}}})。除了new Vue可以直接对data设置对象之外吧,如 new Vue({data: {}});

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>在Vue中注册组件</title>
</head>
<body>
<div id="todoItem"></div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue" type="text/javascript"></script>
<script>

// 局部注册组件
var todoItem = Vue.extend({
  data: function () {
        return {
            todoData: [
              { id: 0, text: '蔬菜' },
              { id: 1, text: '奶酪' },
              { id: 2, text: '随便其它什么人吃的东西' }
            ]
        }
  },
  template: `
        <ul>
            <li v-for='(d, i) in todoData' :key="i">
                {{ d.text }}
            </li>
        </ul>
  `
});

// 请注意,在实例化extends组件构造器时,传入属性必须是propsData、而不是props哦
new todoItem({
  propsData: {
      todoData: [
          { id: 0, text: '蔬菜' },
          { id: 1, text: '奶酪' },
          { id: 2, text: '随便其它什么人吃的东西' }
      ]
  }
}).$mount('#todoItem')

</script>
</html>

转载:https://www.cnblogs.com/CyLee/p/8425191.html

组件使用


<template>
  <div class="report">
    <div class="report_head">
      <img class="doctor" :src="doc" alt />
      <ul class="doc_text" :style="{backgroundImage:'url('+doc_text+')'}">
        <li class="doc_text_head">Hi! {{name}}:</li>
        <li class="doc_text_content">我根据深圳中国科技研究院模型帮您一起达成目标,跟着营养师走,让你健康瘦.</li>
      </ul>
    </div>
    <div class="report_content">
      <ul class="report_title">
        <li
          class="report_title_li"
          v-for="(item,index) in ringList.labels"
          :key="index"
          :style="{backgroundImage:'url('+ title+')'}"
        >
          <p v-html="line(item)"></p>
        </li>
      </ul>
      <ul class="report_des">
        <li class="report_des_head">
          <img class="report_des_icon" :src="diet_plan" alt /> 减脂饮食计划
        </li>
        <li class="report_des_text">{{ringList.detailIntro}}</li>
      </ul>
      <ul class="report_des diet">
        <li class="report_des_head diet_head">
          <div>
            <img class="report_des_icon" :src="fat" alt /> 饮食方案
          </div>
          <div class="diet_head_right">每日:{{total}}千卡</div>
        </li>
        <li class="diet_echarts">
          <div id="diet_echarts_loop"></div>
          <div class="diet_echarts_right">
            <div
              class="diet_echarts_right_content"
              v-for="(item,index) in ringList.nutriMap"
              :key="index"
            >
              <div class="diet_echarts_right_content_left">{{index}}</div>
              <div class="diet_echarts_right_content_middle">{{item}}</div>
              <div
                class="diet_echarts_right_content_right"
                :style="{backgroundColor:color(index)}"
              >{{precnt(item)}}</div>
              <div
                class="diet_echarts_right_content_radius"
                :style="{backgroundColor:color(index)}"
              ></div>
            </div>
          </div>
        </li>
      </ul>
      <ul class="report_des diet food">
        <li class="report_des_head diet_head diet_head_food">
          <div>
            <img class="report_des_icon" :src="recent" alt /> 每日食单
          </div>
        </li>
        <!-- v-for="(item,index) in recentlsit" :key="index" -->
        <li class="report_des_food">
          <div class="report_des_food_head">
            <p
              class="report_des_food_head_ol"
              :class="{active:i==index}"
              v-for="(item,i) in [0,1,2,3,4,5,6]"
              @click="changed(i)"
            >
              <span>DAY0{{item+1}}</span>
            </p>
          </div>
          <turn
            :width="turnwidth"
            :height="turnheight"
            ref="turn"
            @change="changeCurrent"
            :data="recentlsit"
          ></turn>
        </li>
      </ul>
    </div>
    <div class="report_food">
      <p @click="again">
        <!-- 换个计划,重新测评 -->
        开始计划
        <!-- <span class="iconfont icon-refresh"></span> -->
      </p>
    </div>
    <div id="edituser" :style="userH"></div>
  </div>
</template>

<script>
import Vue from "vue";
import echarts from "echarts";
import turn from "vue-flip-page";
import html2canvas from "html2canvas";
import question from "@/components/question/index.js";
let doc = require("@/assets/image/question/doctor.png");
let doc_text = require("@/assets/image/question/doctor-text.png");
let title = require("@/assets/image/question/title.png");
let fat = require("@/assets/image/question/fat.png");
let diet_plan = require("@/assets/image/question/diet_plan.png");
let recent = require("@/assets/image/question/recent.png");
let a = require("@/assets/image/question/01.png");
let b = require("@/assets/image/question/02.png");
let c = require("@/assets/image/question/03.png");
let d = require("@/assets/image/question/04.png");
let e = require("@/assets/image/question/05.png");
let f = require("@/assets/image/question/06.png");
let g = require("@/assets/image/question/07.png");
let dir = document.documentElement.clientWidth / 375;
export default {
  data() {
    return {
      doc: doc,
      doc_text: doc_text,
      title: title,
      fat: fat,
      diet_plan: diet_plan,
      recent: recent,
      // 环装图
      mySector: null,
      ringList: {},
      recentlsit: [
        { picture_image: "" },
        { picture_image: "" },
        { picture_image: "" },
        { picture_image: "" },
        { picture_image: "" },
        { picture_image: "" },
        { picture_image: "" }
      ],
      turnwidth: 316 * dir,
      turnheight: 186 * dir,
      userH: 200 * dir,
      index: 0,
      params: {
        type: 1
      }
    };
  },
  computed: {
    // 姓名
    name() {
      return (
        this.ringList &&
        this.ringList.personalInfo &&
        this.ringList.personalInfo.realName
      );
    },
    total() {
      let obj = {
        碳水化合物: 4,
        脂肪: 9,
        蛋白质: 4,
        color: function(val) {
          return this[val];
        }
      };
      let objlist = this.ringList.nutriMap;
      let value = 0;
      for (let key in objlist) {
        value += objlist[key] * obj.color(key);
      }
      return value;
    }
  },
  filters: {
    // 标题好
    // oindex(val) {
    //   return val > 9 ? val : "0" + (val + 1);
    // }
  },
  components: {
    turn
  },
  methods: {
    // 标题换行
    line(val) {
      if (!!val) {
        // return val.trim();
        if (val.length < 6) {
          return val;
        } else {
          return val.substring(0, 3) + "<br>" + val.substring(3);
        }
      }
    },
    // 环装图
    ringlist(data) {
      this.mySector.setOption(
        {
          series: [
            {
              name: "访问来源",
              type: "pie",
              radius: ["50%", "70%"],
              avoidLabelOverlap: false,
              labelLine: {
                show: false
              },
              data: data
            }
          ]
        },
        true
      );
    },
    // 数据
    ringpage() {
      this.$http
        .request({
          method: "get",
          url: "ajax/web/nutri/project/detail",
          params: this.params
        })
        .then(res => {
          if (res && res.respBody) {
            this.$store.commit("setDataLoading", true);
            // 数据赋值
            this.ringList = res.respBody;
            // 饼状图
            let data = [];
            var placeHolderStyle = {
              normal: {
                label: {
                  show: false
                },
                labelLine: {
                  show: false
                },
                color: "rgba(0, 0, 0, 0)",
                borderColor: "rgba(0, 0, 0, 0)",
                borderWidth: 0
              }
            };
            for (let key in res.respBody.nutriMap) {
              data.push(
                {
                  value: res.respBody.nutriMap[key],
                  name: [key],
                  itemStyle: { color: this.color(key) }
                },
                {
                  value: 2,
                  name: "",
                  itemStyle: placeHolderStyle
                }
              );
            }
            console.log(
              res.respBody.dietPlanVO.diets,
              "res.respBody.dietPlanVO.diets"
            );
            let arr = [],
              breakfast = "breakfast",
              lunch = "lunch",
              supper = "supper";
            res.respBody.dietPlanVO.diets.forEach(element => {
              arr.push({
                [breakfast]: element[breakfast].food,
                [lunch]: element[lunch].food,
                [supper]: element[supper].food
              });
            });
            this.ringlist(data);
            let oarr = [],
              i = 0;
            let cyclic = (arr, i) => {
              let img = question.trans(arr[i], i);
              img.domimg(url => {
                oarr.push(url);
                ++i;
                if (i > arr.length - 1) {
                  let axx = this.recentlsit.map((item, index) => {
                    item.picture_image = oarr[index];
                    return item;
                  });
                  this.recentlsit = axx;
                  document.getElementById("edituser").style.display = "none";
                  this.$store.commit("setDataLoading", false);
                  return;
                } else {
                  cyclic(arr, i);
                }
              });
            };
            cyclic(arr, i);
          }
        });
    },
    color(key) {
      let obj = {
        碳水化合物: "#F591A5",
        脂肪: "#FFD197",
        蛋白质: "#95D1FF",
        color: function(val) {
          return this[val];
        }
      };
      return obj.color(key);
    },
    // 百分比
    precnt(val) {
      let total = Object.values(this.ringList.nutriMap).reduce(
        (curent, item, index) => {
          return (curent += item);
        }
      );
      return (val / total).toFixed(3) * 100 + "%";
    },
    // 重新提交
    again() {
      this.$http
        .request({
          method: "post",
          url:
            "ajax/web/nutri/project/createHealthProject?type=" +
            this.params.type
        })
        .then(res => {
          console.log(res, "res");
          if (!res.success && res.respStatus == 0) {
             if (this.$util.isApp()) {
              app.goApp("com.ysch.platform.healthy.ui.MainActivityEx");
            }
          } else {
            if (this.$util.isApp()) {
              app.goApp("com.ysch.platform.healthy.ui.DietaryManagerActivity");
            }
          }
        });
    },
    // 变化
    changed(i) {
      if (i == this.index) {
        return;
      }
      this.index = i;
      this.$refs["turn"].toPage(i);
    },
    changeCurrent(index) {
      if (index == this.index) {
        return;
      }
      this.index = index;
    }
  },
  created() {
    Object.assign(this.params, this.$route.query);
  },
  mounted() {
    // 扇形图
    this.mySector = echarts.init(document.getElementById("diet_echarts_loop"));

    // 监听数据(扇形图,地图)
    window.addEventListener("resize", () => {
      this.mySector.resize();
    });

    this.ringpage();
  }
};
</script>

<style lang='scss' scoped>
@import "src/style/mixin";
.report {
  .report_head {
    position: relative;
    height: rem(330);
    .doctor {
      position: absolute;
      left: rem(74);
      top: rem(32);
      width: rem(164);
      height: rem(274);
    }
    .doc_text {
      position: absolute;
      left: rem(222);
      top: rem(130);
      width: rem(462);
      height: rem(160);
      background-size: cover;
      background-repeat: no-repeat;
      padding: 0 rem(8) 0 rem(56);
      box-sizing: border-box;
      color: #383637;
      .doc_text_head {
        height: rem(50);
        line-height: rem(50);
        font-size: rem(12);
      }
      .doc_text_content {
        line-height: rem(28);
        font-size: rem(14);
        letter-spacing: rem(4);
        // color: #383637;
      }
    }
  }
  .report_content {
    padding: 0 rem(36);
    .report_title {
      display: flex;
      justify-content: space-around;
      height: rem(108);
      color: #4b4a4a;
      .report_title_li {
        width: rem(86);
        height: rem(94);
        background-size: cover;
        background-repeat: no-repeat;
        // line-height: rem(94);
        text-align: center;
        display: inline-flex;
        flex-wrap: wrap;
        align-items: center;
        font-size: rem(20);

        & > p {
          width: 100%;
          font-size: rem(20);
        }
      }
    }
    .report_des {
      // height: rem(254);
      padding: 0 rem(20) rem(20) rem(20);
      background-color: #edfbfd;
      border-radius: rem(12);
      margin-bottom: rem(34);
      &.diet {
        background-color: #f3f3f3;
        .report_des_food {
          height: rem(480);
          .report_des_food_head {
            display: flex;
            align-items: center;
            justify-content: space-between;
            height: rem(140);
            .report_des_food_head_ol {
              &.active {
                background-color: #95d1ff;
              }
              width: rem(60);
              height: rem(60);
              font-size: rem(12);
              background-color: #f3f3f3;
              color: #010101;
              display: inline-flex;
              align-items: center;
              justify-content: center;
              border-radius: 50%;
              & > span {
                transform: scale(0.6);
              }
            }
          }
        }
      }
      &.food {
        background-color: #fff;
      }
      .report_des_head {
        font-size: rem(28);
        height: rem(80);
        // text-align: center;
        // line-height: rem(80);
        display: flex;
        align-items: center;
        justify-content: center;
        letter-spacing: rem(2);
        &.diet_head {
          height: rem(124);
          justify-content: space-between;
          &.diet_head_food {
            height: rem(90);
          }
          .diet_head_right {
            font-size: rem(26);
            color: #666;
            letter-spacing: rem(2);
          }
        }
        .report_des_icon {
          width: rem(34);
          height: rem(34);
          margin-right: rem(4);
          // vertical-align: middle;
        }
      }
      .report_des_text {
        font-size: rem(20);
        color: #898b8d;
        line-height: rem(34);
      }
      .diet_echarts {
        display: flex;
        justify-content: space-between;
        align-items: center;
        height: rem(218);
        #diet_echarts_loop {
          width: rem(210);
          height: rem(210);
          // border-radius: 50%;
          // border: rem(10) solid #f00;
        }
        .diet_echarts_right {
          height: rem(166);
          // width: rem(350);
          .diet_echarts_right_content {
            height: rem(40);
            width: 100%;
            display: flex;
            align-items: center;
            justify-content: center;
            text-align: center;
            font-size: rem(20);
            margin-bottom: rem(20);
            color: #fff7f9;
            .diet_echarts_right_content_left {
              width: rem(134);
              height: 100%;
              background-color: #60bbdb;
            }
            .diet_echarts_right_content_middle {
              width: rem(124);
              height: 100%;
              background-color: #ffffff;
              color: #29abe4;
            }
            .diet_echarts_right_content_right {
              width: rem(92);
              height: 100%;
              background-color: #f591a5;
              border: rem(6) solid #ffffff;
              border-right: 0;
              display: flex;
              justify-content: flex-end;
              align-items: center;
            }
            .diet_echarts_right_content_radius {
              width: rem(24);
              height: 100%;
              background-color: #f591a5;
              border-radius: 0 50% 50% 0;
              border: rem(6) solid #ffffff;
              border-left: 0;
            }
          }
        }
      }
    }
  }
  .report_food {
    color: #a8e7ff;
    height: rem(186);
    display: flex;
    align-items: center;
    justify-content: center;
    & > p {
      //  text-decoration: underline;
      display: inline-block;
      border-bottom: rem(2) solid #a8e7ff;
      .icon-refresh {
        font-size: rem(18);
        margin-left: rem(12);
      }
    }
  }
}
</style>

extend

//index.js"

import Vue from "vue";
import index from "./index.vue";

const MyComponent = Vue.extend(index);
index.trans = function (itemlist, i) {
  let data = {
    itemlist,
    i,
  };
  var component = new MyComponent({ data }).$mount();
  let dom=document.getElementById("edituser")
  if(i!=0){
    dom.replaceChild(component.$el,dom.children[0]);
  }else{
    dom.appendChild(component.$el);
  }

  // return component.aa
  return component;
};

export default index;
//index.vue";
<template>
  <div ref="dom" class="food_content" :style="{backgroundImage:'url('+imglsit[i]+')'}">
    <div class="food_line" v-for="(item,index) in itemlist" :key="index">
      <img class="food_icon" :src="food_iconlist[1]" />
      {{index|type}}:{{item|con}}
    </div>
  </div>
</template>

<script>
import html2canvas from "html2canvas";
let a = require("@/assets/image/question/01.png");
let b = require("@/assets/image/question/02.png");
let c = require("@/assets/image/question/03.png");
let d = require("@/assets/image/question/04.png");
let e = require("@/assets/image/question/05.png");
let f = require("@/assets/image/question/06.png");
let g = require("@/assets/image/question/07.png");
let food_icon1 = require("@/assets/image/question/food_icon1.png");
let food_icon2 = require("@/assets/image/question/food_icon2.png");
let food_icon3 = require("@/assets/image/question/food_icon3.png");
export default {
  data() {
    return {
      imglsit: [a, b, c, d, e, f, g],
      food_iconlist: [food_icon1,food_icon2,food_icon3]
    };
  },
  filters: {
    type(value) {
      let obj = {
        breakfast: "早餐",
        lunch: "午餐",
        supper: "晚餐",
        type: function(value) {
          return this[value];
        }
      };
      return obj.type(value);
    },
    con(value) {
      let arr = [],
        str = "";
      value.forEach((item, index) => {
        arr.push(item.name);
      });
      str = arr.join("+");
      return str.length > 16 ? str.slice(0, str.lastIndexOf("+")) : str;
    }
  },
  computed: {},
  methods: {
    domimg(callback) {
      this.$nextTick(() => {
        let dom = this.$refs.dom;
        html2canvas(dom, {
          width: dom.offsetWidth,
          height: dom.offsetHeight,
          scale: 1,
          useCORS: true,
          async: true,
          allowTaint: true,
          taintTest: false,
          windowWidth:375,
          windowHeight:1000
        }).then(canvas => {
          let url = canvas.toDataURL("image/png", 1);
          callback(url)
        });
      });
    }
  },
  updated() {
   this.aa()
  }
};
</script>

<style lang='scss' scoped>
@import "src/style/mixin";
.food_content {
  width: 100%;
  height: 100%;
  padding: rem(136) rem(32) 0;
  background-size: cover;
  background-repeat: no-repeat;
  background-position: center;
  .food_line {
    font-size: rem(28);
    font-weight: 550;
    display: inline-flex;
    align-items: center;
    flex-wrap: wrap;
    margin-bottom: rem(40);

    .food_icon {
      width: rem(42);
      height: rem(42);
      margin-right: rem(18);
    }
  }
}
</style>

Logo

前往低代码交流专区

更多推荐