vue3实战-----封装和使用svg图标

在开发项目的时候经常会用到svg矢量图,使用SVG以后,页面上加载的不再是图片资源,这对页面性能来说是个很大的提升,我们SVG文件比img要小的很多,放在项目中几乎不占用资源。

1.安装和配置svg插件

安装SVG依赖插件:

npm install vite-plugin-svg-icons -D

vite.config.ts中配置插件:

import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
import path from 'path'
export default () => {
  return {
    plugins: [
      createSvgIconsPlugin({
        // Specify the icon folder to be cached
        iconDirs: [path.resolve(process.cwd(), 'src/assets/icons')],
        // Specify symbolId format
        symbolId: 'icon-[dir]-[name]',
      }),
    ],
  }
}

在main.ts入口文件导入:

//这是虚拟模块的引入方式,用于给脚手架插件在打包和开发时做相应的处理。
//Vite 和 Rollup 中都约定以 virtual: 作为虚拟模块的前缀:
import 'virtual:svg-icons-register'

2.解决引入虚拟模块失败的问题

如上引入了虚拟模块,可能会报错-----无法找到模块 ‘virtual:svg-icons-register’ 或其相应的类型声明。
在类型声明文件中追加配置:

declare module "virtual:svg-icons-register";

具体界面如下:
在这里插入图片描述
这时候文件就不爆红了。但这时候直接运行项目,可能会出现以下界面:
在这里插入图片描述
需要安装一下fast-glob插件:

 npm i fast-glob -D  

3.使用svg

进入阿里矢量图官网,随便选择一个矢量图,复制其代码:
在这里插入图片描述
新建phone.svg文件(路径必须与vite.config.ts中保持一致):
在这里插入图片描述
在phone.svg中粘贴刚才的svg代码:
在这里插入图片描述
然后去vue文件中测试一下:

<script setup lang="ts"></script>

<template>
  <div>
    <h1>svg测试</h1>
    <!-- svg是图标外层容器节点,内部需要结合use标签使用 -->
    <svg>
      <!-- xlink:href指定用哪一个图标,属性值必须是以"#icon-图标名字"的格式 -->
      <!-- fill可以设置图标的颜色 -->
      <use xlink:href="#icon-phone" fill="green"></use>
    </svg>
  </div>
</template>
<style scoped></style>

运行项目:
在这里插入图片描述
发现颜色未改变,这时候需要把phone.svg中的fill去掉:
在这里插入图片描述
刷新之后,颜色就改变了:
在这里插入图片描述

4.封装svg组件

新建svg组件文件:
在这里插入图片描述
components/SvgIcon/index.vue:

<template>
    <!-- svg:图标外层容器节点,内部需要与use标签结合使用 -->
    <svg :style="{ width, height }">
        <!-- xlink:href执行用哪一个图标,属性值务必#icon-图标名字 -->
        <!-- use标签fill属性可以设置图标的颜色 -->
        <use :xlink:href="prefix + name" :fill="color"></use>
    </svg>
</template>

<script setup lang="ts">
//接受父组件传递过来的参数
defineProps({
    //xlink:href属性值前缀
    prefix: {
        type: String,
        default: '#icon-'
    },
    //提供使用的图标名字
    name: String,
    //接受父组件传递颜色
    color: {
        type: String,
        default: ''
    },
    //接受父组件传递过来的图标的宽度
    width: {
        type: String,
        default: '16px'
    },
    //接受父组件传递过来的图标的高度
    height: {
        type: String,
        default: '16px'
    }
})
</script>
<style scoped></style>

使用一下svg组件:

<script setup lang="ts">
import SvgIcon from "./components/SvgIcon/index.vue";
</script>

<template>
  <div>
    <h3>svg测试</h3>
    <SvgIcon name="phone" color="pink" width="60" height="60"></SvgIcon>
  </div>
</template>
<style scoped></style>

运行项目发现组件生效:
在这里插入图片描述

5.自定义插件注册svg全局组件

svg在很多地方都会用到,直接把svg组件定义为全局组件更好。
在这里插入图片描述
上面components文件夹里面全部要注册为全局组件。需要在index.ts写以下代码:

//引入项目中全部的全局组件
import SvgIcon from './SvgIcon/index.vue'
import Pagination from './Pagination/index.vue'
import Category from './Category/index.vue'
//引入element-plus提供全部图标组件
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
//全局对象
const allGloablComponent: any = { SvgIcon, Pagination, Category }
//对外暴露插件对象
export default {
  //务必叫做install方法
  install(app: any) {
    //注册项目全部的全局组件
    Object.keys(allGloablComponent).forEach((key) => {
      //注册为全局组件
      app.component(key, allGloablComponent[key])
    })
    //将element-plus提供图标注册为全局组件
    for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
      app.component(key, component)
    }
  },
}

然后再main.ts中挂载使用:

import gloablComponent from './components/index';
app.use(gloablComponent);

这样子一个自定义插件就完成了。

<think>嗯,用户问的是怎么用Matlab通过SVD分解来解方程组。这个问题我得仔细想想,先回忆一下SVD的基本概念。SVD,也就是奇异值分解,是把一个矩阵分解成三个矩阵的乘积,分别是U、SV的转置。其中UV是正交矩阵,S是对角矩阵,对角线上的元素是奇异值。那用SVD来解方程组的话,应该利用伪逆有关吧,特别是当方程组是病态或者不满秩的时候。 首先,用户可能遇到的是线性方程组Ax=b的问题,其中A可能不是方阵,或者方阵但不可逆。这时候常规的方法比如inv(A)*b或者A\b可能不适用或者不稳定。SVD分解在这种情况下能提供更稳定的解,尤其是最小二乘解。 那具体步骤应该是怎样的呢?首先对A进行SVD分解,得到U, S, V。然后,构建奇异值的倒数,但是要注意处理那些接近零的奇异值,避免数值不稳定。通常的做法是设定一个阈值,比如小于某个小数的奇异值就视为零,对应的倒数也设为零。这样构建S矩阵的伪逆,之后用V乘以伪逆S,再乘以U的转置b的乘积,得到解x。 然后,在Matlab中实现的话,可以用svd函数,得到U, S, V。注意S是以向量的形式返回的,所以需要转换成对角矩阵。然后计算伪逆的时候,可以用diag(1./s)对那些大于阈值的元素,其他设为0。最后相乘得到解。 不过用户可能还关心为什么用SVD,比如当矩阵A是病态的时候,SVD分解可以帮助去除那些小的奇异值,从而得到更稳定的解。另外,当A的列数多于行数时,可能存在无穷多解,SVD会给出最小范数解;当行数多于列数时,可能无解,SVD给出最小二乘解。 可能还需要提到用pinv函数,因为pinv其实就是基于SVD实现的,所以用户也可以直接使用x = pinv(A)*b来得到解。不过手动实现一遍可以更清楚背后的原理。 那具体代码的话,用户可能需要一个例子。比如给定一个矩阵A向量b,进行SVD分解,然后构建伪逆,最后求解x。例如,生成一个3x2的矩阵A,对应的b。然后进行分解,处理奇异值的倒数,最后相乘得到解。同时,可以对比用svd方法得到的解直接用A\b的结果是否一致,或者pinv的结果比较,来验证正确性。 但需要注意,当手动处理奇异值时,阈值的选取可能会影响结果。比如用max(size(A)) * eps(norm(s))作为阈值,这样能自动处理不同精度的情况。这样在代码中,计算tol,然后将s中小于tol的项对应的倒数设为0。 所以总结步骤:分解A为U, S, V;计算伪逆S_pinv;然后x = V * S_pinv * U&#39; * b。在Matlab中,需要将S向量转换为对角矩阵,并处理每个元素是否超过阈值,再取倒数。然后矩阵相乘得到解。 可能用户还会遇到什么相关问题呢?比如SVD分解的其他应用,如何选择阈值,或者当矩阵是秩亏的时候如何处理。或者比较不同方法(如QR分解、正规方程)在解方程组中的优劣。此外,可能还会问到如何用SVD进行降维,或者数据压缩,这也是SVD的常见应用。 总之,需要详细解释步骤,给出代码示例,并说明各步的作用,以及背后的数学原理,比如最小二乘解最小范数解的选择。然后可能的问题围绕SVD的应用、阈值选择、与其他分解方法的对比,以及伪逆的性质等。</think>在MATLAB中,使用奇异值分解(SVD)求解线性方程组 `Ax = b` 的核心步骤如下: ### 方法实现 ```matlab % 定义矩阵A向量b A = [1 2; 3 4; 5 6]; b = [7; 8; 9]; % 执行SVD分解 [U, S, V] = svd(A, &#39;econ&#39;); % &#39;econ&#39;模式节省计算资源 % 提取奇异值向量并构建伪逆 s = diag(S); tol = max(size(A)) * eps(norm(s)); % 计算自动阈值 s_pinv = zeros(size(s)); s_pinv(s > tol) = 1./s(s > tol); % 仅对显著奇异值取倒数 % 构建解 x = V * diag(s_pinv) * U&#39; * b; % 验证解 disp([&#39;解向量x: &#39;, num2str(x&#39;)]); disp([&#39;残差范数: &#39;, num2str(norm(A*x - b))]); ``` ### 关键解释 1. **SVD分解**: - 将矩阵分解为 `A = U*S*V&#39;`,其中`U``V`是正交矩阵,`S`是对角矩阵 - `&#39;econ&#39;`参数优化计算,适用于非方阵情况 2. **伪逆构造**: - 自动阈值`tol`基于机器精度矩阵规模,避免数值不稳定 - 仅对显著奇异值(大于阈值)取倒数,抑制噪声影响 3. **解的优化特性**: - 当方程欠定时(列数>行数),给出最小范数解 - 当方程超定时(行数>列数),给出最小二乘解 - 特别适合病态矩阵秩亏情况 4. **验证指标**: - 残差范数反映解的拟合质量 - 可通过`cond(A)`检查矩阵条件数,判断病态程度 ### 替代方案对比 ```matlab % MATLAB内置伪逆函数 x_pinv = pinv(A)*b; % 反斜杠运算符 x_backslash = A\b; % 结果对比 disp([&#39;伪逆解差异: &#39;, num2str(norm(x - x_pinv))]); disp([&#39;反斜杠解差异: &#39;, num2str(norm(x - x_backslash))]); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值