范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

搭建出团队的vue3前端架构

  前言
  由于  vue3.2  版本的发布,复制代码 
4.4 封装SVG的图标组件   svg 图标比较小,而且都是可读的 xml 文本,所以我们把它直接放在项目中即可,通过 vite-plugin-svg-icons 插件,实现自动引入 svg 图标。   配置 vite.config.ts: plugins: [ viteSvgIcons({ iconDirs: [resolve(process.cwd(), "src/assets/icons")], symbolId: "icon-[dir]-[name]", }), ] 复制代码   封装一个 vue 组件: 复制代码   首先将下载的 .svg 图标放入 @/assets/icons 文件夹下 复制代码 name 放置在 @/assets/icons 文件夹下的文件名。 color 颜色填充,使用此项会默认覆盖图标颜色。 5.按需自动引入组件   unplugin-vue-components [77] 是一款非常强大的插件(极力推荐),核心功能就是帮助你自动按需引入组件,Tree-shakable,只注册你使用的组件。这里说一下他的两个核心使用方式和配置方式。   此插件不仅支持 vue3,同时也支持 vue2,并且支持 Vite、Webpack、Vue CLI、Rollup。 5.1 安装与配置   安装: npm i unplugin-vue-components -D 复制代码   配置: // vite.config.ts import Components from "unplugin-vue-components/vite" export default defineConfig({ plugins: [ Components({ /* options */ }), ], }) 复制代码   这里的 options 可以配置一些选项,后面提到的组件库注册会使用到。 5.2 改变全局组件注册方式   我们通常将全局的组件封装在 @/src/components 中,然后通过 app.component() 注册全局组件。使用此插件后,无需手写注册,直接在模板中使用组件即可:   这里引入官方的示例: 复制代码   自动编译为: 复制代码 5.3 自动引入组件库   在使用组件库时,常规组件我们也会注册到全局,如果使用局部注册由于页面中会使用到多个组件,会非常麻烦,所以这个功能绝佳,例如我们使用 ant-design-vue 组件库。   直接在模板中使用即可,无需手动注册或局部引用: 复制代码   当然,你还需要在 vite 中引入它的解析器: import Components from "unplugin-vue-components/vite" import { AntDesignVueResolver } from "unplugin-vue-components/resolvers" export default defineConfig({ plugins: [ Components({ resolvers: [ AntDesignVueResolver(), ] }) ], }) 复制代码   目前支持的解析器,根据你的喜好去选择: Ant Design Vue [78] Element Plus [79] Element UI [80] Headless UI [81] IDux [82] Naive UI [83] Prime Vue [84] Vant [85] VEUI [86] Varlet UI [87] View UI [88] Vuetify [89] VueUse Components [90] Quasar [91] 6.样式   项目中最好使用通用样式,可以创建 src/styles 目录存放,这里推荐一些分类: styles antd # 组件库样式覆盖,命名自取,这里以 ant design 为例 color.less # 颜色 index.less # 入口 global.less # 公共类 transition.less # 动画相关 variable.less # 变量 复制代码 6.1 预设基础样式   相信用过 normalize [92] 的同学不在少数,它可以重置 css 样式,使各浏览器效果保持一致。后面的章节会提到 tailwind.css,它内置了预设样式重置的功能,与 normalize 还是有一定的区别,有兴趣的同学可以了解一下 [93] 。 6.2 CSS 预处理器   虽然 vite 原生支持 less/sass/scss/stylus,但是你必须手动安装他们的预处理器依赖,例如: npm install -D less 复制代码   如何选择预处理器?   推荐使用你是所使用的组件库的样式语言,因为 css 预处理器学会一种后,入手其他几乎没有学习成本。 6.3 开启 scoped   没有加 scoped 属性,会编译成全局样式,造成全局污染。 复制代码 6.4 深度选择器   有时我们可能想明确地制定一个针对子组件的规则。   如果你希望 scoped 样式中的一个选择器能够作用得"更深",例如影响子组件,你可以使用 >>> 操作符。有些像 Sass 之类的预处理器无法正确解析 >>>。这种情况下你可以使用 /deep/ 或 ::v-deep 操作符取而代之——两者都是 >>> 的别名,同样可以正常工作。 7.布局   页面整体布局是一个产品最外层的框架结构,往往会包含导航、页脚、侧边栏等。在页面之中,也有很多区块的布局结构。在真实项目中,页面布局通常统领整个应用的界面,有非常重要的作用,所以单独拆分出来也是非常有必要的。   在脚手架中,所有的通用布局组件都应该放在 src/layouts 中,这种封装比较简单,这里就不贴代码了,大家按照自己实际情况自行发挥,在此仅提供一下封装思路。 7.1 常规的布局   BasicLayout   基础页面布局,包含了头部导航,侧边栏等。   BlankLayout   空白的布局。 7.2 特殊的布局   RouteLayout   如果你的项目在路由切换中需要对某些二级页面进行缓存,那么推荐你创建一个 RouteLayout,通过路由 meta 中的配置,返回 router-view 或者使用 keep-alive 包裹的 router-view 。   UserLayout   用于用户登录注册等页面抽离出来。   PageLayout   基础布局,包含了面包屑等信息,内含 slot。 8.集成 Tailwind.css   Tailwind.css [94] 在我第一次看到它的时候,内心是比较反感的,但实际上手之后又觉得真香。从 vue2 项目中,我已经引入了 tailwind,整体的开发结果就是,基本很少再使用 标签去转本定义一些 class 和样式,毕竟起名字这种事,一个是涉及到规范,一个是涉及到英语。如果你选择 tailwind,CSS 预处理器的作用就会显得微乎其微,因为你无需再自定定义各种变量和 mixins。   总体来说,学习成本并不高,花上两个小时足够上手,记住不用死记硬背那些类名。 8.1 效率提升   很多人总是说样式要与 HTML 分离,现在为什么又要提倡 tailwind 这种与 HTML 紧密结合的工具?这是因为现在使用 vue 这类框架已经高度组件化,样式分离是为了方便复用和维护,但在组件化面前样式分离只能是降低开发效率。   下面介绍一下 tailwind 提供了哪些提升效率的功能: 提供了大量的功能类,极大的提高了可维护性。 响应式设计,各种设备一把梭。 悬停、焦点和其它状态。 深色模式。 支持配置,例如颜色方面很难做到跟你的设计师统一。 不用为起名字而纠结??? 8.2 JIT 模式   如果你的环境支持 postcss8( vue/cli 构建的 vue2 项目是 postcss7 ),那么 JIT 模式直接带你起飞。 超快的构建速度。 支持变体,你甚至可以这么写 sm:hover:active:disabled:opacity-75 。 支持任意样式,例如 md:top-[-113px] 。 开发和生产环境结果是一致的,(我在 vue2 项目中就遇到过组件库构建结果不一致的问题)。   如果你使用 vscode 那你一定要安装 Tailwind CSS IntelliSense [95] 插件,它可以自动补全类名,显著降低学习成本。 8.3 关于打包体积   使用默认配置,未压缩是 3739.4kB ,Gzip压缩 是 293.9kB,Brotli压缩 是 73.2kB。这似乎看起来很大,这是因为 tailwind 提供了成千上万的功能类,其中绝大部分你不会使用到。   当构建生产时,你应该使用 purge 选项来 tree-shake 优化未使用的样式,并优化您的最终构建大小当使用 Tailwind 删除未使用的样式时,很难最终得到超过 10kb 的压缩 CSS。   还有一点, Atom CSS 极大的提升了样式的复用程度,从而直接降低了构建体积。 9.vuex 替代方案 pinia   由于 vuex 4 对 typescript 的支持让人感到难过,所以状态管理弃用了 vuex 而采取了 pinia [96] 。   忘记在哪看到,尤大好像说 pinia [97] 可能会代替 vuex,所以请放心使用。 9.1 为什么采用 Pinia ?Pinia 的 API 设计非常接近 Vuex 5 的提案 [98] 。(作者是 Vue 核心团队成员) 无需像 Vuex 4 自定义复杂的类型来支持 typescript,天生具备完美的类型推断。 模块化设计,你引入的每一个 store 在打包时都可以自动拆分他们。 无嵌套结构,但你可以在任意的 store 之间交叉组合使用。 Pinia 与 Vue devtools 挂钩,不会影响 Vue 3 开发体验。   下面简单的介绍一下如何使用 Pinia,并对比 vuex 有哪些区别与注意事项,具体请参考 官方文档 [99] 。 9.2 创建 Store   Pinia 已经内置在脚手架中,并且与 vue 已经做好了关联,你可以在任何位置创建一个 store: import { defineStore } from "pinia" export const useUserStore = defineStore({ id: "user", state: () =>({}), getters: {}, actions: {} }) 复制代码   这与 Vuex 有很大不同,它是标准的 Javascript 模块导出,这种方式也让开发人员和你的 IDE 更加清楚 store 来自哪里。   Pinia 与 Vuex 的区别: id 是必要的,它将所使用 store 连接到 devtools。 创建方式: new Vuex.Store(...) (vuex3),createStore(...) (vuex4)。 对比于 vuex3 ,state 现在是一个 函数返回对象 。 没有 mutations ,不用担心,state 的变化依然记录在 devtools 中。 9.3 State   创建好 store 之后,可以在 state 中创建一些属性了: state: () => ({ name: "codexu", age: 18 }) 复制代码   将 store 中的 state 属性设置为一个函数,该函数返回一个包含不同状态值的对象,这与我们在组件中定义数据的方式非常相似。   在模板中使用 store:   现在我们想从 store 中获取到 name 的状态,我们只需要使用以下的方式即可:

{{userStore.name}}

const userStore = useUserStore() return { userStore } 复制代码   注意这里并不需要 userStore.state.name 。   虽然上面的写法很舒适,但是你一定不要用解构的方式去提取它内部的值,这样做的话,会失去它的响应式: const { name, email } = useUserStore() 复制代码 9.4 Getters   Pinia 中的 getter 与 Vuex 中的 getter 、组件中的计算属性具有相同的功能,传统的函数声明使用 this 代替了 state 的传参方法,但箭头函数还是要使用函数的第一个参数来获取 state ,因为箭头函数处理 this 的作用范围: getters: { nameLength() { return this.name.length }, nameLength: state => state.name.length, nameLength: ()=> this.name.length } 复制代码 9.5 Actions   这里与 Vuex 有极大的不同,Pinia 仅提供了一种方法来定义如何更改状态的规则, 放弃 mutations 只依靠 Actions ,这是一项重大的改变。   Pinia 让 Actions 更加的灵活: 可以通过 组件 或其他 action 调用 可以从 其他 store 的 action 中调用 直接在商店实例上调用 支持 同步 或异步 有任意数量的参数 可以包含有关如何更改状态的逻辑(也就是 vuex 的 mutations 的作用) 可以 $patch 方法直接更改状态属性 actions: { async insertPost(data){ await doAjaxRequest(data); this.name = "..."; } } 复制代码 9.6 Devtools   脚手架已内置下面的代码,这将添加 devtools 支持: import { createPinia, PiniaPlugin } from "pinia" Vue.use(PiniaPlugin) const pinia = createPinia() 复制代码   时间旅行功能貌似已经可以使用了,这块后续会关注。 10.基于 mitt 处理组件间事件联动   如果你曾经是 Vue2.x 的开发者,那么请阅读下面引用 官方文档 [100] 的一段话: 我们从实例中完全移除了 $on 、 $off 和 $once 方法。 $emit 仍然包含于现有的 API 中,因为它用于触发由父组件声明式添加的事件处理函数。   在 Vue 3 中,已经不可能使用这些 API 从组件内部监听组件自己发出的事件了,该用例暂没有迁移的方法。但是该 eventHub 模式可以被替换为实现了事件触发器接口的外部库,例如 mitt 或 tiny-emitter 。 10.1 为什么选择 mitt ?足够小,仅有 200bytes。 支持全部事件的监听和批量移除。 无依赖,不论是什么框架都可以直接使用。 10.2 严重警告   我们已经无法在项目中使用 eventBus ,仅推荐你在特殊场合 下使用 mitt,它并不是开发的常态 ,你一定要确保知道自己在做什么?否则你的项目将难以维护!!! 10.3 如何使用 mitt ?   在使用 mitt 前建议请阅读 官方文档 [101] :   脚手架默认提供一个可以直接使用的对象: import emitter from "@/libs/emitter"; 复制代码   当然你也可以引入已经安装好的 mitt: import mitt from "mitt" const emitter = mitt() 复制代码   mitt 提供了非常简单的 API,下面代码是官方演示: // listen to an event emitter.on("foo", e => console.log("foo", e) ) // listen to all events emitter.on("*", (type, e) => console.log(type, e) ) // fire an event emitter.emit("foo", { a: "b" }) // clearing all events emitter.all.clear() // working with handler references: function onFoo() {} emitter.on("foo", onFoo) // listen emitter.off("foo", onFoo) // unlisten 复制代码 11.异步请求   绝大多数项目想必逃脱不了接口的对接,如果你的项目存在大量的接口,我建议做到以下几点: 封装请求。 统一的 API 接口管理。 Mock 数据功能(根据需求斟酌使用)。   上述的主要目的就是在帮助我们简化代码和利于后期的更新维护。 11.1 基于 axios 的封装   相信开发过 vue2 项目的同学已经对 axios 非常熟悉的,在这里提供一些封装的思路: 通过 import.meta.env.VITE_APP_BASE_URL 获取环境变量,配置 baseURL ,如果接口存在多个不同域名,可以通过 js 变量控制。 设置 timeout 请求超时、断网情况处理。 设置 请求头 ,携带 token 。 异常拦截处理 ,后端通过你携带的 token 判断你是否过期,如果返回 401 你可能需要跳转到登录页面,并提示需要重新登录。 响应拦截 ,通常后端返回 code、data、msg,如果是请求正常,我们可以直接返回 data 数据,如果是异常的 code,我们也可以在这里直接弹出报错提示。 无感刷新 token ,如果你的 token 过期,可以通过后端返回的 refreshToken 调用刷新接口,获取新的 token。当然这里涉及到很多细节,例如终端请求、重新发送请求、重新请求列队。 中断请求 ,例如页面切换时,我们要中断正在发生的请求。   相关代码(仅供参考) [102] 11.2 为 axios 增加泛型的支持   到目前为止,axios 请求返回的类型是 any,这时我们对请求后的数据进行操作时,没有享受到 ts 带来的类型提示,这显然不符合我们的预期。   这时我们要做的就是重新声明 axios 模块:新建一个 shims.d.ts,然后在调用时加上泛型。 import { AxiosRequestConfig } from "axios"; declare module "axios" { export interface AxiosInstance { (config: AxiosRequestConfig): Promise; request(config: AxiosRequestConfig): Promise; get(url: string, config?: AxiosRequestConfig): Promise; delete(url: string, config?: AxiosRequestConfig): Promise; head(url: string, config?: AxiosRequestConfig): Promise; post(url: string, data?: any, config?: AxiosRequestConfig): Promise; put(url: string, data?: any, config?: AxiosRequestConfig): Promise; patch(url: string, data?: any, config?: AxiosRequestConfig): Promise; } } 复制代码   做好这一步后,你就必须在创建接口时,声明请求相应数据的类型。 11.3 封装更方便的 useRequest   设想一下,编写请求代码时,我们通常会定义这么几个变量: data : 储存请求数据 loading : 请求加载状态   尤其是 loading,我们需要在请求前设置为 true,请求结束后设置为 false。   上面的封装方式,是对基础的功能封装,因为我们在使用 vue3,所以可以进行再一次的封装成为 hook ,我们使用起来会更加方便。   例如下面这个样子:   使用 useRequest 定义一个接口: export default getUserInfo(id) { return useRequest({ method: "get", url: "/api/user", params: { id } }) } 复制代码   使用此接口: const { data, loading } = getUserInfo(); 复制代码   注意这里的 data 是响应式的。   这是我想到的一种思路,目前还没有做很好的封装, 相关代码仅供参考 [103] ,你也可以借鉴一些成熟方案,比如 vueuse 中的 useFetch [104] ,但是他是基于 Fetch API 设计的,并不符合我的预期要求,有更好的方案请大家在下面留言。 11.4 统一的 API 接口管理   自从前端和后端分家之后,前后端接口对接就成为了常态,而对接接口的过程就离不开接口文档,比较主流就是 Swagger,但是如何在前端项目中更好的去管理跟后端对接的接口呢?   在 src 目录中 创建 api 目录,内部目录应按照后端制定的模块创建。   每个模块中创建多个 ts 文件,一个接口应对应一个 ts 文件,其中包含了以下内容: 请求 参数 的类型声明。 响应 数据 的类型声明。 返回定义好的请求函数(url、method、params、data 等)。   统一去定义和管理 API 接口,只要后端规范的命名和你认真的写好类型声明,对前端来说 typescript 就是最好的接口文档。 11.5 mock   vite 使用 mock 数据非常简单,你可以使用 vite-plugin-mock [105] 插件,如果你了解 mockjs,你可以快速上手。 12.路由   路由和菜单是组织起一个应用的关键骨架。 12.1 创建路由三部曲   通常一个项目需要做到这几步: 使用 createRouter 创建路由,这时候根据需求选择 Hash 路由或者 History 路由。 根据业务需求 配置路由 ,注意这里很可能就用到前文提到过的布局组件 。 如果有权限相关的业务,你需要创建 permission.ts 在路由钩子触发时做一些事情。   如果你的页面比较多,建议你创建 routes 目录,分模块声明路由。   参考代码 [106] 12.2 使用 meta 丰富你的路由   vue-router4.x 支持 typescript,配置路由的类型是 RouteRecordRaw,这里 meta 可以让我们有更多的发挥空间,这里提供一些参考: title: string; 页面标题,通常必选。 icon?: string; 图标,一般配合菜单使用。 auth?: boolean; 是否需要登录权限。 ignoreAuth?: boolean; 是否忽略权限。 roles?: RoleEnum[]; 可以访问的角色 keepAlive?: boolean; 是否开启页面缓存 hideMenu?: boolean; 有些路由我们并不想在菜单中显示,比如某些编辑页面。 order?: number; 菜单排序。 frameUrl?: string; 嵌套外链。   这里只提供一些思路,每个项目多多少少会涉及到这些问题,具体如何实现请查阅资料自行解决。 13.项目性能与细节优化13.1 开启 gzip   开启 gzip 可以极大的压缩静态资源,对页面加载的速度起到了显著的作用。   使用 vite-plugin-compression [107] 可以 gzip 或 brotli 的方式来压缩资源,这一步需要服务器端的配合,vite 只能帮你打包出 .gz 文件。此插件使用简单,你甚至无需配置参数,引入即可。 13.2 页面载入进度条   页面路由切换时,附带一个加载进度条会显得非常友好,不至于白屏时间过长,让用户以为页面假死。   这时候我们可以用到 nprogress [108] ,在路由切换时开启和关闭: import NProgress from "nprogress"; router.beforeEach(async (to, from, next) => { NProgress.start(); }); router.afterEach((to) => { NProgress.done(); }); 复制代码 13.3 Title   在不同的路由下显示不同的标题是常规的操作,我们可以通过路由钩子获取 meta 中的 title 属性改变标签页上的 title。   你可以使用 vueuse 提供的 useTitle [109] ,或者 window.document.title 自行封装。   你也可以通过环境变量将你的主标题拼接在路由标题的后面: const { VITE_APP_TITLE } = import.meta.env; 复制代码 13.4 解决移动端使用 vh 的问题   有兴趣的同学可以尝试一下 chrome 移动端浏览器上的 100vh,是真正的视口高度的 100% 嘛。   为了解决这一问题,我们可以通过 postCss 插件解决。   安装 postcss-viewport-height-correction [110] 插件: npm install -D postcss-viewport-height-correction 复制代码   在 postcss.config.js 中增加 plugin: module.exports = { plugins: { "postcss-viewport-height-correction": {}, }, } 复制代码   添加这一段 js 代码在全局,你可以直接添加在 index.html 上即可: const customViewportCorrectionVariable = "vh"; function setViewportProperty(doc) { let prevClientHeight; const customVar = `--${customViewportCorrectionVariable || "vh"}`; function handleResize() { const { clientHeight } = doc; if (clientHeight === prevClientHeight) return; requestAnimationFrame(function updateViewportHeight() { doc.style.setProperty(customVar, `${clientHeight * 0.01}px`); prevClientHeight = clientHeight; }); } handleResize(); return handleResize; } window.addEventListener("resize", setViewportProperty(document.documentElement)); 复制代码 13.5 可以常驻的 JavaScript 库前文提到过的 vueuse [111] ,非常强大,强烈建议尝试。 lodash [112] ,用了都说好,早用早下班。 14.代码风格与流程规范14.1 ESLint   不管是多人合作还是个人项目,代码规范都是很重要的。这样做不仅可以很大程度地避免基本语法错误,也保证了代码的可读性。   这里推荐使用 airbnb 规范。   配置参考 [113] 14.2 StyleLint   尽管前文提到过 tailwind,可以让你几乎不写 css,但是涉及到团队协作,这一点也要严谨。   StyleLint 是一个强大的、现代化的 CSS 检测工具, 与 ESLint 类似, 是通过定义一系列的编码风格规则帮助我们避免在样式表中出现错误,配合编辑器的自动修复,可以很好的统一团队项目 css 风格。   配置参考 [114] 14.3 代码提交规范   在多人协作的背景下,git 仓库和 workflow 的作用很重要。而对于 commit 提交的信息说明存在一定规范,现使用 commitlint + husky 规范 git commit -m "" 中的描述信息。我们都知道,在使用 git commit 时,git 会提示我们填入此次提交的信息。可不要小看了这些 commit,团队中规范了 commit 可以更清晰的查看每一次代码提交记录,还可以根据自定义的规则,自动生成 changeLog 文件。   提交格式(注意冒号后面有空格): [optional scope]: 复制代码 type :用于表明我们这次提交的改动类型。 optional scope:可选,用于标识此次提交主要涉及到代码中哪个模块。 description:一句话描述此次提交的主要内容,做到言简意赅。   Type 类型 build:编译相关的修改,例如发布版本、对项目构建或者依赖的改动 chore:其他修改, 比如改变构建流程、或者增加依赖库、工具等 ci:持续集成修改 docs:文档修改 feat:新特性、新功能 fix:修改bug perf:优化相关,比如提升性能、体验 refactor:代码重构 revert:回滚到上一个版本 style:代码格式修改, 注意不是 css 修改 test:测试用例修改   关于 commitlint + husky 的配置文章有很多,大同小异,请根据自己的实际情况配置。 15.编写使用文档   做到这一步,你的整个脚手架开发已经接近于尾声,但是你做了这么多,你的同事并不知道如何使用,甚至你过一段时间也会忘记,所以你必须养成良好的编写文档习惯。 15.1 使用 vitepress 搭建文档   这里我推荐使用 vuepress 或者 vitepress,说实话你只写文档 vitepress 会让你更舒服,因为它很快。   vitepress [115] 很适合构建博客网站、技术文档,就是因为它可以直接用 markdown 进行书写,所有写过博客的人,都应该对它不陌生。一个 .md 文件,即可生成一张页面,十分方便。   创建一个 vitepress 文档实在是太过于简单,你可以参考官方文档,或者参考我的 文档 [116] 。 15.2 文档部署   如果你的团队可以帮助你搭建 CI/CD 自动部署是再好不过了,如果没有这个条件,你也可以通过 github 提供的 actions 功能,完成自动部署。   代码参考 [117] 16.插件   如果你想更痛快的用上述功能,建议你安装下面的插件。 16.1 VSCode 插件Vue Language Features (Volar) [118] ,你现在查 Volar 可能找不到,你需要的是这个。 Vue 3 Snippets [119] ,vue3 快捷输入。 Tailwind CSS IntelliSense [120] ,tailwind 代码提示。 Stylelint [121] Prettier - Code formatter [122] ESLint [123] 16.2 Chrome 插件Vue.js devtools [124] ,你当然要安装支持 vue3 的版本,而且此版本对 pinia 支持的也非常友好。
成绩直追比亚迪!董明珠这次赌对了,48亿没白白研发点击关注,每天精彩不断!导读成绩直追比亚迪!董明珠这次赌对了,48亿没白白研发!随着中国经济的快速发展,也带动了国内很多科技产业的发展,而我们想要在国际科技市场上拥有更多的话语权,iPhone12mini跌至3499,A14iOS15,不等SE3了大家都知道,随着时代的发展,智能手机的屏幕尺寸越来越大,大屏幕可以一次性阅读更多的内容,而且手机厂商还推出了折叠屏手机,目的就是兼具大屏幕和便携性。在手机市场中,小屏手机销量份额并固件更新久违了,Kindle7ampampampKPW2固件升级至5。12。2。2本次固件版本号为5。12。2。2适用设备型号499入门版Kindle(Kindle7)KindlePaperwhite2(KPW2)更新内容性能改善问题修复及其他一般性功能加强。这每天一个linux命令(mv)功能说明移动或更名现有的文件或目录用法mvOPTIONSOURCEDESTormvOPTIONSOURCEDIRECTORYormvOPTIONtDIRECTORYSOURCE补充超硬核!11个非常实用的Python和Shell拿来就用脚本实例Python脚本部分实例企业微信告警FTP客户端SSH客户端Saltstack客户端vCenter客户端获取域名ssl证书过期时间发送今天的天气预报以及未来的天气趋势Shell脚本金砖二代来了,索尼发布旗舰级音乐播放器NWWM1ZM2IT之家2月9日消息,今天上午,索尼正式发布了旗舰级音乐播放器NWWM1ZM2。官方表示,新品在醇音系列一贯的高水准基础上,再次进行了多种重磅升级。精益求精,宽阔的声场和更富临场感聊聊各品牌手机优点为什么聊聊各品牌手机的优点呢,因为说缺点你们懂的但是也得说上大学的时候用的是波导手机,毕业后用的第一部智能手机是华为C8500,之后从小米1用到小米6,然后用过华为MATE20,M从3499跌至2299元,哈曼卡顿无线充电,这才是真香骁龙870手机说到骁龙870手机,很多网友们第一时间都会想到红米K40吧,这款手机是去年销量最好的一款骁龙870手机,在某东平台上也是唯一一款评价数超过100万的骁龙870手机,在去年双十一当天这个春节3。8亿个微信红包封面被领取带封面微信红包收发总数超50亿个哇,我手气最好!姐,你这个红包封面太好看了,哪里抢的!昆明的姜女士一家春节期间在家庭群里抢红包很热闹,各式各样的红包封面也为抢红包增添了乐趣。2月8日,微信发布2022虎年春节数据电商的作假在这个互联网高速发展的时代,相信大家都会在某猫或者某宝上面买东西吧,那么大家一定会选择旗舰店之类的吧,没什么意外的话,大家一定都觉得旗舰店,肯定是真的,要不然怎么能成为旗舰店,而不人工3D脊髓组织或可让瘫痪者重新行走新华社耶路撒冷2月7日电(记者尚昊吕迎旭)以色列特拉维夫大学7日发布声明说,该校研究人员在世界上首次人工合成3D人体脊髓组织,这一技术或可让瘫痪者重新行走。声明说,该校Sagol再
人工智能专业谁最强?全国215所高校专业教学综合能力排行榜一人工智能专业简介人工智能(ArtificialIntelligence),英文缩写为AI。它是研究开发用于模拟延伸和扩展人的智能的理论方法技术及应用系统的一门新的技术科学。人工智GPU新架构?下代骁龙898跑分数据泄露骁龙下代移动端的CPU还未发布就已经受到了很多玩家的关注,近日一款搭载骁龙898的机型曝出跑分,从数据上来看显卡性能有了大幅提升。骁龙898采用全新架构X2,GPU升级为Adren古代洛阳人为什么发明了洛阳铲?洛阳铲是洛阳人李鸭子在上世纪二三十年代洛阳北邙山盗墓盛行时,为适应迅速找墓并盗掘的需求,而在民间用于挖坑栽桩的椭圆形铲子上改进而成的。这种铲子我最近在襄阳搞发掘时还看到民间在用。如微信摇一摇和漂流瓶关了。现在有什么好的聊天软件和别人聊?谢回答!如果QQ,微信,摇一摇,附近加微聊天统统不能满足你的聊天兴趣或种种诱惑,我想头条私信足以提起您的好奇,因为头条私信聊天,不需复杂的加好友认证不需对方的调查访问不论天南地北,5G时代还没搞明白,中国6G技术却悄悄突破,未来通信或被我国掌握中国成功拿下6G专利的消息像炸弹一样在全球炸开,日本跟印度直呼不可能,美国政府一瞬间坐立难安,他们想不明白为什么在重重封锁下,中国还能以如此迅猛的速度发展,难道之前的封锁是个笑话吗中国有了北斗系统,为什么手机上还是GPS?中国北斗导航系统已经成熟,为何手机导航还用美国的GPS?这3个原因很多人不知道。众所周知,美国的GPS系统是目前世界上最大的全球定位导航系统,并且成熟的技术已经可以无差别的进行全球量子纠缠的速度是光速的起码10000倍,违反相对论吗?当然违反相对论,原因在于相对论是有边界条件的,这个边界条件就是假设了光子或量子的质量为零,以及光速是宇宙中的最大速度等。但是从黑洞能够吸入光子或量子的事实证明,其质量不为零,只是我宇宙大爆炸迅速膨胀,数以亿计的天体以超光速四散远离,你信吗?有什么依据吗?自然界最本质的特征就是变化,不存在一成不变的事物。而且,自然界的变化是不连续的,存在着质的变化。所以,其呈现在我们面前的,是一个大千的世界。因此,我们对外在客观世界的认识,既是有层如何看待遗体被切片的数字人?之前我们采访过中国数字人之父钟世镇,木想到当时做的这么冷门的笔记今天竟然会用上,喔呵呵呵所谓数字人非常神奇,可能很多人都不知道所谓数字人什么鬼。简单来说,我们将一个生前健康的人的遗卖的最火的手机是哪些?感谢邀请卖的最火的手机是哪些?题主问题的核心是卖的最火的手机是哪些?我一直觉得苹果手机算是众多手机品牌中算是最火爆的,因为毕竟他凭借一年三款手机,销量都可以来到上亿,能力可见一斑。9月最新数据库排行榜出炉,前三都很稳最近,DBEngines发布了9月份最新数据库排名,此份榜单是根据数据库系统受欢迎程度进行的排名,每月更新一次,为数据库相关从业人员提供了一个技术方向的参考。DBEngines9月