【问题标题】:What's wrong with my Vue "wheel.vue" component? When it renders to html, It appears empty?我的 Vue“wheel.vue”组件有什么问题?当它呈现为 html 时,它显示为空?
【发布时间】:2020-12-24 17:12:22
【问题描述】:

我期待一个像这里 (http://bl.ocks.org/jrue/a2aaf36b3c096925ccbf) 一样的轮子,但组件的内容似乎是空的。

我用谷歌搜索,发现了几个关于组件不渲染的类似问题,但似乎没有一个能解决我的问题。

我正在尝试创建一个轮子组件(使用 Vue 2.6)。

我知道如何创建一个基本的 vue 组件,也知道如何将该组件导入 App.vue,所以我不明白为什么我的代码不起作用。

下面的第一张图显示了 vue 应用程序运行时,标签在那里,但轮子在哪里? 下面的第二张图片显示了 id="chart" 和 id="question" 的元素,但它们似乎是空的。

下面是我的 Wheel.vue 和 App.vue 的代码。

//Wheel.vue
<template>
    <div class="wheelclass">
        <div id="chart">seeme</div>
        <div id="question"></div>
    </div>
</template>

<script type="text/javascript" charset="utf-8">
export default {
    name: "wheel",
    data() {
        return {};
    },
    created() {
        let myscript = document.createElement("script");
        myscript.setAttribute("src", "https://d3js.org/d3.v3.min.js");
        document.head.appendChild(myscript);
    },
};

//begin code for wheel
var padding = { top: 20, right: 40, bottom: 0, left: 0 },
    w = 500 - padding.left - padding.right,
    h = 500 - padding.top - padding.bottom,
    r = Math.min(w, h) / 2,
    rotation = 0,
    oldrotation = 0,
    picked = 100000,
    oldpick = [],
    color = d3.scale.category20(); //category20c()
//randomNumbers = getRandomNumbers();

 var data = [
                    {"label":"Question 1",  "value":1,  "question":"What CSS property is used for specifying the area between the content and its border?"}, // padding
                    {"label":"Question 2",  "value":1,  "question":"What CSS property is used for changing the font?"}, //font-family
                    {"label":"Question 3",  "value":1,  "question":"What CSS property is used for changing the color of text?"}, //color
                    {"label":"Question 4",  "value":1,  "question":"What CSS property is used for changing the boldness of text?"}, //font-weight
                    {"label":"Question 5",  "value":1,  "question":"What CSS property is used for changing the size of text?"}, //font-size
                    {"label":"Question 6",  "value":1,  "question":"What CSS property is used for changing the background color of a box?"}, //background-color
                    {"label":"Question 7",  "value":1,  "question":"Which word is used for specifying an HTML tag that is inside another tag?"}, //nesting
                    {"label":"Question 8",  "value":1,  "question":"Which side of the box is the third number in: margin:1px 1px 1px 1px; ?"}, //bottom
                    {"label":"Question 9",  "value":1,  "question":"What are the fonts that don't have serifs at the ends of letters called?"}, //sans-serif
                    {"label":"Question 10", "value":1, "question":"With CSS selectors, what character prefix should one use to specify a class?"}, //period
                    {"label":"Question 11", "value":1, "question":"With CSS selectors, what character prefix should one use to specify an ID?"}, //pound sign
                    {"label":"Question 12", "value":1, "question":"In an HTML document, which tag holds all of the content people see?"}, //<body>
                    {"label":"Question 13", "value":1, "question":"In an HTML document, which tag indicates an unordered list?"}, //<ul>
                    {"label":"Question 14", "value":1, "question":"In an HTML document, which tag indicates the most important heading of your document?"}, //<h1>
                    {"label":"Question 15", "value":1, "question":"What CSS property is used for specifying the area outside a box?"}, //margin
                    {"label":"Question 16", "value":1, "question":"What type of bracket is used for HTML tags?"}, //< >
                    {"label":"Question 17", "value":1, "question":"What type of bracket is used for CSS rules?"}, // { }
                    {"label":"Question 18", "value":1, "question":"Which HTML tag is used for specifying a paragraph?"}, //<p>
                    {"label":"Question 19", "value":1, "question":"What should always be the very first line of code in your HTML?"}, //<!DOCTYPE html>
                    {"label":"Question 20", "value":1, "question":"What HTML tag holds all of the metadata tags for your page?"}, //<head>
                    {"label":"Question 21", "value":1, "question":"In CSS, what character separates a property from a value?"}, // colon
                    {"label":"Question 22", "value":1, "question":"What HTML tag holds all of your CSS code?"}, // <style>
                    {"label":"Question 23", "value":1, "question":"What file extension should you use for your web pages?"}, // .html
                    {"label":"Question 24", "value":1, "question":"Which coding language is used for marking up content and structure on a web page?"}, // HTML
                    {"label":"Question 25", "value":1, "question":"Which coding language is used for specifying the design of a web page?"}, // CSS
                    {"label":"Question 26", "value":1, "question":"Which coding language is used for adding functionality to a web page?"}, // JavaScript
                    {"label":"Question 27", "value":1, "question":"What CSS property is used for making the edges of a box visible?"}, // border
                    {"label":"Question 28", "value":1, "question":"What character symbol is used at the end of each CSS statement?"},//semi-colon
                    {"label":"Question 29", "value":1, "question":"By default, how wide is a <div> box?"}, //100%
                    {"label":"Question 30", "value":1, "question":"What character symbol do I use to specify multiple CSS selectors in one code block?"} //comma
        ];

var svg = d3
    .select("#chart")
    .append("svg")
    .data([data1])
    .attr("width", w + padding.left + padding.right)
    .attr("height", h + padding.top + padding.bottom);

var container = svg
    .append("g")
    .attr("class", "chartholder")
    .attr(
        "transform",
        "translate(" +
            (w / 2 + padding.left) +
            "," +
            (h / 2 + padding.top) +
            ")"
    );

var vis = container.append("g");

var pie = d3.layout
    .pie()
    .sort(null)
    .value(function (d) {
        return 1;
    });

// declare an arc generator function
var arc = d3.svg.arc().outerRadius(r);

// select paths, use arc generator to draw
var arcs = vis
    .selectAll("g.slice")
    .data(pie)
    .enter()
    .append("g")
    .attr("class", "slice");

arcs.append("path")
    .attr("fill", function (d, i) {
        return color(i);
    })
    .attr("d", function (d) {
        return arc(d);
    });

// add the text
arcs.append("text")
    .attr("transform", function (d) {
        d.innerRadius = 0;
        d.outerRadius = r;
        d.angle = (d.startAngle + d.endAngle) / 2;
        return (
            "rotate(" +
            ((d.angle * 180) / Math.PI - 90) +
            ")translate(" +
            (d.outerRadius - 10) +
            ")"
        );
    })
    .attr("text-anchor", "end")
    .text(function (d, i) {
        return data1[i].label;
    });

container.on("click", spin);

function spin(d) {
    container.on("click", null);

    //all slices have been seen, all done
    console.log("OldPick: " + oldpick.length, "Data length: " + data1.length);
    if (oldpick.length == data1.length) {
        console.log("done");
        container.on("click", null);
        return;
    }

    var ps = 360 / data1.length,
        pieslice = Math.round(1440 / data1.length),
        rng = Math.floor(Math.random() * 1440 + 360);

    rotation = Math.round(rng / ps) * ps;

    picked = Math.round(data1.length - (rotation % 360) / ps);
    picked = picked >= data1.length ? picked % data1.length : picked;

    if (oldpick.indexOf(picked) !== -1) {
        d3.select(this).call(spin);
        return;
    } else {
        oldpick.push(picked);
    }

    rotation += 90 - Math.round(ps / 2);

    vis.transition()
        .duration(3000)
        .attrTween("transform", rotTween)
        .each("end", function () {
            //mark question as seen
            d3.select(".slice:nth-child(" + (picked + 1) + ") path").attr(
                "fill",
                "#111"
            );

            //populate question
            d3.select("#question h1").text(data1[picked].question);

            oldrotation = rotation;

            container.on("click", spin);
        });
}

//make arrow
svg.append("g")
    .attr(
        "transform",
        "translate(" +
            (w + padding.left + padding.right) +
            "," +
            (h / 2 + padding.top) +
            ")"
    )
    .append("path")
    .attr("d", "M-" + r * 0.15 + ",0L0," + r * 0.05 + "L0,-" + r * 0.05 + "Z")
    .style({ fill: "black" });

//draw spin circle
container
    .append("circle")
    .attr("cx", 0)
    .attr("cy", 0)
    .attr("r", 60)
    .style({ fill: "white", cursor: "pointer" });

//spin text
container
    .append("text")
    .attr("x", 0)
    .attr("y", 15)
    .attr("text-anchor", "middle")
    .text("SPIN")
    .style({ "font-weight": "bold", "font-size": "30px" });

function rotTween(to) {
    var i = d3.interpolate(oldrotation % 360, rotation);
    return function (t) {
        return "rotate(" + i(t) + ")";
    };
}

function getRandomNumbers() {
    var array = new Uint16Array(1000);
    var scale = d3.scale.linear().range([360, 1440]).domain([0, 100000]);

    if (
        window.hasOwnProperty("crypto") &&
        typeof window.crypto.getRandomValues === "function"
    ) {
        window.crypto.getRandomValues(array);
        console.log("works");
    } else {
        //no support for crypto, get crappy random numbers
        for (var i = 0; i < 1000; i++) {
            array[i] = Math.floor(Math.random() * 100000) + 1;
        }
    }

    return array;
}
//end code for wheel
</script>

<style type="text/css" scoped>
text {
    font-family: Helvetica, Arial, sans-serif;
    font-size: 11px;
    pointer-events: none;
}
#chart {
    position: absolute;
    width: 500px;
    height: 500px;
    top: 0;
    left: 0;
}
#question {
    position: absolute;
    width: 400px;
    height: 500px;
    top: 0;
    left: 520px;
}
#question h1 {
    font-size: 50px;
    font-weight: bold;
    font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
    position: absolute;
    padding: 0;
    margin: 0;
    top: 50%;
    -webkit-transform: translate(0, -50%);
    transform: translate(0, -50%);
}
</style>
//App.vue

<template>
  <div id="app">
    <img alt="Vue logo" src="./assets/logo.png">
    <HelloWorld msg="Welcome to Your Vue.js App"/>
    <Wheel></Wheel>
  </div>
</template>

<script>
import HelloWorld from './components/HelloWorld.vue'
import Wheel from './components/Wheel.vue'

export default {
  name: 'App',
  components: {
    HelloWorld,
    Wheel
  }
}
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

【问题讨论】:

  • 您是否注意到您的 wheel 代码超出了导出语句?当你没有调用它们时,你想如何渲染它们?

标签: vue.js components


【解决方案1】:

正如@Mohsen 在他/她的评论中所说,您的逻辑代码在导出语句之外。 准确地说,它应该在一个挂载的钩子中,这样你就可以确定 HTML 已经准备好了。

您还应该等待 d3 准备好,以便您的代码变为:

<script type="text/javascript" charset="utf-8">
export default {
    name: "wheel",
    data() {
        return {};
    },
    mounted() { // changed to mounted because we need the HTML to be ready
        let myscript = document.createElement("script");
        myscript.setAttribute("src", "https://d3js.org/d3.v3.min.js");
        document.head.appendChild(myscript);

        // wait for library to be loaed before executing your code
        // don't worry it will keep instance's context
        // Vue automatically bind all methods to the instance
        myscript.onload = this.startWheelCode;
    },
    methods: {
      startWheelCode() { /* your wheel code here */ }
    }
};

【讨论】:

  • 谢谢@darkylmnx。虽然我的解决方案修复了它,但您的答案似乎更完整。我编辑了我的修复程序,使其更像你的答案。
【解决方案2】:

谢谢你,@Mohsen。以下修复了它。我将所有轮子代码放入默认导出中名为 createWheel() 的方法中,然后从“已创建”生命周期挂钩中调用 createWheel()。

【讨论】:

    猜你喜欢
    • 2021-05-07
    • 2018-10-21
    • 2020-06-22
    • 1970-01-01
    • 1970-01-01
    • 2017-10-13
    • 1970-01-01
    • 1970-01-01
    • 2021-03-03
    相关资源
    最近更新 更多