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

Electron结合React和TypeScript进行开发

  结合React+TypeScript进行Electron开发1. electron基本简介
  electron是使用JavaScript,HTML和CSS构建 跨平台 的 桌面应用程序 。我们可以使用一套代码打包成Mac、Windows和Linux的应用,electron比你想象的更简单,如果把你可以建一个网站,你就可以建一个桌面应用程序,我们只需要把精力放在应用的核心上即可。
  为什么选择electron?Electron 可以让你使用纯JavaScript调用丰富的原生APIs来创造桌面应用。你可以把它看作是专注于桌面应用。 在PC端桌面应用开发中,nwjs和electron都是可选的方案,它们都是基于Chromium和Node的结合体,而electron相对而言是更好的选择方案,它的社区相对比较活跃,bug比较少,文档相对利索简洁。 electron相对来说比nw.js靠谱,有一堆成功的案例:Atom编辑器 Visual Studio Code WordPress等等。 Node.js的所有内置模块都在Electron中可用。 2. 快速上手2.1 安装React(template为ts)yarn create react-app electron-demo-ts --template typescript2.2 快速配置React
  工程架构
  index.html                                   electron App              
  App.tsx import React from "react" export default function App() {  return (    App  )}
  index.tsx import React from "react";import ReactDOM from "react-dom/client";import App from "./App";import reportWebVitals from "./reportWebVitals"; const root = ReactDOM.createRoot(  document.getElementById("root") as HTMLElement);root.render(  //       // ); // If you want to start measuring performance in your app, pass a function// to log results (for example: reportWebVitals(console.log))// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitalsreportWebVitals();2.3 安装electron
  将 electron  包安装到您的应用程序的devDependencies  .// npmnpm install --save-dev electron// yarnyarn add --dev electron2.4 配置main.js、preload.js和package.json文件
  main.js // 导入app、BrowserWindow模块// app 控制应用程序的事件生命周期。事件调用app.on("eventName", callback),方法调用app.functionName(arg)// BrowserWindow 创建和控制浏览器窗口。new BrowserWindow([options]) 事件和方法调用同app// Electron参考文档 https://www.electronjs.org/docsconst {app, BrowserWindow, nativeImage } = require("electron")const path = require("path")// const url = require("url");  function createWindow () {    // Create the browser window.    const mainWindow = new BrowserWindow({        width: 800, // 窗口宽度        height: 600,  // 窗口高度        // title: "Electron app", // 窗口标题,如果由loadURL()加载的HTML文件中含有标签,该属性可忽略        icon: nativeImage.createFromPath("public/favicon.ico"), // "string" || nativeImage.createFromPath("public/favicon.ico")从位于 path 的文件创建新的 NativeImage 实例        webPreferences: { // 网页功能设置            webviewTag: true, // 是否使用<webview>标签 在一个独立的 frame 和进程里显示外部 web 内容            webSecurity: false, // 禁用同源策略            preload: path.join(__dirname, "preload.js"),            nodeIntegration: true // 是否启用node集成 渲染进程的内容有访问node的能力,建议设置为true, 否则在render页面会提示node找不到的错误        }    })      // 加载应用 --打包react应用后,__dirname为当前文件路径    // mainWindow.loadURL(url.format({    //   pathname: path.join(__dirname, "./build/index.html"),    //   protocol: "file:",    //   slashes: true    // }));         // 因为我们是加载的react生成的页面,并不是静态页面    // 所以loadFile换成loadURL。    // 加载应用 --开发阶段  需要运行 yarn start    mainWindow.loadURL("http://localhost:3000");     // 解决应用启动白屏问题    mainWindow.on("ready-to-show", () => {        mainWindow.show();        mainWindow.focus();    });     // 当窗口关闭时发出。在你收到这个事件后,你应该删除对窗口的引用,并避免再使用它。    mainWindow.on("closed", () => {        mainWindow = null;    });        // 在启动的时候打开DevTools    mainWindow.webContents.openDevTools()} app.allowRendererProcessReuse =true; // This method will be called when Electron has finished// initialization and is ready to create browser windows.// Some APIs can only be used after this event occurs.app.whenReady().then(() =>{    console.log("qpp---whenready");    createWindow();}) // Quit when all windows are closed.app.on("window-all-closed", function () {    // On macOS it is common for applications and their menu bar    // to stay active until the user quits explicitly with Cmd + Q    console.log("window-all-closed");    if (process.platform !== "darwin") app.quit()}) app.on("activate", function () {    // On macOS it"s common to re-create a window in the app when the    // dock icon is clicked and there are no other windows open.    if (BrowserWindow.getAllWindows().length === 0) createWindow()}) // In this file you can include the rest of your app"s specific main process// code. You can also put them in separate files and require them here.
  package.json
  这时候我们来修改 package.json  文件。配置启动文件,添加 main  字段,我们这里也就是main.js文件。如果没有添加,Electron 将尝试加载包含在package.json  文件目录中的index.js  文件。配置运行命令,使用 "electron": "electron ."  区别于react的启动命令 "start": "react-scripts start", 安装concurrently:  yarn add concurrently  {    ...    "main": "main.js", // 配置启动文件  	"homepage": ".", // 设置应用打包的根路径    "scripts": {        "start": "react-scripts start",  // react 启动命令        "build": "react-scripts build",        "test": "react-scripts test",        "eject": "react-scripts eject",        "electron": "electron .",  // electron 启动命令        "dev": "concurrently "npm run start" "npm run electron""    },}
  preload.js window.addEventListener("DOMContentLoaded", () => {    const replaceText = (selector, text) => {        const element = document.getElementById(selector)            if (element) element.innerText = text    }      for (const dependency of ["chrome", "node", "electron"]) {        replaceText(`${dependency}-version`, process.versions[dependency])    }})
  此时的工程架构
  2.5 运行electron项目先 yarn start   然后再开一个终端yarn electron  或者是 npm run dev
  其实我们就可以看出Electron就是一个应用套了一个谷歌浏览器壳子,然后里面是前端页面。 2.6 打包项目
  使用 electron-packager 依赖: yarn add --dev electron-packager
  package.json配置打包命令: "package": "electron-packager . bleak-electron-app --platform=win32 --arch=x64 --overwrite --electron-version=18.1.0 --icon=./public/favicon.ico"
  配置解释: electron-packager <应用目录> <应用名称> <打包平台> <架构x86 还是 x64> <架构> <electron版本> <图标>overwrite 如果输出目录已经存在,替换它
  然后运行命令: yarn package
  打包时间慢的话可按照下面两种方式优化: 方法1:在执行electron-packager前先运行set ELECTRON_MIRROR=http://npm.taobao.org/mirrors/electron/方法2:在electron-packager命令行加入参数--download.mirrorOptions.mirror=https://npm.taobao.org/mirrors/electron/(Windows x64)完整版如下:electron-packager . bleak-electron-app --platform=win32 --arch=x64 --overwrite --electron-version=18.0.4 --download.mirrorOptions.mirror=https://npm.taobao.org/mirrors/electron/
  然后运行 bleak-electron-app-win32-x64  里面的exe文件就可以了。
  3. 自动刷新页面
  当你用react开发的时候,网页内容会自动热更新,但是electron窗口的main.js中代码发生变化时不能热加载。
  安装插件electron-reloader: yarn add --dev electron-reloadernpm install --save-develectron-reloader
  然后在路口引用插件: const reloader = require("electron-reloader")reloader(module)
  就可以实现electron插件热更新。 4. 主进程和渲染进程
  Electron运行package.json的main脚本的进程称为 主进程 。在主进程中运行的脚本通过创建web页面来展示用户节面,一个Electron应用总是有且只有一个主进程。
  由于Electron使用了Chromium来展示web页面,所以Chromium的多进程架构也被使用到,每个Electron钟大哥web页面运行在它的叫 渲染进程 的进程中。
  在普通的浏览器中,web页面无法访问操作系统的原生资源。然而Electron的用户在Node.js的API支持下可以在页面中和操作系统进行一些底层交互。
  ctrl + shift + i 打开渲染进程调试(devtools)
  默认打开调试: // 在启动的时候打开DevToolsmainWindow.webContents.openDevTools()5.定义原生菜单、顶部菜单5.1 自定义菜单
  可以使用Menu菜单来创建原生应用菜单和上下文菜单。 首先判断是什么平台,是mac还是其他: const isMac = process.platform === "darwin"创建菜单模板:
  其是由一个个MenuItem组成的,可以在菜单项官网API查看。 const template = [  // { role: "appMenu" }  // 如果是mac系统才有  ...(isMac ? [{    label: app.name,    submenu: [      { role: "about" },      { type: "separator" },      { role: "services" },      { type: "separator" },      { role: "hide" },      { role: "hideOthers" },      { role: "unhide" },      { type: "separator" },      { role: "quit" }    ]  }] : []),  // { role: "fileMenu" }  {    label: "文件",    submenu: [      isMac ? { role: "close" } : { role: "quit", label: "退出" }    ]  },  // { role: "editMenu" }  {    label: "编辑",    submenu: [      { role: "undo", label: "撤消" },      { role: "redo", label: "恢复" },      { type: "separator" },      { role: "cut", label: "剪切" },      { role: "copy", label: "复制" },      { role: "paste", label: "粘贴" },      ...(isMac ? [        { role: "pasteAndMatchStyle" },        { role: "delete" },        { role: "selectAll" },        { type: "separator" },        {          label: "Speech",          submenu: [            { role: "startSpeaking" },            { role: "stopSpeaking" }          ]        }      ] : [        { role: "delete", label: "删除" },        { type: "separator" },        { role: "selectAll", label: "全选" }      ])    ]  },  // { role: "viewMenu" }  {    label: "查看",    submenu: [      { role: "reload", label: "重新加载" },      { role: "forceReload", label: "强制重新加载" },      { role: "toggleDevTools", label: "切换开发工具栏" },      { type: "separator" },      { role: "resetZoom", label: "原始开发工具栏窗口大小" },      { role: "zoomIn", label: "放大开发工具栏窗口"},      { role: "zoomOut", label: "缩小开发工具栏窗口" },      { type: "separator" },      { role: "togglefullscreen", label:"切换开发工具栏全屏" }    ]  },  // { role: "windowMenu" }  {    label: "窗口",    submenu: [      { role: "minimize", label:"最小化" },      ...(isMac ? [        { type: "separator" },        { role: "front" },        { type: "separator" },        { role: "window" }      ] : [        { role: "close", label: "关闭" }      ])    ]  },  {    role: "help",    label: "帮助",    submenu: [      {        label: "从Electron官网学习更多",        click: async () => {          const { shell } = require("electron")          await shell.openExternal("https://electronjs.org")        }      }    ]  }]根据模板创建menu: const menu = Menu.buildFromTemplate(template)设置菜单: Menu.setApplicationMenu(menu)5.2 给菜单定义点击事件
  可以通过 click  属性来设置点击事件5.3 抽离菜单定义
  创建一个menu.js: const {app, Menu } = require("electron") const isMac = process.platform === "darwin" const template = [  // { role: "appMenu" }  // 如果是mac系统才有  ...(isMac ? [{    label: app.name,    submenu: [      { role: "about" },      { type: "separator" },      { role: "services" },      { type: "separator" },      { role: "hide" },      { role: "hideOthers" },      { role: "unhide" },      { type: "separator" },      { role: "quit" }    ]  }] : []),  // { role: "fileMenu" }  {    label: "文件",    submenu: [      isMac ? { role: "close" } : { role: "quit", label: "退出" }    ]  },  // { role: "editMenu" }  {    label: "编辑",    submenu: [      { role: "undo", label: "撤消" },      { role: "redo", label: "恢复" },      { type: "separator" },      { role: "cut", label: "剪切" },      { role: "copy", label: "复制" },      { role: "paste", label: "粘贴" },      ...(isMac ? [        { role: "pasteAndMatchStyle" },        { role: "delete" },        { role: "selectAll" },        { type: "separator" },        {          label: "Speech",          submenu: [            { role: "startSpeaking" },            { role: "stopSpeaking" }          ]        }      ] : [        { role: "delete", label: "删除" },        { type: "separator" },        { role: "selectAll", label: "全选" }      ])    ]  },  // { role: "viewMenu" }  {    label: "查看",    submenu: [      { role: "reload", label: "重新加载" },      { role: "forceReload", label: "强制重新加载" },      { role: "toggleDevTools", label: "切换开发工具栏" },      { type: "separator" },      { role: "resetZoom", label: "原始开发工具栏窗口大小" },      { role: "zoomIn", label: "放大开发工具栏窗口"},      { role: "zoomOut", label: "缩小开发工具栏窗口" },      { type: "separator" },      { role: "togglefullscreen", label:"切换开发工具栏全屏" }    ]  },  // { role: "windowMenu" }  {    label: "窗口",    submenu: [      { role: "minimize", label:"最小化" },      ...(isMac ? [        { type: "separator" },        { role: "front" },        { type: "separator" },        { role: "window" }      ] : [        { role: "close", label: "关闭" }      ])    ]  },  {    role: "help",    label: "帮助",    submenu: [      {        label: "从Electron官网学习更多",        click: async () => {          const { shell } = require("electron")          await shell.openExternal("https://electronjs.org")        }      }    ]  }] const menu = Menu.buildFromTemplate(template)Menu.setApplicationMenu(menu)
  然后在 main.js  中createWindow  的方法使用require  调用:const createWindow = () => {    ......    require("./menu")    ......}5.4 自定义顶部菜单
  我们可以自定义顶部菜单,通过以下两个步骤进行: 先通过frame创建无边框窗口。 function createWindow () {    const mainWindow = new BrowserWindow({        ......        frame: false    })    }然后再通过前端页面布局设置顶部菜单
  如果想让顶部菜单支持拖拽,可以加如下css: -webkit-app-region: drag;5.5 在渲染进程中使用主进程方法remote和electron(点击创建新窗口)
  我们想要通过 remote 来使用主进程方法和功能。 首先要安装 @electron/remote  yarn add @electron/remote在主进程main.js中配置remote: const remote = require("@electron/remote/main")remote.initialize() const createWindow = () => {    let mainWindow = new BrowserWindow({        ......        webPreferences: { // 网页功能设置        	......            nodeIntegration: true, // 是否启用node集成 渲染进程的内容有访问node的能力,建议设置为true, 否则在render页面会提示node找不到的错误            contextIsolation : false, //允许渲染进程使用Nodejs        }    })    remote.enable(mainWindow.webContents)}在渲染进程中使用remote的BrowserWindow:App.tsx import React from "react"// 使用electron的功能// const electron = window.require("electron")// 使用remoteconst { BrowserWindow } = window.require("@electron/remote") export default function App() {  const openNewWindow = () => {    new BrowserWindow({      width:500,      height:500    })  }   return (          App              <button onClick={openNewWindow}>点我开启新窗口</button>            )}
  我们想要通过使用electron提供给渲染进程的API: const electron = window.require("electron")
  然后从electron中提取方法。 5.6 点击打开浏览器
  使用electron中的shell可以实现此功能: import React from "react"// 使用electron的功能// const electron = window.require("electron")// 使用remote// const { BrowserWindow } = window.require("@electron/remote")// 使用shellconst { shell } = window.require("electron") export default function App() {  const openNewWindow = () => {    shell.openExternal("https://www.baidu.com")  }   return (          App              <button onClick={openNewWindow}>点我开启新窗口打开百度</button>            )}6. 打开对话框读取文件6.1 读取文件
  主进程中的dialog模块可以显示用于打开和保存文件、警报等的本机系统对话框。
  因为dialog模块属于主进程,如果我们在渲染进程中需要使用则需要使用remote模块。
  App.tsx import React,{ useRef } from "react"// 使用electron的功能// const electron = window.require("electron") // 使用remote// const remote = window.require("@electron/remote")// const { BrowserWindow } = window.require("@electron/remote")const { dialog } = window.require("@electron/remote") // 使用shellconst { shell } = window.require("electron") // 使用fsconst fs = window.require("fs") export default function App() {  // ref   const textRef = useRef<HTMLTextAreaElement | null>(null)   const openNewWindow = () => {    shell.openExternal("https://www.baidu.com")  }   const openFile = () => {    const res = dialog.showOpenDialogSync({      title: "读取文件", // 对话框窗口的标题      buttonLabel: "读取", // 按钮的自定义标签, 当为空时, 将使用默认标签。      filters: [ // 用于规定用户可见或可选的特定类型范围        //{ name: "Images", extensions: ["jpg", "png", "gif", "jpeg", "webp"] },        //{ name: "Movies", extensions: ["mkv", "avi", "mp4"] },        { name: "Custom File Type", extensions: ["js"] },        { name: "All Files", extensions: ["*"] },      ]    })    const fileContent:string  = fs.readFileSync(res[0]).toString();    (textRef.current as HTMLTextAreaElement).value = fileContent  }   return (          App Test              <button onClick={openNewWindow}>点我开启新窗口打开百度</button>                    <button onClick={openFile}>打开文件</button>        <textarea ref={textRef}></textarea>            )}6.2 保存文件
  保存文件需要使用dialog函数里的 showSaveDialogSync  ,与之前的读取文件所用到的showOpenDialogSync  类似:const saveFile = () => {    const res = dialog.showSaveDialogSync({        title:"保存文件",        buttonLable: "保存",        filters: [            { name: "index", extensions: ["js"]}        ]    })    fs.writeFileSync(res, textRef.current?.value)}7. 定义快捷键7.1 主线程定义
  引入 globalShortcut  const {app, BrowserWindow, nativeImage, globalShortcut } = require("electron")
  注册快捷键打印字符串、窗口最大化、窗口最小化、关闭窗口。 const createWindow = () => {    ......    // 注册快捷键    globalShortcut.register("CommandOrControl+X", () => {        console.log("CommandOrControl + X is pressed")    })     globalShortcut.register("CommandOrControl+M", () => {        mainWindow.maximize()    })     globalShortcut.register("CommandOrControl+T", () => {        mainWindow.unmaximize()    })     globalShortcut.register("CommandOrControl+H", () => {        mainWindow.close()    })     // 检查快捷键是否注册成功    // console.log(globalShortcut.isRegistered("CommandOrControl+X"))} // 将要退出时的生命周期,注销快捷键app.on("will-quit", () => {    // 注销快捷键    globalShortcut.unregister("CommandOrControl+X")    // 注销所有快捷键    globalShortcut.unregisterAll()})7.2在渲染进程中定义
  通过retmote来定义 const { globalShortcut } = window.require("@electron/remote")  globalShortcut.register("Ctrl+O", () => {    console.log("ctrl+O is pressed.")})8. 主进程和渲染进程通讯
  在渲染进程使用ipcRenderer,主进程使用ipcMain,可以实现主进程和渲染进程的通讯:
  App.tsx ......import React,{ useState, useRef } from "react"const { shell, ipcRenderer } = window.require("electron")export default function App() {    // state  	const [windowSize, setWindowSize] = useState("max-window")    ......    // 传参    const maxWindow = () => {        ipcRenderer.send("max-window", windowSize);        if(windowSize === "max-window") {            setWindowSize("unmax-window")        } else {            setWindowSize("max-window")        }    }        ......        return (                                                        <button onClick={maxWindow}>与主进程进行通讯,窗口最大化或取消窗口最大化</button>                                                        )}
  main.js const {app, BrowserWindow, nativeImage, globalShortcut, ipcMain } = require("electron")const createWindow = () => {    let mainWindow = ......    ......    // 定义通讯事件    ipcMain.on("max-window", (event, arg) => {        if(arg === "max-window") {            mainWindow.maximize()        } else if (arg === "unmax-window") {            mainWindow.unmaximize()        }    })    ......}......
  原文链接:Electron结合React和TypeScript进行开发 - bleaka - 博客园</pre><hr>
<div class="middle_list"><a href="at_84897.html">NASA将再次向宇宙发送信息,科学家表示担忧,为何我们还要发?</a>前些天,英国科学家表示,有关美国国家航空航天局计划将地球信息发送到外太空的计划公之于众,这也引起了各界的关注。目前,NASA领导的研究团队正在支持并推进一项名为银河系灯塔的计划,作<a href="at_84898.html">比钢铁硬100亿倍,宇宙中最硬的物质!来自中子星的硬菜</a>科学家如果想要开脑洞,那他们的想象力可比一般人大得多。在核物理和天文学中,科学家就把一种天体当作了一种菜肴,这是什么天体呢?致密星中最恐怖的两个存在黑洞和中子星这便是中子星,一颗致<a href="at_84899.html">如幻如梦的金梭岛</a>这次去大理,住在洱海中的金梭岛,据说是洱海唯一可以居住的岛屿,目前还没有桥梁相连,只能依靠船只来往。从高空往下看,它像一个织梭横卧在洱海上,在大理一带的传说中,天上一位善织彩锦的仙<a href="at_84900.html">1000元人民币在缅甸可以玩得爽吗?听听缅甸姑娘怎么说</a>现如今,出国旅游已经成为了大多数国人们享受生活的主要方式之一了。(此处已添加小程序,请到今日头条客户端查看)由于我国的假期时间相对较短,因此国人们在选择出国旅游的时候,都会选择去周<a href="at_84901.html">适合自驾游听的六首歌曲,嗨起来出发啦</a>01曾经的你词许巍曲许巍演唱许巍许巍的歌很多都适合在旅行中听,特别是长时间的自驾,其实除了曾经的你以外,旅行完美生活蓝莲花等都是不错的选择。02再见杰克词高虎曲高虎演唱痛仰乐队想要<a href="at_84902.html">读万卷书,更要行万里路</a>漠河,大兴安岭,福建土楼,阳朔,开平碉堡,神农架,泸沽湖,稻城亚丁,西双版纳,香格里拉,腾冲,雅鲁藏布江大峡谷,林芝,阿里,贡嘎雪山,喀拉峻,伊犁,赛里木湖,喀纳斯,额济纳,平遥古<a href="at_84903.html">人到中年,肠胃消化有问题的人,吃东西要记住三吃,三不吃</a>人到中年,无论是生活还是工作中,繁重的压力向我们袭来,都会导致人会出现一些消化系统上的问题。如果你再不重视自己的胃部健康,小病酿成大病,拖累的可不止是你一个人。在日常的饮食中就要格<a href="at_84904.html">幼师做了一件事,孩子出门不再缠着买东西,8岁前培养财商很重要</a>你家孩子没买到想要的东西,会怎么办?前几天去超市买东西,在服装区,看到一排艾莎公主裙,很是好看。只是与之不和谐的,是一个10岁左右的小姑娘,躺在地上闹。从她和妈妈的吵闹中大概得知,<a href="at_84905.html">五一假期游览文明有序,大运河文化旅游景区装扮一新</a>近日,随着京杭大运河实现百年来首次全线水流贯通,北京(通州)大运河文化旅游景区创建国家5A级旅游景区工作全面展开。景区作为大运河缤纷旅游带上的重要节点,面向游客特别推出了五一体验游<a href="at_84906.html">钟南山院士称他为健康食物常吃这些东西完成健康早餐吧</a>1超级水果橙子橙子中含有丰富的果胶蛋白质钙磷铁及维生素B1B2C等多种营养成分,尤其是维生素C的含量最高。中医认为橙子有生津止渴,舒肝理气通乳消食开胃等功效,有很好的补益作用。2鸡<a href="at_84907.html">NBA半决赛拉开战幕,东西决你更期待谁的到来</a>如果说附加赛只是开胃小菜,季后赛首轮也更多承担着军备练兵作用的话,那么接下来东西区半决赛就是真正厮杀的舞台。大幕拉开,战士已就位!西部太阳(1)vs独行侠(4)回首两支球队季后赛首</div>
<div class="middle_page"><a href="/udt/ls_8630.html"><<<</a><a href="/udt/ls_8629.html"><<</a><a href="/udt/ls_8628.html"><</a><span>-</span><a href="/udt/ls_8626.html">></a><a href="/udt/ls_8625.html">>></a><a href="/udt/ls_8624.html">>>></a></div></div>
<div class="middle_right"><a href="https://www.vkhz.com/think.html"><img src="/static/vkhz.png" width="100%"></a><a href="at_202934.html">压哨改写命运,韩国队兑现奇迹</a>以卡瓦尼(左)和苏亚雷斯(右)为代表的乌拉圭黄金一代,就此悲情谢幕。视觉中国本报记者谷苗再次展现我们的激情和努力,加上一点点运气,就能创造奇迹。金英权的赛前豪言,在韩国与葡萄牙的比<a href="at_202935.html">特种钢,钢种之王,我国特种钢研发生产任重道远</a>特种钢,特指特殊用途的钢铁,是指经国家冶金工业部批准,在冶金产品生产过程中添加一定的化学成分和合金元素,用以提高产品的性能,具有高强度高硬度耐磨性耐腐蚀性,并具有良好的塑性减磨及机<a href="at_202936.html">资讯热点12月05日国内11月生猪价格环比下降7。4</a>速读摘要证监会表态要建设中国特色资本市场,国内11月生猪价格环比下降7。4,全国多地进一步优化管控政策,首届中阿峰会将在12月9日举办,厂商调降户储产品增速预期。媒体精选1。证监会<a href="at_202937.html">对比CarLife,CarPlay究竟好用在哪里?</a>文Muse测评相信有车的朋友,大多数都对CarLife深恶痛绝,相反,苹果的CarPlay却备受推崇,甚至很多人会因为支持CarPlay而考虑入手一台车。还有很多原生只支持CarL<a href="at_202938.html">购置补贴和免费绿牌倒计时,上海购买插混新能源车赶还得上吗?</a>头条创作挑战赛分享用车生活,减少大家踩坑朋友们,大家好,我是辉哥新能源车购置补贴和上海插混新能源车免费绿牌政策截止同步倒计时,两个政策都是到2022年12月31日截止,而今天已经是<a href="at_202939.html">华为最保值的机型已出炉,快来看看是不是你用的那部?</a>最近有好很对小伙伴问我现在华为最保值的手机是那一部?关于这个华为手机这些年的保值率明显提高,可以说比苹果手机的保值率还高,随着华为mate50系列的发布很多人都在问我同样一个问题那<a href="at_202940.html">截至目前,盘点搭载骁龙888Plus的手机</a>1小米MIX4全球首发骁龙888Plus旗舰处理器,采用三星5nm的制程工艺,最高主频达3。0GHz,并行计算效率大大增强,拥有卓越的性能,但功耗翻车,发热非常严重正面是一块6。6<a href="at_202941.html">记者调查智能手表真的防水吗?</a>视频加载中宣称20米防水50米防水的智能手表,却戴着游泳都不行?目前,市面上众多智能手表都以卓越的防水性能作为卖点,但是不少消费者却反映,他们购买的智能手表其实防水功能并不佳。那么<a href="at_202942.html">笔电售后大解析?以惠普战66为例详细拆解售后服务</a>随着科技水平的发展与消费习惯的改变,人们在选购一台笔记本电脑时,着重考量的不再简单的是其性能能否满足自己的日常所需,而是对售后服务越来越看重。尤其对于许多轻薄本用户来讲,笔记本电脑<a href="at_202943.html">原神1600原石奖励来了,原神动画曝光,6号或将停服一天</a>各位旅行者,你们好呀,小编今天给大家带来了最新消息!!我们一起来看看都有哪些值得我们关注的新内容吧!原神荣获2022年度索尼大奖特等奖,和原神一同获奖的是艾尔登法环,由此可以看出,<a href="at_202944.html">免费的手游代理好做吗?</a>很多广告宣传入行手游代理分分钟赚大钱,其实不要太天真,一口吃一个大胖子。手游代理推广是一个慢慢累积的过程。在推广的过程中,慢慢累积玩家资源,最终量变引起质变。做手游代理要保持游戏持<div class="middle_right_youlian"></div></div></div>
</body></html>