vue2升级vue3:vue3真的需要vuex或者Pinia吗?hooks全有了

在写 《vue2升级vue3:TypeScript下vuex-module-decorators/vuex-class to vuex4.x》,建议新项目使用 Pinia,但是我的项目部分组件希望直接打包出去给地方使用。这个时候还是会遇到vue2 是否打包出vuex的 问题。所以,干脆舍弃 vuex/Pinia,直接使用 vue3 原生搞定——hook出现之后,状态管理的问题已经从根本上被消解了!

vue-composition 提供了类似 React Hook 的能力,将 Vue 的抽象层级从「组件级(Component)」降低为「函数级(Function)」。

当掌握了Hook(或者Composition API)之后,感觉万物皆可hook,总是想把数据和操作这堆数据的方法封装在一起!

1、方案有以下几种reactive 响应式数据取代store,在各个组件hooks 调用

const store = reactive({state: {})

2、利用rovide和inject,类似react  context,做全局数据管理(不推荐)具体可参看:《vue2升级vue3:provide与inject 使用注意事项》

父组件

const person = reactive({name: 'bob', age:32});
provide('person', person);

子组件

const person = inject('person');

有了provide/inject和ref/reactive配合,父子组件/兄弟组件共享状态的问题已经迎刃而解。

通过provide提供了一个reactive响应式对象;然后在子组件通过inject注入该对象。在子组件修改对象的age属性,视图就会响应式更新!同样的,如果child组件也有自己的子组件,调用inject同样有效。具体参看:

  • Vue3你还在用Vuex?一个“函数式”状态管理的新思路 https://zhuanlan.zhihu.com/p/345963989
  • Vue3 尝鲜 Hook + TypeScript 取代 Vuex 实现图书管理小型应用 https://my.oschina.net/sl1673495/blog/4439246 (全局注入)

1、2方法结合:

hooks

export function useUserInfo() {
  const userInfo = reactive({ });
  
  const login = (data) => {...};
  const logout = () => {...};
  const editUserInfo => (data) => {};
  
  return {
   userInfo,
   login,
   logout,
   editUserInfo
  }
}

在根组件调用provide,将userHook函数传入

import {useUserInfo} from '@/hooks/userUserInfo';
provide('user', useUserInfo())

这个 封装好的东西,直接看这个:https://github.com/tbhuabi/vue-di-plugin

但是还是不推荐这个写法!即使 provide/inject 再香,我还是绕道走,总感觉 这玩意和react的 useContext + useReducer 貌似 貌合神离——可以看一下  :https://github.com/tangxiangmin/vue3-hook/tree/master/src/useReducer

1、使用

比如我之前的数据,vuex的

/**
 * 面板查询变量
 */

import { VuexModule, Module, getModule, Mutation } from 'vuex-module-decorators';
import store from '../index';
import { TimeRangeType } from '@/components/time-range';
import { DEFAULT_TIME_RANGE, TimeRange } from '@/components/time-range/utils';
import { FiltersList, FilterType, QueryContextState } from '@/typings';

@Module({ dynamic: true, store, name: 'queryContext' })
export default class QueryContext extends VuexModule implements QueryContextState {
  timeRange: TimeRangeType = DEFAULT_TIME_RANGE;
  timezone = 'Asia/Shanghai';
  variables: FiltersList = {};
  share_uid = '';
  // 缓存的时间 - TimeRangeType 转时间戳
  get getTimeRange(): [number | string, number | string] {
    const date = new TimeRange(this.timeRange);
    const [start, last] = date.value;
    return [start.valueOf(), last.valueOf()];
  }
  @Mutation
  setTimeRange(range: TimeRangeType) {
    this.timeRange = range;
  }
  @Mutation
  setTimezone(zone: string) {
    this.timezone = zone;
  }
  @Mutation
  setShareUid(share_uid: string) {
    this.share_uid = share_uid;
  }
  @Mutation
  setVariation({ name, value }: { name: string; value: FilterType }) {
    // this.variables[name] = value;
    this.variables = { ...this.variables, [name]: value };
  }

  @Mutation
  setVariations(variables: FiltersList) {
    this.variables = variables;
  }
  @Mutation
  clear() {
    this.variables = {};
    this.timeRange = DEFAULT_TIME_RANGE;
  }
}

export const QueryContextModule = getModule(QueryContext);

直接使用响应式数据

import { reactive } from 'vue';
import { FiltersList, FilterType, QueryContextState } from '@/typings';
import { DEFAULT_TIME_RANGE } from '@/components/time-range/utils';
import { TimeRangeType } from '@/components/time-range';
export const QueryContextModule = reactive<QueryContextState>({
  timeRange: DEFAULT_TIME_RANGE,
  timezone: 'Asia/Shanghai',
  variables: {},
  share_uid: '',
});
export function setTimeRange(range: TimeRangeType) {
  QueryContextModule.timeRange = range;
}
export function setTimezone(zone: string) {
  QueryContextModule.timezone = zone;
}
export function setShareUid(share_uid: string) {
  QueryContextModule.share_uid = share_uid;
}
export function setVariation({ name, value }: { name: string; value: FilterType }) {
  QueryContextModule.variables = { ...QueryContextModule.variables, [name]: value };
}
export function setVariations(variables: FiltersList) {
  QueryContextModule.variables = variables;
}
export function clear() {
  QueryContextModule.variables = {};
  QueryContextModule.timeRange = DEFAULT_TIME_RANGE;
}

改为类vuex,可以参看此篇文章: Vue3 还要啥 Vuex,自定义 hooks给你实现数据共享和状态管理 https://juejin.cn/post/7054060160045547550

import { reactive } from 'vue';
import { FiltersList, FilterType } from '@/typings';
import { DEFAULT_TIME_RANGE } from '@/components/time-range/utils';
import { TimeRangeType } from '@/components/time-range';
const store = reactive({
  state: {
    timeRange: DEFAULT_TIME_RANGE,
    timezone: 'Asia/Shanghai',
    variables: {},
    share_uid: '',
  },
});

export function setTimeRange(range: TimeRangeType) {
  store.state.timeRange = range;
}
export function setTimezone(zone: string) {
  store.state.timezone = zone;
}
export function setShareUid(share_uid: string) {
  store.state.share_uid = share_uid;
}
export function setVariation({ name, value }: { name: string; value: FilterType }) {
  store.state.variables = { ...store.state.variables, [name]: value };
}
export function setVariations(variables: FiltersList) {
  store.state.variables = variables;
}
export function clear() {
  store.state.variables = {};
  store.state.timeRange = DEFAULT_TIME_RANGE;
}

export const useQueryContext = () => ({
  store,
  setTimeRange,
  setTimezone,
  setShareUid,
  setVariation,
  setVariations,
  clear,
});

这个使用肯定是还太粗糙,项目中使用的代码,等有空的 脱密了在分享一下

参考文章:

有了 Vue3 还要啥 Vuex,自定义 hooks给你实现数据共享和状态管理 https://juejin.cn/post/7054060160045547550

转载本站文章《vue2升级vue3:vue3真的需要vuex或者Pinia吗?hooks全有了》, 请注明出处:https://www.zhoulujun.cn/html/webfront/ECMAScript/vue3/8881.html

本文转载于网络 如有侵权请联系删除

相关文章

  • 如何拥有一款有特色的 Github Profile?

    什么是GithubProfileGithubProfile用于展示个人的一些成果,把Markdown转换为HTML渲染在个人主页上,并且高度支持自定义。话不多说,先展示两个酷炫的主页。如果你也想拥有这样酷炫主页,继续往下看创建自己的Profile可以参照Profile官方文档[1],建一个和用户名同名的仓库,在仓库中编辑README.md文件就可以了。接下来开始丰富你的Profile1.添加图片markdown支持两种添加图片的方式![alt](src)普通的<img>标签使用标签会更灵活,比如设置width=xxx,height=xxx来固定宽高,也可以设置align="left|center|right"来规定对齐方式可以合理使用gif让主页更酷炫2.添加一些开源Element1.GitHub数据统计[2]根据你的用户名,获取并直观展示Github贡献数据。根据提交数、贡献数、issue数量、star数量、PR数量等计算出一个等级值。2.GitHub统计奖杯[3]统计你的Github数据,评估各分项等级并以奖杯的形式展示,最高级SSS,并有一个隐藏奖

  • .NET 6 中的HTTP 3支持

    dotnet团队官方博客发布了一篇HTTP3的文章:HTTP/3supportin.NET6:https://devblogs.microsoft.com/dotnet/http-3-support-in-dotnet-6/。文章介绍了.NET6将预览支持HTTP3,.NET7正式支持HTTP3,原因主要是HTTP/3的RFC尚未最终确定,因此仍然可以更改,并且在.NET6中,HTTP/3可能存在行为或性能问题。将HTTP/3包含在.NET6中,可以开始尝试它。HTTP/3是HTTP的第三个即将发布的主要版本。HTTP/3使用与HTTP/1.1和HTTP/2相同的语义:相同的请求方法、状态代码和消息字段适用于所有版本。差异在于基础传输。HTTP/1.1和HTTP/2都将TCP用作其传输协议。HTTP/3使用的是与HTTP/3同时开发的一种新传输技术,称为QUIC。与HTTP/1.1和HTTP/2相比,HTTP/3和QUIC具有很多优势:第一个请求的响应时间更短。QUIC和HTTP/3在客户端和服务器之间以较少的往返次数协商连接。第一个请求更快地到达服务器,QUIC使用UDP并内置TLS

  • 你偷看的小黄片,全被监视了

    号外: 本号免费提供CSDN资源下载,需要的伙伴公众号后台回复【CSDN】素材来源:网络长夜漫漫,总是让人无心睡眠。你悄悄打开收藏已久的网页,熟练地切换成“无痕模式”。但你以为清理历史记录+切换无痕模式就安全了,就太天真了! 今天小白告诉你,网页被谁偷窥了。浏览器难咎其责,之前谷歌就曾因无痕模式泄露隐私,遭到50亿高额索赔。浏览器获取相应内容的过程是这样的:输入关键词→记录搜索记录→传输到网络运营商主网络→再把信息传送到相应的网站服务器→最后把搜索到的结果传送给用户。中间这么多流程,你的小秘密早已不保。而且浏览器还会通过Cookie记录用户的输入数据,自动保存用户信息。当用户下次再登录该网站时,网站就可以通过Cookie辨别用户身份,直接登陆。基于用户的这一顾虑,浏览器推出无痕模式。看似没什么问题,但无痕模式的查看详情里有说明:以下各方可能仍会看到您的活动: 您访问的网站您的雇主或学校您的互联网服务提供商。 这主要是为了能够收集用户数据,分析用户的喜好,精准投放广告。其次,要怪输入法。 输入法用的越久就越来越懂你。输入法会根据用户输入内容,精准推送广告早就不是什么秘密了。 虽然开启了

  • 死循环的妙用

    做开发写程序,最麻烦就是写循环。一个程序功能里面如果多于5个循环的,那么要么这个业务逻辑有问题,要么就是开发的人太Yang。用5个循环去做一个业务逻辑,耗时耗资源不说;假设其中有个死循环那就死翘翘了。但是有时候死循环也有他的妙用,就像我接手的一个用wpf写的程序;客户反馈说程序容易卡死或点击没反应甚至根本没法进入程序。。首先看了一下程序,里面光循环就N多个,然后再不同的业面跳转。。还有WPF因为是坐标定位,所以一不小心就会定位错误,,唉。。但这些问题都不是这次的主问题,主问题是为什么会卡死没反应。。经过一轮问题复现测试后,发现是由于网络不联通导致的。问题找到那就解决吧,在执行相关的业务逻辑前,先判断一下网络是否可用,可用就执行,不可用就提示到可用为止。于是就先从程序运行前进行网络的检测调用。。网络检测的代码如下:#region检测网络状态 boolCheckNET(Stringip,intport) { boolb=false; IPEndPointpoint=newIPEndPoint(IPAddress.Parse(ip),port); Socketsocket=newSocke

  • 使用深度学习来实现超分辨率的介绍

    作者:BharathRaj 编译:ronghuaiyang 导读这里详细讨论了用于使用深度学习的超分辨率的各种组件、损失函数和度量。介绍 超分辨率是从给定的低分辨率(LR)图像中恢复高分辨率(HR)图像的过程。由于较小的空间分辨率(即大小)或退化的结果(如模糊),图像可能具有“较低的分辨率”。我们可以将HR图像和LR图像通过如下公式联系起来:LR=degradation(HR)`显然,在应用退化函数时,我们可以从高分辨率图像中得到低分辨率图像。但是,我们可以反过来做吗?在理想情况下,是的!如果我们知道精确的退化函数,通过对LR图像应用它的逆函数,我们可以恢复HR图像。 但是,问题就在这里。我们通常事先不知道退化函数。直接估计逆退化函数是一个不适定的问题。尽管如此,深度学习技术已被证明是有效的超分辨率方法。本博客主要介绍如何通过使用监督训练方法使用深度学习来进行超分辨率。还讨论了一些重要的损失函数和度量。很多内容都来自于这篇文献综述:https://arxiv.org/abs/1902.06068,读者可以参考一下。监督方法如前所述,深度学习可以用给定的低分辨率图像来估计高分辨率图像。通

  • Github项目推荐 | Awesome-Image-Inpainting 图像补全相关资源大列表

    Github项目链接:https://github.com/1900zyh/Awesome-Image-Inpainting早期方法(非基于学习)[1]Bertalmio,M.,Sapiro,G.,Caselles,V.,&Ballester,C.(2000,July).Imageinpainting.InSIGGRAPH(pp.417-424).[paper][2]Bertalmio,M.,Vese,L.,Sapiro,G.,&Osher,S.(2003).Simultaneousstructureandtextureimageinpainting.TIP,12(8),882-889.[paper][3]Criminisi,A.,Pérez,P.,&Toyama,K.(2004).Regionfillingandobjectremovalbyexemplar-basedimageinpainting.TIP13(9),1200-1212.[paper][4]Sun,J.,Yuan,L.,Jia,J.,&Shum,H.Y.(2005,July).Imag

  • python: 经典排序 汇总

    冒泡排序defbubble_sort(x): foriinrange(len(x)): forjinrange(1,len(x)-i): ifx[j-1]>x[j]: x[j-1],x[j]=x[j],x[j-1] returnx复制插入排序definsert_sort(x): foriinrange(len(x)): forjinrange(i): ifx[i]<x[j]: tmp=x[i] forpinrange(i,j,-1): x[p]=x[p-1] x[j]=tmp returnx复制选择排序defselect_sort(x): foriinrange(len(x)): forjinrange(i+1,len(x)): ifx[i]>x[j]: x[i],x[j]=x[j],x[i] returnx复制归并排序defmerge(left,right): i,j,res=0,0,[] whilei<len(left)andj<len(right): ifleft[i]<=right[j]: res.append(left[i]) i+=1 e

  • Golang 入门系列(四)如何理解interface接口

    前面讲了很多Go语言的基础知识,包括go环境的安装,go语言的语法等,感兴趣的朋友,可以先看看之前的文章。https://www.cnblogs.com/zhangweizhong/category/1275863.html 今天就正式开始写Go的代码,讲讲如何理解interface接口。什么是interface接口interface是GO语言的基础特性之一。可以理解为一种类型的规范或者约定。它跟java,C#不太一样,不需要显示说明实现了某个接口,它没有继承或子类或“implements”关键字,只是通过约定的形式,隐式的实现interface中的方法即可。因此,Golang中的interface让编码更灵活、易扩展。如何理解go语言中的interface?只需记住以下三点即可:1.interface是方法声明的集合 2.任何类型的对象实现了在interface接口中声明的全部方法,则表明该类型实现了该接口。 3.interface可以作为一种数据类型,实现了该接口的任何对象都可以给对应的接口类型变量赋值。注意: 1.interface可以被任意对象实现,一个类型/对象也可以实现多个

  • virtualenv -p python3 venv报错

    在阿里云服务器上,用virtualenv创建虚拟环境时,报了个错误root@iZwz982qla1uxm1s5dnyo7Z:/usr/lib/python3/dist-packages/virtualenv-15.0.1.egg-info#virtualenv-ppython3venv Runningvirtualenvwithinterpreter/usr/bin/python2 Newpythonexecutablein/usr/lib/python3/dist-packages/virtualenv-15.0.1.egg-info/venv/bin/python2 Notoverwritingexistingpythonscript/usr/lib/python3/dist-packages/virtualenv-15.0.1.egg-info/venv/bin/python(youmustuse/usr/lib/python3/dist-packages/virtualenv-15.0.1.egg-info/venv/bin/python2) Pleasemakesureyou

  • 根分区伸缩实验

    众所周知LVM是Linux环境下对磁盘进行管理的一种机制。用户在安装Linux操作系统时,难以分配合适的硬盘空间,当一个分区存放不下某个文件时,这个文件因为文件系统的限制,也不能跨越多个分区来存放。而遇到出现某个分区耗尽时,只有使用调整分区大小的工具。随着LVM功能的出现,这些问题都迎刃而解,用户在无需停机的情况下可以方便地调整各个分区大小。 但是,今天我们讨论的不是LVM,而是分区工具对分区的操作技巧。有些发型版本默认安装Linux没有支持LVM,或者用户在安装时没有选择LVM,导致根分区空间过大。例如VM在自动安装CentOS6.5时没有支持LVM,以下是我的CentOS6.5全自动安装完成的磁盘情况。 系统安装并没有详细的分区,所以我们自然就打起了根分区的主意,想再分出一些空闲空间。下面就开始我们的实验吧。 想要对根分区操作的操作需要调整启动选项并使用U盘或光盘进入resecu模式。注意:在进入resecu模式时选择忽略将根挂载在/mnt/sysimage这一项。进入resecu模式下的shell后,先执行e2fsck-f/dev/sda整理一下磁盘。之后就可以使用parted

  • 聊聊对称/非对称加密在HTTPS中的应用

    目前常用的加密算法主要分成三类:对称加密算法非对称加密算法消息摘要算法在互联网中,信息防护主要涉及两个方面:信息窃取和信息篡改。对称/非对称加密算法能够避免信息窃取,而消息摘要算法能够避免信息篡改。对称加密算法发送方和接收方需要持有同一把密钥,发送消息和接收消息均使用该密钥。相对于非对称加密,对称加密具有更高的加解密速度,但双方都需要事先知道密钥,密钥在传输过程中可能会被窃取,因此安全性没有非对称加密高。非对称加密算法接收方在发送消息前需要事先生成公钥和私钥,然后将公钥发送给发送方。发送放收到公钥后,将待发送数据用公钥加密,发送给接收方。接收到收到数据后,用私钥解密。在这个过程中,公钥负责加密,私钥负责解密,数据在传输过程中即使被截获,攻击者由于没有私钥,因此也无法破解。非对称加密算法的加解密速度低于对称加密算法,但是安全性更高。消息摘要算法消息摘要算法可以验证信息是否被篡改。在数据发送前,首先使用消息摘要算法生成该数据的签名,然后签名和数据一同发送给接收者。接收者收到数据后,对收到的数据采用消息摘要算法获得签名,最后比较签名是否一致,以此来判断数据在传输过程中是否发生修改。无论输入的

  • token与安全

    http://ju.outofmemory.cn/entry/134189    关于Token,你应该知道的十件事 https://blog.csdn.net/Fabulous1111/article/details/79375358  基于Token进行身份验证 https://blog.csdn.net/buyaoshuohua1/article/details/73739419   WT——Token认证的两种实现和安全详解 https://blog.csdn.net/wangcantian/article/details/74199762    Web安全通讯之Token与JWT https://blog.csdn.net/wanghang88/article/details/51707276  Cookie与session通熟一点的理解,并且Cookie防劫持的处理  

  • Cookie的Secure属性

    测试过程 支付页面: Secure属性为false,没有开启。 风险分析 Cookie未设置secure属性,攻击者可以通过嗅探HTTP形式的数据包获取到该cookie。 解决方法 将Cookie应设置secure属性。   基于安全的考虑,需要给cookie加上Secure和HttpOnly属性,HttpOnly比较好理解,设置HttpOnly=true的cookie不能被js获取到,无法用document.cookie打出cookie的内容。 Secure属性是说如果一个cookie被设置了Secure=true,那么这个cookie只能用https协议发送给服务器,用http协议是不发送的。换句话说,cookie是在https的情况下创建的,而且他的Secure=true,那么之后你一直用https访问其他的页面(比如登录之后点击其他子页面),cookie会被发送到服务器,你无需重新登录就可以跳转到其他页面。但是如果这是你把url改成http协议访问其他页面,你就需要重新登录了,因为这个cookie不能在http协议中发送。 例子是: 前提条件:https://loc

  • 深入分析Linux Kernel Exception 框架(基础篇)

    极力推荐Android开发大总结文章:欢迎收藏 程序员Android力荐,Android开发者需要的必备技能 KernelException在工作中偶尔会遇到,发生此异常时候经常会导致手机死机或重启。那么如何解决这些问题,本篇文章将带你从KE小白变小牛。 注: 本文部分内容参考MTK,如有侵权,请告知,立马关闭此文,停止侵权。知识共享,感谢支持! 本篇文章主要介绍Android开发中的部分知识点,通过阅读本篇文章,您将收获以下内容: 基础篇:通过log分析KE 1.KernelException 2.kernel空间布局 3.了解printk 4.ramconsole 5.前期异常处理 6.die()流程 7.panic()流程 8.nestedpanic 基础篇:通过log分析KE 1.KernelException KE(KernelException)概念 AndroidOS由3层组成,最底层是kernel,上面是nativebin/lib,最上层是java层: 任何软件都有可能发生异常,比如野指针,跑飞、死锁等等。 异常发生在kernel层,我们就叫它为KE(k

  • 《基于SpringCloud微服务架构广告系统设计与实现》笔记

    1-1课程导学 什么是广告系统?    2-1广告系统概览          2-2广告系统架构      2-3准备工作与系统目录结构     2-3准备工作与系统目录结构   第3章广告系统骨架开发 3-1Maven基础知识       3-2Maven相关特性     3-3广告系统主工程 ...建立项目结构...  Maven有三种类型的仓库: 本地仓库:工程里依赖的jar包,maven会主动下载到本地目录的.m2。 中央仓库:由maven社区提供,包含有大量的常用库。 远程仓库:对开发者提供的,开发者把自己编写的包放在这个仓库,工程就可以指定远程仓库去下载。   3-4单节点EurekaServer的开发   3-5EurekaServer的部署 分别启动单节点和多节点的EurekaServer 单节点配置文件: 多节点(三个节点的Eurekaserv

  • 自我接纳,打破渴望被认可的魔咒

      你不需要别人过多的称赞和认同,你自己知道自己有多优秀就好,内心的强大,永远胜过外表的浮华。

  • 数据结构-打印1到最大的n位数

    题目:输入数字n,按顺序打印出从1到最大的n位十进制数,比如输入3,则打印出1,2,3一直到最大的3位数即999. 分析:本题最关键的部分是当n值非常大的时候会超出数据类型的范围。偷个懒,没有实现打印1,2,3....999.可以利用分割把string分割成char[]。然后单个的char转为int再进行加减法,作为输出。 /* 剑指offer面试题12 该问题主要考虑到数据非常大超出数据类型的范围 */ #include<iostream> #include<cstring> usingnamespacestd; voidprintMaxNum(intn){ stringstr="9"; stringresult=""; if(n<=0){ return; } else{ for(inti=0;i<n;i++){ result+=str; } cout<<result<<endl;; } } intmain() { intn; cin>>n; printMaxNum(n); return0; }复制

  • 范磊 C++ 第6章 面向对象

    1//section_6.cpp:Definestheentrypointfortheconsoleapplication. 2//范磊C++第6章面向对象 3 4#include"stdafx.h" 5#include"iostream" 6 7 8 9//6.3.7对象只能调用类中存在的方法(函数) 10usingstd::cout; 11classHuman 12{ 13public: 14voidwalk() 15{ 16cout<<"我是人,我会走路.\n"; 17} 18voidspeak() 19{ 20cout<<"我是人,我会说话.\n"; 21} 22voidrun() 23{ 24cout<<"我是人,我会跑步.\n"; 25} 26voideat() 27{ 28cout<<"我是人,我会吃饭.\n"; 29} 30voidsleep() 31{ 32cout<<"我是人,我会睡觉.\n"; 33} 34}; 35//这里的成员函数的声明和定义都放在类里面. 36 37voidfun1() 38{ 39

  • Java IO流详尽解析

    流的概念和作用 学习JavaIO,不得不提到的就是JavaIO流。 流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象。即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输特性将流抽象为各种类,方便更直观的进行数据操作。 IO流的分类 根据处理数据类型的不同分为:字符流和字节流 根据数据流向不同分为:输入流和输出流 字符流和字节流 字符流的由来:因为数据编码的不同,而有了对字符进行高效操作的流对象。本质其实就是基于字节流读取时,去查了指定的码表。字节流和字符流的区别: (1)读写单位不同:字节流以字节(8bit)为单位,字符流以字符为单位,根据码表映射字符,一次可能读多个字节。 (2)处理对象不同:字节流能处理所有类型的数据(如图片、avi等),而字符流只能处理字符类型的数据。 (3)字节流在操作的时候本身是不会用到缓冲区的,是文件本身的直接操作的;而字符流在操作的时候下后是会用到缓冲区的,是通过缓冲区来操作文件,我们将在下面验证这一点。 结论:优先选用字节流。首先因为硬盘上的所有文件都是以字节的形式进行传输或者保存的,包括图片等内容。但是字符只是在内存中才会

  • iconfont在cordova打包vue的应用中图标不显示

    在使用cordova打包vue的apk应用的过程中遇到一个问题:通过cordovaserveandroid指令运行然后在浏览器里面通过http://localhost:8000/android/www/index.html#/图标都能正常显示、但是在真机app上却无法显示    原因是在引入iconfont.css文件的问题 错误的引入方式         <linkrel="stylesheet"type="text/css"href="//at.alicdn.com/t/font_1756687_5e1jgxmrs.css"> 复制    问题的原因是 在真机上、用双斜杠//的引用方法在app上是无法识别不出来的、这也造成图标无法显示、所以必须加上http:或者 https:  PS:重新将vue项目编译、然后使用cordova打包一次、替换真机上面的app、图标就能正常显示了!!! <linkrel

  • 配置工程文件dll编译后copy路径

    放到工程文件的最后面的配置节点: 下面的配置节点中生成路径换成实际的相对路径就可以了 修改:Prject.csproj文件里面的配置节点 project配置节点里面的最后面 <TargetName="AfterBuild"><CopySourceFiles="$(TargetDir)$(TargetFileName);$(TargetDir)$(TargetName).pdb;"DestinationFolder="生成路径"SkipUnchangedFiles="true"OverwriteReadOnlyFiles="true"/></Target> 实力打造非凡,王者绝非偶然。

相关推荐

推荐阅读