echarts实现3d柱状图的两种方式

news2025/7/15 16:59:00

echarts实现3d柱状图的两种方式

看了不少关于3d柱状图的案例,发现做3d柱状图 常用的两种方式就是 自定义图形和象型柱图, 两种实现方式效果如下:
在这里插入图片描述

方法1: echarts.graphic.extendShape 自定义图形

echarts自定义图形的详细用法点这里, 官网点这里, 图中第一个3d柱状图我参考的案例在这里, 看了很多 echarts这种3d案例, 自定义图形做3d柱状图,貌似只能有个柱子(可能 能做双柱,但是 我真的不会)

封装成组件的完整代码如下:

<template></template>

<script setup lang="ts">
import { nextTick, watch } from 'vue';
import echarts from '@/assets/ts/echarts';
import useResizeChart from '@/hooks/useResizeChart';

function mergeConfig(defaultConfig: object, config: object) {
    return Object.assign(defaultConfig, config);
}
function initOption(): echarts.EChartsCoreOption {
    // 绘制左侧面
    const CubeLeft = echarts.graphic.extendShape({
        shape: {
            x: 0,
            y: 0,
        },
        buildPath: function (ctx, shape) {
            // 会canvas的应该都能看得懂,shape是从custom传入的
            const xAxisPoint = shape.xAxisPoint;
            const c0 = [shape.x + 3.5, shape.y];
            const c1 = [shape.x - 11.5, shape.y - 3];
            const c2 = [xAxisPoint[0] - 11.5, xAxisPoint[1] - 6.5];
            const c3 = [xAxisPoint[0] + 3.5, xAxisPoint[1]];
            ctx.moveTo(c0[0], c0[1])
                // @ts-ignore

                .lineTo(c1[0], c1[1])
                .lineTo(c2[0], c2[1])
                .lineTo(c3[0], c3[1])
                .closePath();
        },
    });
    // 绘制右侧面
    const CubeRight = echarts.graphic.extendShape({
        shape: {
            x: 0,
            y: 0,
        },
        buildPath: function (ctx, shape) {
            const xAxisPoint = shape.xAxisPoint;
            const c1 = [shape.x + 3, shape.y];
            const c2 = [xAxisPoint[0] + 3, xAxisPoint[1]];
            const c3 = [xAxisPoint[0] + 12, xAxisPoint[1] - 7];
            const c4 = [shape.x + 12, shape.y - 7];

            ctx.moveTo(c1[0], c1[1])
                // @ts-ignore

                .lineTo(c2[0], c2[1])
                .lineTo(c3[0], c3[1])
                .lineTo(c4[0], c4[1])
                .closePath();
        },
    });
    // 绘制顶面
    const CubeTop = echarts.graphic.extendShape({
        shape: {
            x: 0,
            y: 0,
        },
        buildPath: function (ctx, shape) {
            const c1 = [shape.x + 3.5, shape.y];
            const c2 = [shape.x + 12.5, shape.y - 7.5]; //右点
            const c3 = [shape.x - 2.5, shape.y - 10];
            const c4 = [shape.x - 11.5, shape.y - 3];

            ctx.moveTo(c1[0], c1[1])
                // @ts-ignore

                .lineTo(c2[0], c2[1])
                .lineTo(c3[0], c3[1])
                .lineTo(c4[0], c4[1])
                .closePath();
        },
    });
    // 注册三个面图形
    echarts.graphic.registerShape('CubeLeft', CubeLeft);
    echarts.graphic.registerShape('CubeRight', CubeRight);
    echarts.graphic.registerShape('CubeTop', CubeTop);
    const VALUE = props.value;

    const series = [
        {
            type: 'custom',
            renderItem: (params: any, api: any) => {
                let cubeLeftStyle = new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                    {
                        offset: 0,
                        // @ts-ignore
                        color: props.color[0],
                    },
                    {
                        offset: 1,
                        color: 'rgba(7, 20, 52,0.7)',
                    },
                ]);
                let cubeRightStyle = new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                    {
                        offset: 0,
                        color: 'rgba(7, 20, 52,1)',
                    },
                    {
                        offset: 1,
                        // @ts-ignore

                        color: props.color[0],
                    },
                ]);
                let cubeTopStyle = new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                    {
                        offset: 0,
                        // @ts-ignore
                        color: props.color[1] || props.color[0],
                    },
                ]);

                const location = api.coord([api.value(0), api.value(1)]);
                return {
                    type: 'group',
                    children: [
                        {
                            type: 'CubeLeft',
                            shape: {
                                api,
                                xValue: api.value(0),
                                yValue: api.value(1),
                                x: location[0],
                                y: location[1],
                                xAxisPoint: api.coord([api.value(0), 0]),
                            },
                            style: {
                                fill: cubeLeftStyle,
                            },
                        },
                        {
                            type: 'CubeRight',
                            shape: {
                                api,
                                xValue: api.value(0),
                                yValue: api.value(1),
                                x: location[0],
                                y: location[1],
                                xAxisPoint: api.coord([api.value(0), 0]),
                            },
                            style: {
                                fill: cubeRightStyle,
                            },
                        },
                        {
                            type: 'CubeTop',
                            shape: {
                                api,
                                xValue: api.value(0),
                                yValue: api.value(1),
                                x: location[0],
                                y: location[1],
                                xAxisPoint: api.coord([api.value(0), 0]),
                            },
                            style: {
                                fill: cubeTopStyle,
                            },
                        },
                    ],
                };
            },
            data: VALUE,
        },
        {
            type: 'bar',
            label: {
                show: true,
                position: 'top',
                fontSize: 14,
                color: props.color[0],
                offset: [2, -10],
            },
            itemStyle: {
                color: 'transparent',
            },
            tooltip: {},
            data: VALUE,
        },
    ];

    const title = mergeConfig(
        {
            text: '',
            textStyle: {
                color: props.color[0],
                fontWeight: '800',
                fontSize: 12,
            },
            left: '18px',
            top: '1%',
        },
        props.title,
    );

    const XAxisLine = mergeConfig(
        {
            show: false,
            lineStyle: {
                type: 'solid',
                width: 1,
                color: '#2c3954',
            },
        },
        props.XAxisLine,
    );

    const YAxisLine = mergeConfig(
        {
            show: false,
            lineStyle: {
                show: true,
                lineStyle: {
                    type: 'solid',
                    width: 1,
                },
            },
        },
        props.YAxisLine,
    );

    const legend = mergeConfig(
        {
            show: true,
            left: 'center',
            top: '95%',
            icon: 'circle',
            textStyle: {
                color: '#fff',
            },
        },
        props.legend,
    );

    const grid = mergeConfig(
        {
            left: '5%',
            right: '5%',
            top: '12%',
            bottom: '0%',
            containLabel: true,
        },
        props.grid,
    );

    const XSplitLine = mergeConfig(
        {
            show: false,
            lineStyle: {
                type: 'dashed',
                width: 1,
            },
        },
        props.XSplitLine,
    );

    // 纵坐标分割线配置
    const YSplitLine = mergeConfig(
        {
            // 是否显示
            // show: false,
            show: true,
            // 样式
            lineStyle: {
                color: '#13263e',
                type: 'solid',
                width: 1,
            },
        },
        props.YSplitLine,
    );

    const XAxisTick = mergeConfig(
        {
            show: false,
            length: 5,
            inside: true,
            alignWithLabel: true,
            lineStyle: {
                type: 'solid',
                width: 1,
            },
        },
        props.XAxisTick,
    );

    const YAxisTick = mergeConfig(
        {
            show: true,
            length: 5,
            inside: true,
            alignWithLabel: true,
            lineStyle: {
                color: '#13263e',
                type: 'solid',
                width: 1,
            },
        },
        props.YAxisTick,
    );

    let option: echarts.EChartsCoreOption = {
        title,
        tooltip: {
            show: false,
            // 指示器提示的坐标轴
            trigger: 'axis',
            // 阴影提示器
            axisPointer: {
                type: 'shadow',
                shadowStyle: {
                    shadowColor: '#2e3e51', // 设置阴影的颜色
                },
            },
            formatter: function (params: any) {
                const item = params[1];
                return item.name + ' : ' + item.value;
            },
            // 提示框背景颜色
            backgroundColor: '#122843',
            // 提示框边框颜色
            borderColor: '#42D1F1',
            // 提示框文本样式
            textStyle: {
                color: '#fff',
            },
        },
        legend: legend,
        grid: grid,
        xAxis: {
            type: 'category',
            // boundaryGap: false,
            data: props.xAxisData,
            axisLine: XAxisLine,
            splitLine: XSplitLine,
            axisTick: XAxisTick,
            axisLabel: {
                //x轴文字的配置
                show: true,
                color: '#fff',
                fontSize: 12,
                rotate: 30,
            },
        },
        yAxis: {
            type: 'value',
            name: props.yUnit,
            nameTextStyle: {
                color: '#fff',
                fontSize: 16,
            },
            axisLine: YAxisLine,
            splitLine: YSplitLine,
            axisTick: YAxisTick,
            axisLabel: {
                //y轴文字的配置
                color: '#fff',
                fontSize: 12,
            },
        },

        series,
    };
    option = Object.assign(option, props.config);
    return option;
}

const props = defineProps({
    pid: {
        type: String,
        required: true,
    },
    title: {
        type: Object,
        default: {},
    },
    xAxisData: {
        type: Array,
        required: true,
    },
    legend: {
        type: Object,
        default: {},
    },
    grid: {
        type: Object,
        default: {},
    },
    XAxisLine: {
        type: Object,
        default: {},
    },
    YAxisLine: {
        type: Object,
        default: {},
    },
    yUnit: {
        type: String,
        default: '',
    },
    XSplitLine: {
        type: Object,
        default: {},
    },
    YSplitLine: {
        type: Object,
        default: {},
    },
    XAxisTick: {
        type: Object,
        default: {},
    },
    YAxisTick: {
        type: Object,
        default: {},
    },
    config: {
        type: Object as () => echarts.EChartsCoreOption,
        default: {},
    },
    value: {
        type: Array,
        required: true,
    },
    // 柱子的颜色
    color: {
        type: Array,
        default: ['rgba(29, 230, 235,1)', 'rgba(7, 235, 251,1)'],
    },
});

let option = initOption();

let container: HTMLElement | null = null;
let myChart: echarts.ECharts | null = null;

const renderChart = (notMerge: boolean = false) => {
    if (!myChart) myChart = echarts.init(container as HTMLElement);
    myChart.setOption(option, {
        notMerge,
    });
};

nextTick(() => {
    container = document.querySelector('#' + props.pid) as HTMLElement;
    renderChart();
    useResizeChart(container, myChart as echarts.ECharts);
});

watch(
    () => props,
    (newVal, oldVal) => {
        let notMerge = true;
        option = initOption();
        renderChart(notMerge);
    },
    {
        deep: true,
    },
);

function exportImg() {
    const src = (myChart as echarts.ECharts).getDataURL({
        pixelRatio: 2,
        backgroundColor: '#08172A',
    });
    const a = document.createElement('a');
    a.href = src;
    a.download = (option.title as { text: string }).text || 'chart-img';
    a.click();
}

defineExpose({
    exportImg,
});
</script>

<style lang="scss" scoped></style>

方式2: 象型柱图(type: “pictorialBar”)

echarts象型柱图的官网配置项点这里, 参考的案例在这里, 象型柱图可以单柱可以双柱
封装成组件的完整代码如下:

<template></template>

<script setup lang="ts">
import { nextTick, watch } from "vue";
import echarts from "@/assets/ts/echarts";
import { LegendComponent } from "echarts/components";
echarts.use([LegendComponent]);
// 合并配置方法
function mergeConfig(defaultConfig: object, config: object) {
  return Object.assign(defaultConfig, config);
}

function initOption(): echarts.EChartsCoreOption {
  // 此时 使用组件只需要要将  zzx1的数据和 wgx1 的数据传递到子组件
  // 第一个柱子的值
  const zzx1 = props.series[0].data; // 实际值

  // 第二个柱子的值
  const wgx1 = props.series[1].data;


  // 变量: 改变每个柱子的大小, 后期可将其设置为动态的?
  const barWidth = 30;
  const series = [
    // (0)第一个柱子 中间的正方形
    {
      type: "pictorialBar", // 象型柱状
      symbol: "diamond",

      symbolSize: [barWidth, 5], // 调整大小
      // symbolOffset: [-13, -3], // 图形相对于原本位置的偏移
      symbolOffset: ["-55%", -3], // 图形相对于原本位置的偏移
      symbolPosition: "end",
      z: 12,
      color: "#2584e0",
      data: zzx1,
    },
    // (1)第二个柱子中间的正方形
    {
      type: "pictorialBar",
      symbol: "diamond",
      symbolSize: [barWidth, 8],
      // symbolOffset: [13, -3],
      symbolOffset: ["55%", -3],
      symbolPosition: "end",
      z: 12,
      color: "#07fdd3",
      data: wgx1,
    },
    //  (2)第一个柱子 底部的正方形
    {
      type: "pictorialBar",
      symbol: "diamond",
      symbolSize: [barWidth, 5],
      // symbolOffset: [-13, 3],
      symbolOffset: ["-55%", 3],
      z: 12,
      color: "#355ba8",
      data: zzx1,
    },
    // (3)第二个柱子 底部的正方形
    {
      name: "",
      type: "pictorialBar",
      symbol: "diamond",
      symbolSize: [barWidth, 5],
      // symbolOffset: [13, 3],
      symbolOffset: ["55%", 3],
      color: "#2095a3",
      z: 12,
      data: wgx1,
    },
    // (4)一个柱子, 下方有颜色填充的的柱子
    {
      name: props.nameOne,
      type: "bar",
      barWidth: barWidth,
      barGap: "10%",
      // zlevel: 2,
      stack: "1",
      itemStyle: {
        opacity: 0.7,
        color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
          {
            offset: 0.5,
            color: "rgba(44, 97, 188,0.7)",
            // color: '#2c61bc',
          },
          {
            offset: 0.5,
            color: "#2584e0",
          },
          {
            offset: 1,
            color: "#214a87",
          },
        ]),
        // barBorderRadius: 0,
        borderRadius: 0,
      },
      // 是否在每个柱子显示 相应的值
      label: {
        show: true,

        position: ["0", "-25"],
        color: "#005dd9",
        fontSize: 14,
        fontWeight:'bold'
      },
      data: zzx1,
    },
    // (5)第二个柱子, 下方有颜色填充的的柱子
    {
      name: props.nameTow,
      type: "bar",
      stack: "2",
      barWidth: barWidth,
      itemStyle: {
        opacity: 0.7,
        color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
          {
            offset: 0.5,
            color: "rgba(15, 182, 182,0.7)",
          },
          {
            offset: 0.5,
            color: "#0ccec7",
          },
          {
            offset: 1,
            color: "#0bddd0",
          },
        ]),
        // barBorderRadius: 0,
        borderRadius: 0,
      },
      // 是否在每个柱子显示 相应的值
      label: {
        show: true,
        position: ["0", "-25"],
        color: "#06e6f6",
        fontSize: 14,
        fontWeight:'bold'
      },
      data: wgx1,
    },
  ];

  // title 配置
  const title = mergeConfig(
    {
      // 是否显示
      show: true,
      // title 文本
      text: "",
      top: 0,
      left: "left",
      // 文字样式
      textStyle: {
        color: "#fff",
        fontSize: 16,
      },
    },
    props.title
  );

  // 横坐标轴线配置
  const XAxisLine = mergeConfig(
    {
      // 是否显示
      show: true,
      // show: false,
      // 样式
      lineStyle: {
        // color: "rgba(46, 60, 87)",
        type: "solid",
        width: 1,
      },
    },
    props.XAxisLine
  );

  // 纵坐标轴线配置
  const YAxisLine = mergeConfig(
    {
      // 是否显示
      // show: true,
      show: false,
      // 样式
      lineStyle: {
        // 是否显示
        show: true,
        // 样式
        lineStyle: {
          color: "#fff",
          type: "solid",
          width: 1,
        },
      },
    },
    props.YAxisLine
  );

  // 横坐标分割线配置
  const XSplitLine = mergeConfig(
    {
      // 是否显示
      show: false,
      // 样式
      lineStyle: {
        color: "#fff",
        type: "dotted",
        width: 1,
      },
    },
    props.XSplitLine
  );

  // 纵坐标分割线配置
  const YSplitLine = mergeConfig(
    {
      // 是否显示
      show: true,
      // 样式
      lineStyle: {
        color: "rgba(46, 59, 86)",
        type: 'dashed',
        // type: "solid",
        width: 1,
      },
    },
    props.YSplitLine
  );

  // 横坐标刻度配置
  const XAxisTick = mergeConfig(
    {
      // 是否显示
      show: false,
      // 刻度长度
      length: 5,
      // 是否朝内
      inside: true,
      // 刻度是否居中
      alignWithLabel: true,
      // 样式
      lineStyle: {
        color: "#fff",
        type: "solid",
        width: 1,
      },
    },
    props.XAxisTick
  );

  // 纵坐标刻度配置
  const YAxisTick = mergeConfig(
    {
      // 是否显示
      show: false,
      // 刻度长度
      length: 5,
      // 是否朝内
      inside: true,
      // 刻度是否居中
      alignWithLabel: true,
      color: "#fff",
      // 样式
      lineStyle: {
        color: "#fff",
        type: "solid",
        width: 1,
      },
    },
    props.YAxisTick
  );

  // 图例标记配置
  const legend = mergeConfig(
    {
      show: true,
      right: "0",
      top: "0",
      icon: "rect",
      itemHeight: 10,
      itemWidth: 10,
      textStyle: {
        color: "#fff",
      },
      // 取消默认点击事件
      selectedMode: false,
      // 距离
      itemGap: 50,
    },
    props.legend
  );

  // 指示器:
  const tooltip = {
    show: false,
    trigger: "axis",
    axisPointer: {
      type: "shadow",
    },
    formatter: function (e: any) {
      // console.log(e);
      var str =
        e[4].axisValue +
        "<br>" +
        "<span style='display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color:" +
        e[4].color.colorStops[0].color +
        ";'></span>" +
        "" +
        e[4].seriesName +
        " : " +
        e[4].value +
        "<br>" +
        "<span style='display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color:" +
        e[5].color.colorStops[0].color +
        ";'></span>" +
        "" +
        e[5].seriesName +
        " : " +
        e[5].value;
      return str;
    },
    // 提示框背景颜色
    backgroundColor: "#122843",
    // 提示框边框颜色
    borderColor: "#42D1F1",
    // 提示框文本样式
    textStyle: {
      color: "#fff",
    },
  };

  // 汇总配置
  let option: echarts.EChartsCoreOption = {
    title,
    tooltip,
    legend,
    grid: {
      top: "12%",
      left: "2%",
      right: "2%",
      bottom: "5%",
      // height: "85%",
      containLabel: true,
    },
    xAxis: {
      type: "category",
      boundaryGap: true,
      data: props.xAxisData,
      axisLine: XAxisLine,
      splitLine: XSplitLine,
      axisTick: XAxisTick,
      axisLabel: {
        // textStyle: {
        color: "#fff",
        fontSize:16
        // },
      },
    },
    yAxis: {
      type: "value",
      // 单位
      name: props.yUnit,
      axisLine: YAxisLine,
      splitLine: YSplitLine,
      axisTick: YAxisTick,
      axisLabel: {
        // textStyle: {
        color: "#fff",
        fontSize:16
        // },
      },
      
      min: 0,
      // max: props.max,
    },
    series,
  };
  // 合并配置生成最终配置
  option = Object.assign(option, props.config);
  return option;
}

// props
const props = defineProps({
  // 父容器ID
  pid: {
    type: String,
    required: true,
  },
  title: {
    type: Object,
    default: {},
  },
  // 数据
  series: {
    // type: Array as () => Array<BarSeriesOption>,
    type: Array as () => { data: number[] }[],
    required: true,
  },
  // 横坐标
  xAxisData: {
    type: Array,
    required: true,
  },
  // 图例标记
  legend: {
    type: Object,
    default: {},
  },
  // 横坐标轴线
  XAxisLine: {
    type: Object,
    default: {},
  },
  // 纵坐标轴线
  YAxisLine: {
    type: Object,
    default: {},
  },
  // y轴单位
  yUnit: {
    type: String,
    default: "",
  },
  // 横坐标分割线
  XSplitLine: {
    type: Object,
    default: {},
  },
  // 纵坐标分割线
  YSplitLine: {
    type: Object,
    default: {},
  },
  // 横坐标刻度
  XAxisTick: {
    type: Object,
    default: {},
  },
  // 纵坐标刻度
  YAxisTick: {
    type: Object,
    default: {},
  },
  // 总配置,将与默认配置与用户传入的配置合并
  config: {
    type: Object as () => echarts.EChartsCoreOption,
    default: {},
  },
  // 最值
  // max: {
  //     type: Number,
  //     // requird: true,
  //     default: 5000,
  // },
  nameOne: {
    type: String,
    default: "昨日总量",
  },
  nameTow: {
    type: String,
    default: "今日总量",
  },
});

// option
let option = initOption();

// chart 容器
let container: HTMLElement | null = null;
// chart 实例
let myChart: echarts.ECharts | null = null;

// 渲染方法
const renderChart = () => {
  if (!myChart) myChart = echarts.init(container as HTMLElement);
  myChart.setOption(option);
};

// DOM加载后渲染 chart
nextTick(() => {
  // 获取容器
  container = document.querySelector("#" + props.pid) as HTMLElement;
  // 渲染 chart
  renderChart();
  // 自适应 chart
  // useResizeChart(container, myChart as echarts.ECharts);
});

// 监听 props 变化
watch(
  () => props,
  () => {
    // 更新 option
    option = initOption();
    // 重新渲染chart
    renderChart();
  },
  {
    deep: true,
  }
);

// 导出为图片
function exportImg() {
  // 生成 base64 图片
  const src = (myChart as echarts.ECharts).getDataURL({
    pixelRatio: 2,
    backgroundColor: "#08172A",
  });
  // 下载
  const a = document.createElement("a");
  a.href = src;
  a.download = (option.title as { text: string }).text || "chart-img";
  a.click();
}

// 暴露出 chart 图片导出方法,父组件可以通过实例调用
defineExpose({
  exportImg,
});
</script>

<style lang="scss" scoped></style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/405045.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

unplugin-auto-import 和 unplugin-vue-components

背景 unplugin-auto-import&#xff1a;为 Vite、Webpack、Rollup 和 esbuild 按需自动导入 API。支持 TypeScript。 unplugin-vue-components&#xff1a;Vue 的按需组件自动导入。 这两个插件都是涉及到按需自动导入&#xff0c;所以我们在使用 Vue 和其对应的 组件之类时…

最全的—— ES6有哪些新特性?

目录ES6新特性1、let和const2、symbol3、模板字符串3.1 字符串新方法&#xff08;补充&#xff09;4、解构表达式4.1 数组解构4.2 对象解构5、对象方面5.1 Map和Set5.1.1 Map5.1.2 Set5.3 数组的新方法5.3.1 Array.from()方法5.3.2 includes()方法5.3.3 map()、filter() 方法5.…

ES6中的箭头函数详细梳理

一、箭头函数的介绍 1.1 什么是箭头函数 ES6中允许使用>来定义函数。箭头函数相当于匿名函数&#xff0c;并简化了函数定义。 1.2 基本语法 // 箭头函数 let fn (name) > {// 函数体return Hello ${name} !; };// 等同于 let fn function (name) {// 函数体return …

vue是什么?vue的优点有哪些?

目录 一、vue是什么 二、为什么要用Vue&#xff1f; 1. 组件化 2. MVVM 数据双向绑定 3. 响应式 虚拟DOM 4.生命周期 三、Vue的优点 1. 轻量级 2. 高性能 3. 好上手 4. 插件化 5. 便于测试 6.运行速度更快 7.视图,数据,结构分离 一、vue是什么 Vue是一套用于构建…

vue基础用法基础原理整理

vue基础用法&基础原理整理 md文件地址&#xff1a;https://gitee.com/gaohan888/note 1. vue基础知识和原理 1.1 初识Vue 想让Vue工作&#xff0c;就必须创建一个Vue实例&#xff0c;且要传入一个配置对象demo容器里的代码依然符合html规范&#xff0c;只不过混入了一些特…

Vue3 中路由Vue Router 的使用

目录前言&#xff1a;一、什么是 Vue Router &#xff1f;二、路由的使用1、路由的安装2、路由的模式3、创建路由模块4、声明路由链接和占位符三、路由的重定向和别名四、嵌套路由五、声明式和编程式导航1、声明式导航2、编程式导航3、替换当前位置4、路由历史总结&#xff1a;…

如何使用vue-cli来搭建vue项目?详细步骤跟着我来吧!

目录 一、什么是vue-cli? 二、前提&#xff1a;搭建好NodeJS环境 安装vue-cli 三、使用脚手架vue-cli(2.X版)来构建项目 第一步 第二步 第三步 第三步 第四步 三、SPA完成路由的开发 第一步 ​编辑第二步 第三步 第四步 第四步 四、嵌套路由 使用children属性 五、知…

SpringMVC的文件上传

6.SpringMVC的文件上传 6.1-SpringMVC的请求-文件上传-客户端表单实现(应用) 文件上传客户端表单需要满足&#xff1a; 表单项type“file” 表单的提交方式是post 表单的enctype属性是多部分表单形式&#xff0c;及enctype“multipart/form-data” <form action"…

怎样创建一个VUE项目(超简单)

目录 一、安装node.js 二、搭建vue环境 1、全局安装vue/cli模块包 2、执行命令 3、检查是否安装成功 三、创建vue项目 1、创建项目 2、选择模板和包管理器&#xff0c;等待项目创建完毕 四、启动vue项目 1、执行命令 2、浏览项目页面 五、vue项目目录文件含义和作用…

2022 uniapp基础掌握及面试题整理

1.uniapp优缺点 优点: a. 一套代码可以生成多端 b. 学习成本低,语法是vue的,组件是小程序的 c. 拓展能力强 d. 使用HBuilderX开发,支持vue语法 e. 突破了系统对H5调用原生能力的限制 缺点: a. 问世时间短,很多地方不完善 b. 社区不大 c. …

2022前端面试题汇总(持续更新中~)

目录 1. 防抖和节流 2. js闭包 vue中的data为什么是一个函数&#xff1f;&#xff08;面试常问&#xff09; 3. ES6面试题 3.1 var let const 区别 3.2 解构 3.3 如何利用es6快速的去重&#xff1f; 3.4 Promise 面试题 以下代码的执行结果是&#xff1f; 4. Vue相关…

前端面试八股文(超详细)

JavaScript \1. Promise 的理解 Promise 是一种为了避免回调地狱的异步解决方案 2. Promise 是一种状态机&#xff1a; pending&#xff08;进行中&#xff09;、fulfilled&#xff08;已成功&#xff09;和rejected&#xff08;已失败&#xff09; 只有异步操作的结果&#…

2022最全最新前端面试题(附加解答)

JS 1、说一下innerHTML 与 innerText的作用与区别&#xff1f; 作用&#xff1a;都可以获取或者设置元素的内容区别&#xff1a;innerHTML可以解析内容中的html标签innerText不能解析内容中的html标签 2、JavaScript 由以下三部分组成&#xff1a; ECMAScript&#xff08;语…

Java Web 项目入门指南(http、Servlet、Request、Response、ServletContext、会话技术[cookie、session]、Filter、Listener)

概述 web 服务器、项目、资源概述 web 服务器&#xff1a;可以被浏览器访问到的服务器 常见的 web 服务器&#xff1a; tomcat&#xff1a;中小型的服务器软件&#xff0c;免费开源&#xff0c;支持 JSP 和 Servlet apache 公司的产品WebLogic&#xff1a;Oracle 公司的产品…

Vue.js 状态管理:Pinia 与 Vuex

&#x1f482; 个人网站:【海拥】【摸鱼游戏】【神级源码资源网】&#x1f91f; 前端学习课程&#xff1a;&#x1f449;【28个案例趣学前端】【400个JS面试题】&#x1f485; 想寻找共同学习交流、摸鱼划水的小伙伴&#xff0c;请点击【摸鱼学习交流群】 目录Pinia 和 Vuex 简…

vue3 一个基于pinia简单易懂的系统权限管理实现方案,vue-router动态路由异步问题解决

文章目录前情提要应用场景实战解析1、控制添加路由2、实践观察3、控制功能4、解决异步路由问题最后前情提要 作为项目经验稀少的vue开发者来说&#xff0c;在关键技术点上的经验不多&#xff0c;我希望通过我的思想和实践&#xff0c;把好的东西分享在这里&#xff0c;目的是进…

【前端进阶】-TypeScript类型声明文件详解及使用说明

前言 博主主页&#x1f449;&#x1f3fb;蜡笔雏田学代码 专栏链接&#x1f449;&#x1f3fb;【TypeScript专栏】 前三篇文章讲解了TypeScript的一些高级类型 详细内容请阅读如下&#xff1a;&#x1f53d; 【前端进阶】-TypeScript高级类型 | 泛型约束、泛型接口、泛型工具类…

【live2D看板娘】为你的网站添加萌萌的二次元板娘,这都拿不下你?

&#x1f4cb; 个人简介 &#x1f496; 作者简介&#xff1a;大家好&#xff0c;我是阿牛&#xff0c;全栈领域优质创作者。&#x1f61c;&#x1f4dd; 个人主页&#xff1a;馆主阿牛&#x1f525;&#x1f389; 支持我&#xff1a;点赞&#x1f44d;收藏⭐️留言&#x1f4d…

渐进式 Web 应用程序介绍

&#x1f482; 个人网站:【海拥】【摸鱼游戏】【神级源码资源网】&#x1f91f; 前端学习课程&#xff1a;&#x1f449;【28个案例趣学前端】【400个JS面试题】&#x1f485; 想寻找共同学习交流、摸鱼划水的小伙伴&#xff0c;请点击【摸鱼学习交流群】 构建 PWA 背后的核心思…

【Promise】一文带你了解promise并解决回调地狱

文章目录Promise为什么需要promise需求回调地狱Promise的基本使用promise实例promise的状态promise状态的改变promise的结果promise方法then方法通过then方法获取promise的结果then方法的返回值catch方法解决回调地狱Promise 为什么需要promise 需求 通过ajax请求id,再根据id…