vue3 和vue2 的比较
文章目录
- 生命周期
- 多根节点
- Composition API组合式API
- Options API与composition API对比
- 优化逻辑组织
- 优化逻辑复用
- 异步组件(Suspense)
- Suspense组件
- 响应式原理
- 性能
- 体积优化
- 编译优化
- diff算法优化
- 静态提升
- 数据劫持(响应式系统)优化
生命周期
vue3在组合API中使用生命周期钩子时需要先引入,而vue2在选项API中可以直接调用钩子
setup是围绕beforeCreate和created生命周期钩子运行的,所以不需要显式地去定义
多根节点
vue2中,在模板中如果使用多个根节点时会报错,而vue3 支持多个根节点
Composition API组合式API
vue2 是选项式API(Options API),一个逻辑灰散乱在文件的不同位置(data、props、computed、watch、生命周期等),导致代码地可读性变差。
vue3组合式API(Composition PI)则很好地解决了这个问题,可将同一逻辑的内容写到一起,增强了代码的可读性、内聚性,其还提供了较为完美的逻辑复用性方案。
Options API与composition API对比
优化逻辑组织
Options API 碎片化使得理解和维护复杂组件变得困难, 选项的分离掩盖了潜在的逻辑问题。此外,在处理单个逻辑关注点时,我们必须不断地“跳转”相关代码的选项块
Compositon API 将某个逻辑关注点相关的代码全都放在一个函数里,这样当需要修改一个功能时,就不再需要在文件中跳来跳去
function useCount() {let count = ref(10);let double = computed(() => {return count.value * 2;});const handleConut = () => {count.value = count.value * 2;};console.log(count);return {count,double,handleConut,};
}
组件上使用count
export default defineComponent({setup() {const { count, double, handleConut } = useCount();return {count,double,handleConut}},
});
优化逻辑复用
在vue2中,我们是通过mixin实现功能混合,如果多个mixin混合,会存在两个非常明显的问题:命名冲突和数据来源不清晰
而通过composition这种形式,可以将一些复用的代码抽离出来作为一个函数,只要的使用的地方直接进行调用即可
在vue2中,通过mixin实现功能混合的缺陷
1.命名冲突:如果多个 Mixin 中包含了相同的选项,会导致命名冲突,这可能会导致不可预期的行为。
2.隐式依赖:当多个 Mixin 依赖于相同的属性或方法时,可能会出现隐式的依赖关系,使得代码难以维护和理解。
3.耦合性增强:Mixin 可能会导致组件与多个不同的代码片段紧密耦合,这会增加代码的复杂度和维护难度。
4.全局污染:如果一个 Mixin 修改了全局对象或其他共享资源,可能会影响到整个应用程序。
5.不可追踪性:当一个组件使用了多个 Mixin 时,很难追踪每一个 Mixin 对组件行为的影响。
6.调试困难:当出现问题时,定位问题所在可能会比较困难,特别是当多个 Mixin 交叉影响时。
7.组件复用性:过度使用 Mixin 可能会导致组件的复用性降低,因为组件的功能散布在多个 Mixin 中。
8.组件难以理解:Mixin 可能会导致组件的行为变得复杂,特别是当多个 Mixin 互相影响时,会使得组件的行为难以理解。
因此,在使用 Vue 2 中的 Mixin 时,需要谨慎考虑,尽量避免上述问题的出现。同时,也可以考虑使用其他方式,如使用组件复合、插槽(slot)、高阶组件(Higher Order Component)等来达到类似的功能复用效果,但更加灵活和可控。vue3 的组合式API很好解决了这种问题
在 Vue 3 中,提供了 Composition API(组合式 API)作为一种新的组件组织方式,它可以更好地解决了在 Vue 2 中使用 Mixin 可能出现的一些问题:
命名冲突问题减少:Composition API 使用函数组合的方式,可以将相关的逻辑组织在一个函数内部,减少了命名冲突的可能性。
1.明确的依赖关系:Composition API 允许你在组件内部明确地声明你的依赖关系,这使得组件的依赖关系更加清晰。
2.提供了更强大的逻辑封装:通过 Composition API,可以更灵活地组合和封装逻辑,使得代码更易于理解和维护。
3.模块化和可组合性:Composition API 鼓励将逻辑以函数的形式封装,这使得逻辑可以更容易地进行模块化和复用。
4.代码的可追踪性:由于逻辑被封装在函数内部,所以在组件内部可以更容易地追踪逻辑的来源和影响。
5.更好的代码隔离:Composition API 允许你将逻辑按功能组织在不同的函数中,从而实现更好的代码隔离,减少了耦合性。
总的来说,Composition API 提供了一种更灵活、可组合、可控的方式来组织组件的逻辑,相比于 Vue 2 的 Mixin,可以更好地解决了命名冲突、依赖关系不清晰等问题,使得组件的代码更容易理解、维护和复用。
异步组件(Suspense)
Vue3提供Suspense组件,允许程序在等待异步组件加载完成前渲染兜底的内容,如loading,使用户的体验更加平滑。使用它,需要在模板中声明,并包括两个名命插槽:default和fallback。Suspense确保加载完异步内容时显示默认插槽,并将fallback插槽用作加载状态
<tempalte><suspense><template #default><List /></template><template #fallback><div>Loading...</div></template></suspense>
</template>
Suspense组件
vue3中增加了一个名为Suspense的内置组件,用于在异步组件加载完成前显示占位符,避免页面空白或显示错误信息,提高用户体验。
注意:是一项实验性功能,它不一定灰最终成为稳定功能,并且在稳定之前相关API也可能会发生变化。
<template><div><Suspense><template #default><AsyncComponent /></template><template #fallback><div>Loading...</div></template></Suspense></div>
</template>
<script setup lang="ts">
import { defineAsyncComponent } from 'vue'
const AsyncComponent = defineAsyncComponent(() => import('./AsyncComponent.vue'))
</script>
注意事项:
Suspense
组件只能包含一个异步组件,否则会抛出错误fallback
插槽中的内容只能是一个单独的元素,否则会抛出错误- 异步组件必须通过
defineAsynsComponent
方法定义,否则无法使用Suspense组件。 - 为了提高用户体验,建议在fallback插槽中显示一个占位符,如Loading
响应式原理
Vue2 响应式原理的基础是Object.defineProperty
Vue3的响应式原理是Proxy
Object.defineProperty基本用法:直接在一个对象上定义新的属性或修改现有的属性,并返回对象
// 创建一个空对象
const person = {};// 使用 Object.defineProperty 定义属性
Object.defineProperty(person, 'name', {value: 'John', // 属性值writable: false, // 不可写enumerable: true, // 可枚举configurable: false // 不可配置
});// 尝试修改属性值会失败,因为属性是不可写的
person.name = 'Mike';// 遍历对象的属性
for (let key in person) {console.log(key); // 输出 'name',因为属性是可枚举的
}// 删除属性会失败,因为属性是不可配置的
delete person.name;// 重新定义属性为可配置
Object.defineProperty(person, 'name', {configurable: true
});// 现在可以成功删除属性
delete person.name;
vue2核心源码:
function defineReactive(obj, key, val) {
//创建一个依赖实例,每个属性对象一个依赖// 一 key 一个 depconst dep = new Dep()// 获取 key 的属性描述符,发现它是不可配置对象的话直接 returnconst property = Object.getOwnPropertyDescriptor(obj, key)if (property && property.configurable === false) { return }// 获取 getter 和 setter,并获取 val 值(以及初始化值)const getter = property && property.getconst setter = property && property.setif((!getter || setter) && arguments.length === 2) { val = obj[key] }// 递归处理,保证对象中所有 key 被观察let childOb = observe(val)Object.defineProperty(obj, key, {//属性可枚举enumerable: true,//属性可配置configurable: true,// get 劫持 obj[key] 的 进行依赖收集get: function reactiveGetter() {const value = getter ? getter.call(obj) : valif(Dep.target) {// 依赖收集,将当前依赖(观察者)添加到属性的依赖列表中dep.depend()if(childOb) {// 针对嵌套对象,依赖收集childOb.dep.depend()// 如果属性值是数组 还需要触发数组响应式if(Array.isArray(value)) {dependArray(value)}}}}//返回属性值return value})// set 派发更新 obj[key]set: function reactiveSetter(newVal) {//在这里实现属性的设置,包括触发响应式更新...if(setter) {setter.call(obj, newVal)} else {val = newVal}// 新值设置响应式childOb = observe(val)// 依赖通知更新dep.notify()}
}
这段代码的主要功能是将对象的属性变成响应式的,当属性的值来发生变化时,可以自动通通知相关的视图进行更新。它通过Object.defineProperty来定义属性的get和set方法,以及属性的特性(例如可枚举、可配置等)来实现这一功能。同时它还支持嵌套对象和数组的响应式处理。
性能
体积优化
相比于Vue2,Vue3整体体积变小了,移除了一些不常用的API,任何一个函数,比方说ref、reavived、computed等,仅仅在用到的时候才打包,没用到的模块都去掉,打包整体体积变小,最重要的是Tree shanking
Tree shanking是一种通过清除多余代码方式来优化项目打包体积的技术,专业术语叫Dead code elimination
Tree shaking是基于ES6模板语法(import与exports),主要是借助ES6模块的静态编译思想,在编译时就能确定模块的依赖关系,以及输入和输出的变量
Tree shaking做了两件事:
- 编译阶段利用ES6 Module判断哪些模块已经加载
- 判断那些模块和变量未被使用或者引用,进而删除对应代码
编译优化
diff算法优化
vue3在diff算法中相比vue2增加了静态标记, 其作用是为了会发生变化的地方添加一个flag标记,下次发生变化的时候直接找该地方进行比较,提高性能。
静态提升
Vue3对不参与更新的元素,会做静态提升只会被创建一次,在渲染时直接复用,这样就免去了重复的创建节点,大型应用会受益于这个改动,免去了重复的创建操作,优化了运行时候的内存占用
没有做静态提升之前
export function render(_ctx, _cache, $props, $setup, $data, $options) {return (_openBlock(), _createBlock(_Fragment, null, [_createVNode("span", null, "你好"),_createVNode("div", null, _toDisplayString(_ctx.message), 1 /* TEXT */)], 64 /* STABLE_FRAGMENT */))
}
做了静态提升之后
const _hoisted_1 = /*#__PURE__*/_createVNode("span", null, "你好", -1 /* HOISTED */)export function render(_ctx, _cache, $props, $setup, $data, $options) {return (_openBlock(), _createBlock(_Fragment, null, [_hoisted_1,_createVNode("div", null, _toDisplayString(_ctx.message), 1 /* TEXT */)], 64 /* STABLE_FRAGMENT */))
}// Check the console for the AST
静态内容_hoisted_1被放置在render 函数外,每次渲染的时候只要取 _hoisted_1 即可
同时 _hoisted_1 被打上了 PatchFlag ,静态标记值为 -1 ,特殊标志是负整数表示永远不会用于 Diff
数据劫持(响应式系统)优化
在Vue2 中,数据劫持就是通过Object.defineProperty,这个API有一些缺陷:检测不到对象属性的添加和删除
数组Api方法无法监听到,需要对每个属性进行遍历监听,如果嵌套对象,需要深层监听,造成性能问题
Object.defineProperty(data, 'a',{get(){// track},set(){// trigger}
})
Proxy直接可以劫持整个对象,并返回一个新对象,我们可以只操作新的对象达到响应式目的
function reactive(obj) {if (typeof obj !== 'object' && obj != null) {return obj}// Proxy相当于在对象外层加拦截const observed = new Proxy(obj, {get(target, key, receiver) {const res = Reflect.get(target, key, receiver)console.log(`获取${key}:${res}`)return isObject(res) ? reactive(res) : res}set(target, key, value, receiver) {const res = Reflect.set(target, key, value, receiver)console.log(`设置${key}:${value}`)return res},deleteProperty(target, key) {const res = Reflect.deleteProperty(target, key)console.log(`删除${key}:${res}`)return res}})return observed
}
同时Proxy 并不能监听到内部深层次的对象变化,而 Vue3 的处理方式是在 getter 中去递归响应式,这样的好处是真正访问到的内部对象才会变成响应式,而不是无脑递归
Proxy的作用
在vue中 Proxy主要用于监听对象的变化,以便在对象属性发生变化时,自动更新相关的视图。这是Vue实现响应式数据绑定的核心机制之一
- 实现响应式数据的绑定
vue使Proxy对象来监听数据变化,当数据发生变化时,会自动触发相关视图更新。这使得开发者无需手动去追踪数据变化并更新视图,大大简化了前端开发工作 - 监听数据的读取和写入
Proxy可以拦截对象属性的读取和写入操作。这意味着在读取或写入数据时可以执行自定义的逻辑,比如在写入时进行数据验证 - 递归监听对象嵌套
Vue中的Proxy不仅可以监听对象本身,还可以递归地监听对象内部的所有属性和嵌套对象。这使得整个数据结构都可以实现响应式 - 数组变化的监听
对于数组,Proxy 会拦截数组的变化操作(如 push、pop、splice 等),从而实现数组变化的响应式更新。 - 动态添加属性:
使用 Proxy 可以动态地向对象添加属性,并且这个新属性也会被监听,从而保证了新添加的属性也能实现响应式。 - 防止非预期的属性访问:
通过 Proxy 可以限制对象属性的访问,防止对某些属性的非法访问或修改。 - 监听对象的删除:
Proxy 还可以监听对象属性的删除操作,当属性被删除时,可以执行相应的逻辑。
相关文章:
vue3 和vue2 的比较
文章目录 生命周期多根节点Composition API组合式APIOptions API与composition API对比优化逻辑组织优化逻辑复用 异步组件(Suspense)Suspense组件 响应式原理性能体积优化编译优化diff算法优化静态提升数据劫持(响应式系统)优化 生命周期 vue3在组合AP…...
算法通过村第八关-树(深度优先)黄金笔记|寻找祖先
文章目录 前言最近公共祖先问题总结 前言 提示:生活就是一场有很多规则,却没有裁判的比赛。 --约瑟夫布罗茨基《悲伤与理智》 最近公共祖先问题 参考题目地址:236. 二叉树的最近公共祖先 - 力扣(LeetCode) 如果将搜索…...
postgresql|数据库|数据库测试工具pgbench之使用
前言: 数据库是项目中的重要组件,也是一个基础的重要组件,其地位说是第一我想应该是没有什么太多问题的。 那么,数据库的设计这些方面是不用多说的,关键的第一步,主要是涉及数据库的部署方式,…...
代码随想录Day51 | 309.最佳买卖股票时机含冷冻期
309. 买卖股票的最佳时机含冷冻期 class Solution { public:int maxProfit(vector<int>& prices) {int n prices.size();if (n 0) return 0;vector<vector<int>> dp(n, vector<int>(4, 0));dp[0][0] - prices[0]; // 持股票for (int i 1; i &l…...
libopenssl 实现私钥加密公钥解密
在需要验证可信来源时,需要用到签名验签。因此,需要使用私钥加密,公钥解密,取得被加密的信息。这就会使用到私钥加密,公钥解密的场景了。 参考: https://github.com/openssl/openssl/issues/20493 https:/…...
代码随想录 Day - 51|#309 最佳买卖股票时机含冷冻期|#714 买卖股票的最佳时机含手续费
清单 ● 309.最佳买卖股票时机含冷冻期 ● 714.买卖股票的最佳时机含手续费 LeetCode #309 最佳买卖股票时机含冷冻期 1. 题目 给定一个整数数组,其中第 i 个元素代表了第 i 天的股票价格 。 设计一个算法计算出最大利润。在满足以下约束条件下,你可…...
.net 使用IL生成代理类实现AOP对比Java Spring Boot的AOP
首先,我们需要定义一个接口,代表我们要代理的目标对象的功能: // 日志记录器接口 public interface ILogger {/// <summary>/// 记录日志/// </summary>/// <param name"message">日志消息</param>void L…...
美容店预约小程序搭建流程
随着科技的不断发展,小程序已经成为了人们生活中不可或缺的一部分。对于美容店来说,搭建一个预约小程序不仅可以提高工作效率,还可以增加客户数量、提高服务质量。那么,如何搭建一个美容店预约小程序呢?本文将为你详细…...
ppt 作图 如何生成eps格式
需求 ppt中画的图,按照eps格式导出。 环境 软件: ppt, Gsview(用来将ps格式转成eps), Adobe 操作系统: win11 思路 直接在ppt里选择adobe打印机,将图片以文件形式打印到ps格式的文件中,再由gsview转化成eps。 建议在本身就…...
渗透测试中的前端调试(上)
一、前言 前端调试是安全测试的重要组成部分。它能够帮助我们掌握网页的运行原理,包括js脚本的逻辑、加解密的方法、网络请求的参数等。利用这些信息,我们就可以更准确地发现网站的漏洞,制定出有效的攻击策略。前端知识对于安全来说ÿ…...
跨境电商引流之Reddit营销,入门保姆级攻略
在当今竞争激烈的在线市场中,企业不断寻求新的方法来加强其数字营销工作。Reddit 是最受欢迎的社交媒体平台之一,为企业提供了巨大的潜力,可以通过引人入胜且相关的内容来接触目标受众。然而,将 Reddit 用于营销目的需要仔细考虑某…...
Linux下虚拟网卡的基本命令
文章目录 创建虚拟网卡查看虚拟网卡删除虚拟网卡 创建虚拟网卡 # 创建tap模式的虚拟网卡tap0 sudo ip tuntap add mode tap tap0 # 开启网卡 sudo ip link set tap0 up # 设置网卡的ip地址和子网掩码 sudo ip addr add 192.168.1.1/24 dev tap0查看虚拟网卡 # 查看虚拟网卡ta…...
conan入门(二十七):因profile [env]字段废弃导致的boost/1.81.0 在aarch64-linux-gnu下交叉编译失败
今天在尝试用conan 1.60.0使用aarch64-linux-gnu编译器交叉编译boost/1.81.0时报错了: conan install boost/1.81.0 -pr:h aarch64-linux-gnu.jinja -pr:b default --build boost输出如下: Configuration (profile_host): [settings] archarmv8 arch_b…...
BFS专题7 多终点迷宫问题
题目: 样例: 输入 3 3 0 0 0 1 0 0 0 1 0 输出 0 1 2 -1 2 3 -1 -1 4 思路: 单纯的 BFS 迷宫问题,只是标记一下每个点的 step,注意初始化答案数组都为 -1. 代码详解如下: #include <iostream> #…...
ES6中对象新增了哪些扩展?
一、属性的简写 当对象字面量的属性名与变量名相同时,可以省略属性名,直接使用变量名作为属性名。 const x 10; const y 20;// ES6之前 const obj1 { x: x, y: y };// ES6属性简写 const obj2 { x, y };注意:简写的对象方法不能用作构造…...
蓝桥杯每日一题2023.9.22
4960. 子串简写 - AcWing题库 题目描述 题目分析 原本为纯暴力但是发现会超时,可以加入前缀和,从前往后先记录一下每个位置c1出现的次数 再从前往后扫一遍,如果遇到c2就将答案加上此位置前的所有c1的个数(直接加上此位置的前缀…...
vscode左键无法跳转到定义的文件
之前用vscode的时候,明明是可以ctrl键鼠标左键跳转到定义文件的,突然之间就不行了,鼠标移到引入上根本都没有下划线,无法跳转 解决方法: 项目的根目录新建 jsconfig.json 文件,代码如下 {"compiler…...
c、c++排序的相关知识(归并排序、计数排序、稳定性等)
排序,是对给定的一组数,按照某种逻辑关系,进行位置上的移动。由于排序至少需要将所有数过一遍(正常情况下,非特殊数组),因此排序的时间复杂度一定不能小于O(N)。 归并排…...
oracle定时任务的使用
常见错误: PLS-00225: subprogram or cursor xxx reference is out of scope # job名字太长PLS-00201: identifier COUNT_JOB.SUBMIT must be declared # DBMS_JOB.SUBMIT是固定写法创建存储过程 -- 建表 CREATE TABLE TEST_A(TEST_ADD_DATA DATE); -- 存储过程 C…...
VSCode 配置 Lua 开发环境(清晰明了)
概述 由于 AutoJS 学得已经差不多了,基本都会了,现在开始向其他游戏脚本框架进发, Lua 语言很强大,就不多说, 按键精灵、触动精灵等等都是用该语言编程脚本的,由于按键精灵、触动精灵 和 AutoJS 类似,不是…...
JS合并2个远程pdf
要在HTML和JavaScript中读取远程PDF文件的矢量数据并合并两个PDF文件,您可以使用pdf-lib和Axios库。以下是使用pdf-lib和Axios在HTML和JavaScript中读取和合并远程PDF文件的步骤: 1. 引入 首先,确保您在HTML文件中引入了pdf-lib和Axios库。…...
TikTok的伦理挑战:虚拟世界与现实世界的交汇
在数字时代,社交媒体平台已经不再只是一个信息传播的工具,它已经深刻地改变了我们的社交行为、价值观和伦理观。 而在这一领域的佼佼者之一,TikTok,正面临着伦理挑战,这是虚拟世界与现实世界交汇的产物。 本文将深入…...
C# 获取磁盘空间大小的方法
方法一:利用System.IO.DriveInfo.GetDrives方法来获取 /// 获取指定驱动器的空间总大小(单位为B)////// 只需输入代表驱动器的字母即可 (大写)///public static long GetHardDiskSpace(string str_HardDiskName){long totalSize new long();…...
JVM机制理解与调优方案
作者:逍遥Sean 简介:一个主修Java的Web网站\游戏服务器后端开发者 主页:https://blog.csdn.net/Ureliable 觉得博主文章不错的话,可以三连支持一下~ 如有需要我的支持,请私信或评论留言! 前言 很多Java开发…...
Django的设计模式及模板层
Django的设计模式及模板层 设计模式MVC和MVT MVC 代表 Model-View-Controller(模型-视图-控制器)模式。 M 模型层(Model),主要用于对数据库层的封装 V 视图层(View),用于向用户展示结果 (WHAT HOW) C 控制(Controller,用于处理请求、获取数据、返回结果(重要) 作…...
写代码生成流程图
我们在写文档,博客的时候,一般都会使用markdown语法,最常见的就是一些github开源项目的README。有时候会去画一些流程图,例如使用process.on或者xmind等第三方网站,然后截图插入到文档中。 今天我们介绍一种使用代码直…...
python reportlab生成pdf
这里自定义了pagetemplate,使用BaseDocTemplate,但我感觉一般使用SimpleDocTemplate就可以。 from reportlab.platypus import Frame from reportlab.lib.pagesizes import A4, landscapepadding dict(leftPadding72,rightPadding72,topPadding72,bott…...
第一次作业题解
第一次作业题解 P5717 【深基3.习8】三角形分类 思路 考的是if()的使用,还要给三条边判断大小 判断优先级: 三角形?直角、钝角、锐角等腰等边 判断按题给顺序来 代码 #include <stdio.h> int main() {int a 0, b 0, c 0, x 0, y 0, z 0…...
美篇作文网教学资源源码-自带作文数据
非常漂亮的UI设计和页面排版! 自适应手机pc端 页面内容均支持自定义 可以用来做网站矩阵,或者增强你其他网站板块,或者单独运营都可以。 可以通过广告方式变现,或者引流等等 友好的seo,更容易被浏览器收录 关注青狐…...
电脑软件:Duplicate Cleaner Pro 5.16 重复文件清理软件(附下载)
大家平时在使用电脑的时候,会经常从网上下载文件或者从其他电脑拷贝文件到自己的电脑上。久而久之就会在电脑中存放很多相同的文件,并且会越积越多,不仅占用很多磁盘空间,在文件管理上也非常混乱不方便。如何解决呢? …...
采集电影做的网站/新闻联播今日新闻
点击右上方红色按钮关注“web秀”,让你真正秀起来前言vue组件非常常见的有父子组件通信,兄弟组件通信。而父子组件通信就很简单,父组件会通过 props 向下传数据给子组件,当子组件有事情要告诉父组件时会通过 $emit 事件告诉父组件…...
怎么做自己的个人网站/从哪里找网络推广公司
以下内容全部来自 Transforms Ⅰ. Transforms 简而言之,就是训练的数据有时候并不是机器学习训练的数据格式,这个时候就需要 Transforms 对数据进行一些操作(转换),使其适合做神经网络的输入。比如对于图像数据&…...
用ps可以做网站吗/游戏推广员如何推广引流
1.联合结果集 (1) 简单的结果集联合 select FNumber,FName,Fage from T_Employee\ union select FidCardNumber,FName,Fage from T_Employee (2) 查询的基本原则是:每个结果集必须有相同的列数,没个结果集的列必须类型相同。 select FNumber,FName,Fage,…...
关于政府补贴企业做网站的事/软文营销常用的方式
大三上:数据库系统概论所有实验报告和课后作业 文章目录一、实验目的及要求二、实验内容(或实验原理、实验拓扑)三、实验设备与环境四、实验设计方案(包括实验步骤、设计思想、算法描述或开发流程等)五、实验结果&…...
西安网站托管排名/aso具体优化
一、准备: 1.1、GOPATH目录下的bin文件夹添加系统path变量中。 添加后可直接在任意位置控制台中直接调用bin目录下的可执行程序。 1.2、准备好自己的程序ico图标文件,放在main.go同级目录。 下文中提到的:控制台运行命令,都是在…...
石家庄商城网站制作/seo自学教程推荐
本问题已经有最佳答案,请猛点这里访问。我正在尝试加载正在使用的应用程序的条款和条件。 客户端向我提供了条款和条件的html文件,我没有任何类型的服务器访问权限。 因此从技术上讲,该应用需要随身携带该文件。 我已经完成了Web视图…...