jQuery UI widget源码解析

这篇具有很好参考价值的文章主要介绍了jQuery UI widget源码解析。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

  1. //实例化父类 获取父类的  prototype

  2. basePrototype = new base();

  3. // we need to make the options hash a property directly on the new instance

  4. // otherwise we’ll modify the options hash on the prototype that we’re

  5. // inheriting from

  6. //这里深复制一份options

  7. basePrototype.options = $.widget.extend({}, basePrototype.options);

  8. //在传入的ui原型中有方法调用this._super 和this.__superApply会调用到base上(最基类上)的方法

  9. $.each(prototype, function(prop, value) {

  10. //如果val不是function 则直接给对象赋值字符串

  11. if (!$.isFunction(value)) {

  12. proxiedPrototype[prop] = value;

  13. return;

  14. }

  15. //如果val是function

  16. proxiedPrototype[prop] = (function() {

  17. //两种调用父类函数的方法

  18. var _super = function() {

  19. //将当期实例调用父类的方法

  20. return base.prototype[prop].apply(this, arguments);

  21. },

  22. _superApply = function(args) {

  23. return base.prototype[prop].apply(this, args);

  24. };

  25. return function() {

  26. var __super = this._super,

  27. __superApply = this._superApply,

  28. returnValue;

  29. //                console.log(prop, value,this,this._super,‘===’)

  30. //                debugger;

  31. //在这里调用父类的函数

  32. this._super = _super;

  33. this._superApply = _superApply;

  34. returnValue = value.apply(this, arguments);

  35. this._super = __super;

  36. this._superApply = __superApply;

  37. //                console.log(this,value,returnValue,prop,‘===’)

  38. return returnValue;

  39. };

  40. })();

  41. });

  42. //    console.info(proxiedPrototype)

  43. //    debugger;

  44. //这里是实例化获取的内容

  45. constructor.prototype = $.widget.extend(basePrototype, {

  46. // TODO: remove support for widgetEventPrefix

  47. // always use the name + a colon as the prefix, e.g., draggable:start

  48. // don’t prefix for widgets that aren’t DOM-based

  49. widgetEventPrefix: existingConstructor ? (basePrototype.widgetEventPrefix || name) : name

  50. }, proxiedPrototype, {

  51. //重新把constructor指向 constructor 变量

  52. constructor: constructor,

  53. namespace: namespace,

  54. widgetName: name,

  55. widgetFullName: fullName

  56. });

  57. // If this widget is being redefined then we need to find all widgets that

  58. // are inheriting from it and redefine all of them so that they inherit from

  59. // the new version of this widget. We’re essentially trying to replace one

  60. // level in the prototype chain.

  61. //这里判定插件是否被使用了。一般来说,都不会被使用的。

  62. //因为插件的开发者都是我们自己,呵呵

  63. if (existingConstructor) {

  64. $.each(existingConstructor._childConstructors, function(i, child) {

  65. var childPrototype = child.prototype;

  66. // redefine the child widget using the same prototype that was

  67. // originally used, but inherit from the new version of the base

  68. $.widget(childPrototype.namespace + “.” + childPrototype.widgetName, constructor, child._proto);

  69. });

  70. // remove the list of existing child constructors from the old constructor

  71. // so the old child constructors can be garbage collected

  72. delete existingConstructor._childConstructors;

  73. } else {

  74. //父类添加当前插件的实例 主要用于作用域链查找 不至于断层

  75. base._childConstructors.push(constructor);

  76. }

  77. //将此方法挂在jQuery对象上

  78. $.widget.bridge(name, constructor);

  79. return constructor;

  80. };

  81. //扩展jq的extend方法,实际上类似$.extend(true,…) 深复制

  82. $.widget.extend = function(target) {

  83. var input = widget_slice.call(arguments, 1),

  84. inputIndex = 0,

  85. inputLength = input.length,

  86. key, value;

  87. for (; inputIndex < inputLength; inputIndex++) {

  88. for (key in input[inputIndex]) {

  89. value = input[inputIndex][key];

  90. if (input[inputIndex].hasOwnProperty(key) && value !== undefined) {

  91. // Clone objects

  92. if ($.isPlainObject(value)) {

  93. target[key] = KaTeX parse error: Undefined control sequence: \[ at position 22: …inObject(target\̲[̲key\]) ? .widget.extend({}, target[key], value) :

  94. // Don’t extend strings, arrays, etc. with objects

  95. $.widget.extend({}, value);

  96. // Copy everything else by reference

  97. } else {

  98. target[key] = value;

  99. }

  100. }

  101. }

  102. }

  103. return target;

  104. };

  105. //bridge 是设计模式的一种,这里将对象转为插件调用

  106. $.widget.bridge = function(name, object) {

  107. var fullName = object.prototype.widgetFullName || name;

  108. //这里就是插件了

  109. //这部分的实现主要做了几个工作,也是制作一个优雅的插件的主要代码

  110. //1、初次实例化时将插件对象缓存在dom上,后续则可直接调用,避免在相同元素下widget的多实例化。简单的说,就是一个单例方法。

  111. //2、合并用户提供的默认设置选项options

  112. //3、可以通过调用插件时传递字符串来调用插件内的方法。如:$(‘#id’).menu(‘hide’) 实际就是实例插件并调用hide()方法。

  113. //4、同时限制外部调用“_”下划线的私有方法

  114. $.fn[name] = function(options) {

  115. var isMethodCall = typeof options === “string”,

  116. args = widget_slice.call(arguments, 1),

  117. returnValue = this;

  118. // allow multiple hashes to be passed on init.

  119. //可以简单认为是$.extend(true,options,args[0],…),args可以是一个参数或是数组

  120. options = !isMethodCall && args.length ? $.widget.extend.apply(null, [options].concat(args)) : options;

  121. //这里对字符串和对象分别作处理

  122. if (isMethodCall) {

  123. this.each(function() {

  124. var methodValue, instance = $.data(this, fullName);

  125. //如果传递的是instance则将this返回。

  126. if (options === “instance”) {

  127. returnValue = instance;

  128. return false;

  129. }

  130. if (!instance) {

  131. return $.error("cannot call methods on " + name + " prior to initialization; " + “attempted to call method '” + options + “'”);

  132. }

  133. //这里对私有方法的调用做了限制,直接调用会抛出异常事件

  134. if (!$.isFunction(instance[options]) || options.charAt(0) === “_”) {

  135. return $.error(“no such method '” + options + “’ for " + name + " widget instance”);

  136. }

  137. //这里是如果传递的是字符串,则调用字符串方法,并传递对应的参数.

  138. //比如插件有个方法hide(a,b); 有2个参数:a,b

  139. //则调用时$(‘#id’).menu(‘hide’,1,2);//1和2 分别就是参数a和b了。

  140. methodValue = instance[options].apply(instance, args);

  141. if (methodValue !== instance && methodValue !== undefined) {

  142. returnValue = methodValue && methodValue.jquery ? returnValue.pushStack(methodValue.get()) : methodValue;

  143. return false;

  144. }

  145. });

  146. } else {

  147. this.each(function() {

  148. var instance = $.data(this, fullName);

  149. if (instance) {

  150. instance.option(options || {});

  151. //这里每次都调用init方法

  152. if (instance._init) {

  153. instance._init();

  154. }

  155. } else {

  156. //缓存插件实例

  157. $.data(this, fullName, new object(options, this));

  158. }

  159. });

  160. }

  161. return returnValue;

  162. };

  163. };

  164. //这里是真正的widget基类

  165. $.Widget = function( /* options, element */ ) {};

  166. $.Widget._childConstructors = [];

  167. $.Widget.prototype = {

  168. widgetName: “widget”,

  169. //用来决定事件的名称和插件提供的callbacks的关联。

  170. // 比如dialog有一个close的callback,当close的callback被执行的时候,一个dialogclose的事件被触发。

  171. // 事件的名称和事件的prefix+callback的名称。widgetEventPrefix 默认就是控件的名称,但是如果事件需要不同的名称也可以被重写。

  172. // 比如一个用户开始拖拽一个元素,我们不想使用draggablestart作为事件的名称,我们想使用dragstart,所以我们可以重写事件的prefix。

  173. // 如果callback的名称和事件的prefix相同,事件的名称将不会是prefix。

  174. // 它阻止像dragdrag一样的事件名称。

  175. widgetEventPrefix: “”,

  176. defaultElement: “

    ”,
  177. //属性会在创建模块时被覆盖

  178. options: {

  179. disabled: false,

  180. // callbacks

  181. create: null

  182. },

  183. _createWidget: function(options, element) {

  184. element = $(element || this.defaultElement || this)[0];

  185. this.element = $(element);

  186. this.uuid = widget_uuid++;

  187. this.eventNamespace = “.” + this.widgetName + this.uuid;

  188. this.options = $.widget.extend({}, this.options, this._getCreateOptions(), options);

  189. this.bindings = $();

  190. this.hoverable = $();

  191. this.focusable = $();

  192. if (element !== this) {

  193. //            debugger

  194. $.data(element, this.widgetFullName, this);

  195. this._on(true, this.element, {

  196. remove: function(event) {

  197. if (event.target === element) {

  198. this.destroy();

  199. }

  200. }

  201. });

  202. this.document = $(element.style ?

  203. // element within the document

  204. element.ownerDocument :

  205. // element is window or document

  206. element.document || element);

  207. this.window = $(this.document[0].defaultView || this.document[0].parentWindow);

  208. }

  209. this._create();

  210. //创建插件时,有个create的回调

  211. this._trigger(“create”, null, this._getCreateEventData());

  212. this._init();

  213. },

  214. _getCreateOptions: $.noop,

  215. _getCreateEventData: $.noop,

  216. _create: $.noop,

  217. _init: $.noop,

  218. //销毁模块:去除绑定事件、去除数据、去除样式、属性

  219. destroy: function() {

  220. this._destroy();

  221. // we can probably remove the unbind calls in 2.0

  222. // all event bindings should go through this._on()

  223. this.element.unbind(this.eventNamespace).removeData(this.widgetFullName)

  224. // support: jquery <1.6.3

  225. // http://bugs.jquery.com/ticket/9413

  226. .removeData($.camelCase(this.widgetFullName));

  227. this.widget().unbind(this.eventNamespace).removeAttr(“aria-disabled”).removeClass(

  228. this.widgetFullName + "-disabled " + “ui-state-disabled”);

  229. // clean up events and states

  230. this.bindings.unbind(this.eventNamespace);

  231. this.hoverable.removeClass(“ui-state-hover”);

  232. this.focusable.removeClass(“ui-state-focus”);

  233. },

  234. _destroy: $.noop,

  235. widget: function() {

  236. return this.element;

  237. },

  238. //设置选项函数

  239. option: function(key, value) {

  240. var options = key,

  241. parts, curOption, i;

  242. if (arguments.length === 0) {

  243. // don’t return a reference to the internal hash

  244. //返回一个新的对象,不是内部数据的引用

  245. return $.widget.extend({}, this.options);

  246. }

  247. if (typeof key === “string”) {

  248. // handle nested keys, e.g., “foo.bar” => { foo: { bar: ___ } }

  249. options = {};

  250. parts = key.split(“.”);

  251. key = parts.shift();

  252. if (parts.length) {

  253. curOption = options[key] = $.widget.extend({}, this.options[key]);

  254. for (i = 0; i < parts.length - 1; i++) {

  255. curOption[parts[i]] = curOption[parts[i]] || {};

  256. curOption = curOption[parts[i]];

  257. }

  258. key = parts.pop();

  259. if (arguments.length === 1) {

  260. return curOption[key] === undefined ? null : curOption[key];

  261. }

  262. curOption[key] = value;

  263. } else {

  264. if (arguments.length === 1) {

  265. return this.options[key] === undefined ? null : this.options[key];

  266. }

  267. options[key] = value;

  268. }

  269. }

  270. this._setOptions(options);

  271. return this;

  272. },

  273. _setOptions: function(options) {

  274. var key;

  275. for (key in options) {

  276. this._setOption(key, options[key]);

  277. }

  278. return this;

  279. },

  280. _setOption: function(key, value) {

  281. this.options[key] = value;

  282. if (key === “disabled”) {

  283. this.widget().toggleClass(this.widgetFullName + “-disabled”, !! value);

  284. // If the widget is becoming disabled, then nothing is interactive

  285. if (value) {

  286. this.hoverable.removeClass(“ui-state-hover”);

  287. this.focusable.removeClass(“ui-state-focus”);

  288. }

  289. }

  290. return this;

  291. },

  292. enable: function() {

  293. return this._setOptions({

  294. disabled: false

  295. });

  296. },

  297. disable: function() {

  298. return this._setOptions({

  299. disabled: true

  300. });

  301. },

  302. _on: function(suppressDisabledCheck, element, handlers) {

  303. var delegateElement, instance = this;

  304. // no suppressDisabledCheck flag, shuffle arguments

  305. if (typeof suppressDisabledCheck !== “boolean”) {

  306. handlers = element;

  307. element = suppressDisabledCheck;

  308. suppressDisabledCheck = false;

  309. }

  310. // no element argument, shuffle and use this.element

  311. if (!handlers) {

  312. handlers = element;

  313. element = this.element;

  314. delegateElement = this.widget();

  315. } else {

  316. // accept selectors, DOM elements

  317. element = delegateElement = $(element);

  318. this.bindings = this.bindings.add(element);

  319. }

  320. $.each(handlers, function(event, handler) {

  321. function handlerProxy() {

  322. // allow widgets to customize the disabled handling

  323. // - disabled as an array instead of boolean

  324. // - disabled class as method for disabling individual parts

  325. if (!suppressDisabledCheck && (instance.options.disabled === true || $(this).hasClass(“ui-state-disabled”))) {

  326. return;

  327. }

  328. return (typeof handler === “string” ? instance[handler] : handler).apply(instance, arguments);

  329. }

  330. // copy the guid so direct unbinding works

  331. if (typeof handler !== “string”) {

  332. handlerProxy.guid = handler.guid = handler.guid || handlerProxy.guid || $.guid++;

  333. }

  334. var match = event.match(/^([\w:-]*)\s*(.*)$/),

  335. eventName = match[1] + instance.eventNamespace,

  336. selector = match[2];

  337. if (selector) {

  338. delegateElement.delegate(selector, eventName, handlerProxy);

  339. } else {

  340. element.bind(eventName, handlerProxy);

  341. }

  342. });

  343. },

  344. _off: function(element, eventName) {

  345. eventName = (eventName || “”).split(" ").join(this.eventNamespace + " ") + this.eventNamespace;

  346. element.unbind(eventName).undelegate(eventName);

  347. },

  348. _delay: function(handler, delay) {

  349. function handlerProxy() {

  350. return (typeof handler === “string” ? instance[handler] : handler).apply(instance, arguments);

  351. }

  352. var instance = this;

  353. return setTimeout(handlerProxy, delay || 0);

  354. },

  355. _hoverable: function(element) {

  356. this.hoverable = this.hoverable.add(element);

  357. this._on(element, {

  358. mouseenter: function(event) {

  359. $(event.currentTarget).addClass(“ui-state-hover”);

  360. },

  361. mouseleave: function(event) {

  362. $(event.currentTarget).removeClass(“ui-state-hover”);

  363. }

  364. });

  365. },

  366. _focusable: function(element) {

  367. this.focusable = this.focusable.add(element);

  368. this._on(element, {

  369. focusin: function(event) {

  370. $(event.currentTarget).addClass(“ui-state-focus”);

  371. },

  372. focusout: function(event) {

  373. $(event.currentTarget).removeClass(“ui-state-focus”);

  374. }

  375. });

  376. },

  377. _trigger: function(type, event, data) {

  378. var prop, orig, callback = this.options[type];

  379. data = data || {};

  380. event = $.Event(event);

  381. event.type = (type === this.widgetEventPrefix ? type : this.widgetEventPrefix + type).toLowerCase();

  382. // the original event may come from any element

  383. // so we need to reset the target on the new event

  384. event.target = this.element[0];

  385. // copy original event properties over to the new event

  386. orig = event.originalEvent;

  387. if (orig) {

  388. for (prop in orig) {

  389. if (!(prop in event)) {

  390. event[prop] = orig[prop];

  391. }

  392. }

  393. }

  394. this.element.trigger(event, data);

  395. return !($.isFunction(callback) && callback.apply(this.element[0], [event].concat(data)) === false || event.isDefaultPrevented());

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。





既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip1024c (备注前端)

TCP协议

  • TCP 和 UDP 的区别?
  • TCP 三次握手的过程?
  • 为什么是三次而不是两次、四次?
  • 三次握手过程中可以携带数据么?
  • 说说 TCP 四次挥手的过程
  • 为什么是四次挥手而不是三次?
  • 半连接队列和 SYN Flood 攻击的关系
  • 如何应对 SYN Flood 攻击?
  • 介绍一下 TCP 报文头部的字段
  • TCP 快速打开的原理(TFO)
  • 说说TCP报文中时间戳的作用?
  • TCP 的超时重传时间是如何计算的?
  • TCP 的流量控制
  • TCP 的拥塞控制
  • 说说 Nagle 算法和延迟确认?
  • 如何理解 TCP 的 keep-alive?
浏览器篇
  • 浏览器缓存?
  • 说一说浏览器的本地存储?各自优劣如何?
  • 说一说从输入URL到页面呈现发生了什么?
  • 谈谈你对重绘和回流的理解
  • XSS攻击
  • CSRF攻击
  • HTTPS为什么让数据传输更安全?
  • 实现事件的防抖和节流?
  • 实现图片懒加载?

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!**

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip1024c (备注前端)
[外链图片转存中…(img-xRYLHS2m-1712835639108)]

TCP协议

  • TCP 和 UDP 的区别?
  • TCP 三次握手的过程?
  • 为什么是三次而不是两次、四次?
  • 三次握手过程中可以携带数据么?
  • 说说 TCP 四次挥手的过程
  • 为什么是四次挥手而不是三次?
  • 半连接队列和 SYN Flood 攻击的关系
  • 如何应对 SYN Flood 攻击?
  • 介绍一下 TCP 报文头部的字段
  • TCP 快速打开的原理(TFO)
  • 说说TCP报文中时间戳的作用?
  • TCP 的超时重传时间是如何计算的?
  • TCP 的流量控制
  • TCP 的拥塞控制
  • 说说 Nagle 算法和延迟确认?
  • 如何理解 TCP 的 keep-alive?

[外链图片转存中…(img-s0o4vBxU-1712835639108)]

浏览器篇
  • 浏览器缓存?
  • 说一说浏览器的本地存储?各自优劣如何?
  • 说一说从输入URL到页面呈现发生了什么?
  • 谈谈你对重绘和回流的理解
  • XSS攻击
  • CSRF攻击
  • HTTPS为什么让数据传输更安全?
  • 实现事件的防抖和节流?
  • 实现图片懒加载?

[外链图片转存中…(img-mqGlnSQI-1712835639108)]

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
[外链图片转存中…(img-L0l6uqvo-1712835639109)]文章来源地址https://www.toymoban.com/news/detail-850999.html

到了这里,关于jQuery UI widget源码解析的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 面试流程解析:从初面到终面,程序员需要注意什么

    🌷🍁 博主猫头虎 带您 Go to New World.✨🍁 🦄 博客首页——猫头虎的博客🎐 🐳《面试题大全专栏》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~🌺 🌊 《IDEA开发秘籍专栏》学会IDEA常用操作,工作效率翻倍~💐 🌊 《100天精通Golang(基础入门篇)》学会Golang语言

    2024年02月10日
    浏览(19)
  • 黑马程序员-职工管理系统实战-附加源码Git

    职工管理系统可以用来管理公司内所有员工的信息 本教程主要利用C++来实现一个基于多态的职工管理系统 公司中职工分为三类:普通员工、经理、老板,显示信息时,需要显示职工编号、职工姓名、职工岗位、以及职责 普通员工职责:完成经理交给的任务 经理职责:完成老

    2024年02月03日
    浏览(31)
  • 身为一个后端程序员如何快速制作后端管理系统的UI

    我的专业领域在后端开发上,前端我仅仅是熟悉,但是要从头开发一个前端UI界面有点难为人了。那么身为一个后端程序员我们怎么来开发后端管理系统UI界面呢? 市面上有很多后端管理系统的UI模版,但我推荐的layui + lauyimini,虽然技术偏老,也没咋维护了,但是上手简单呀

    2024年02月11日
    浏览(19)
  • mint-ui使用,面试一路绿灯Offer拿到手软,最新大厂程序员进阶宝典

    mint-ui 的使用 mint-ui官网 安装 npm install mint-ui -S 引入项目 全局引入(简单粗暴,一次引入所有组件) main.js // 引入全部组件 import Vue from ‘vue’; import Mint from ‘mint-ui’; import ‘mint-ui/lib/style.css’; // 有可能会报错, 找node_modules --》 mint-ui ?css Vue.use(Mint); 弹框 Toast组件 import {

    2024年04月08日
    浏览(23)
  • 【正在更新】【最新!黑马程序员Python自学课程笔记】课上笔记+案例源码+作业源码

    1.1字面量 1.2注释 1.3变量 debug工具的使用 1.对着某行代码 打断点 2.下方一步步 步进 1.4数据类型 1.5数据类型转换 错误示例 1.6标识符 变量的命名规范: 1.见名知意,简洁; 2.(多个单词)用下划线命名法 3.英文字母全小写 1.7运算符 1.8字符串的三种定义方式 1.9字符串的拼接

    2024年01月21日
    浏览(21)
  • Python 程序员过中秋Python+pygame 制作拼图小游戏(附源码:5源码)

    Python 程序员过中秋Python+pygame 制作拼图小游戏(附源码:5源码) 又是一年中秋至一花好月 圆夜,佳文当共鉴。Python+ pygame制作拼图小游戏; 制作一个自己的拼图小游戏,看看几步可以观赏到月亮。 官方活动入口 ​ 本文档是对Python语言制作拼图小游戏界面功能需求进行分析归

    2023年04月09日
    浏览(19)
  • 【程序员必备】UE4 C++ 虚幻引擎:详解JSON文件读、写、解析,打造高效开发!

    🙋‍♂️ 作者:海码007 📜 专栏:UE虚幻引擎专栏 💥 标题:【程序员必备】UE4 C++ 虚幻引擎:详解JSON文件读、写、解析,打造高效开发! ❣️ 寄语:人生的意义或许可以发挥自己全部的潜力,所以加油吧! 🎈 最后: 文章作者技术和水平有限,如果文中出现错误,希望大

    2024年02月03日
    浏览(19)
  • 黑马程序员课程Vue实战项目_Element-ui——电商后台管理系统-商品管理(商品列表)

    目录 商品列表 一.创建一个子分支 二.创建组件 三.绘制商品列表的页面基本结构 1.面包屑导航  2.卡片视图区域 四.功能 1.搜索  2.删除  3.添加 五.提交代码 git branch——查看当前所在分支 git checkout -b goods_list——创建新的子分支goods_list git branch——查看当前所在分支 git pus

    2024年02月08日
    浏览(22)
  • 【Python】中秋节快到了,这才是程序员该赏的“月亮”(3D+音频+源码)

    目录 导语​ 一、做月饼 二、赏“月” 1. 引言 2. 下载ursina库 3.实现思路 4.资源的获取 总结 送一个圆圆的饼,寄一个圆圆的请,献一颗圆圆的心,圆一个圆圆的梦,中秋节快乐!转眼之间,农历八月十五中秋节即将到来,又是一年中秋,作为一位Python爱好者,怎么能置之不理

    2024年02月08日
    浏览(12)
  • Android SystemUI源码分析与修改,作为Android程序员应该怎样去规划自己的学习路线

    systemui:keyCode=“4” android:layout_weight=“0” systemui:glowBackground=“@drawable/ic_sysbar_highlight” android:contentDescription=“@string/accessibility_back” / 音量减的布局如下,这里先把Visibility定义为Gone,然后在代码中控制是否显示: com.android.systemui.statusbar.policy.KeyButtonView android:id=“@+id/sub”

    2024年04月15日
    浏览(25)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包