摘要:而且上一篇文章中,也已經(jīng)實(shí)現(xiàn)了一個(gè)基本的用戶(hù)管理列表頁(yè)面。接著上一篇,完善用戶(hù)管理,實(shí)現(xiàn)增刪改。為了用戶(hù)體驗(yàn),增加和修改用戶(hù)信息的表單,都放在彈窗中進(jìn)行。
經(jīng)過(guò)前面幾篇文章的介紹,一個(gè)基本的MVC結(jié)構(gòu)應(yīng)該是具備了。而且上一篇文章中,也已經(jīng)實(shí)現(xiàn)了一個(gè)基本的用戶(hù)管理列表頁(yè)面。接著上一篇,完善用戶(hù)管理,實(shí)現(xiàn)增刪改。為了用戶(hù)體驗(yàn),增加和修改用戶(hù)信息的表單,都放在彈窗中進(jìn)行。避免跳轉(zhuǎn)頁(yè)面。定義用戶(hù)增加窗口:app/luter/view/sys/user/UserAdd.js
Ext.define("luter.view.sys.user.UserAdd", { extend: "Ext.window.Window",//擴(kuò)展window組件 alias: "widget.useraddview", requires: [], constrain: true,//約束窗體彈出,別出瀏覽器可視范圍 modal: true,//模態(tài) maximizable: true,//可以最大化 iconCls: baseConfig.appicon.add,//圖標(biāo) layout: "fit",//自適應(yīng)布局 width: 700, autoHeight: true,//自適應(yīng)高度 viewModel: { data: { title: "" } }, bind: { title: "新增用戶(hù): " + "{title}"http://綁定這個(gè)空間的title屬性上 }, initComponent: function () { var me = this; //加入一個(gè)表單,表單內(nèi)元素通過(guò)loadView方法添加 me.items = [{ xtype: "form", width: 700, autoHeight: true, fieldDefaults: { labelAlign: "right", labelStyle: "font-weight:bold;" }, border: false }] //操作按鈕直接加載window上 me.buttons = ["->", { text: "新增", cls: "green-btn", iconCls: baseConfig.appicon.add, handler: function () { var form = this.down("form"); if (form.isValid()) { form.submit({ url: "sys/user/add", method: "POST", waitTitle: "提示", waitMsg: "正在提交數(shù)據(jù),請(qǐng)稍后 ……", success: function (form, action) {//添加成功后提示消息,并且刷新用戶(hù)列表數(shù)據(jù) me.close(); DealAjaxResponse(action.response); Ext.data.StoreManager.lookup("UserStore").load(); }, failure: function (form, action) { DealAjaxResponse(action.response); } }); } else { toast({ msg: "表單填寫(xiě)錯(cuò)誤,請(qǐng)確認(rèn)" }) } }, scope: this }, "-", { text: "放棄", cls: "red-btn", iconCls: baseConfig.appicon.undo, handler: function () { me.close(); }, scope: this }] me.callParent(arguments); }, //form表單的渲染在這里完成,目的是可以通過(guò)創(chuàng)建操作傳入?yún)?shù) loadView: function (config) { var formCmp = this.getComponent(0); formCmp.add([{ columnWidth: 1, layout: "form", items: [{ xtype: "textfield", fieldLabel: baseConfig.model.user.username, name: "username", maxLength: 250, maxLengthText: "請(qǐng)輸入{0}個(gè)字以?xún)?nèi)", emptyText: "登錄用的用戶(hù)名", bind: "{title}",//mvvm數(shù)據(jù)綁定,輸入的時(shí)候同步就顯示在win的title上了 allowBlank: false, flex: 1 }, { xtype: "textfield", fieldLabel: baseConfig.model.user.real_name, name: "real_name", maxLength: 10, maxLengthText: "請(qǐng)輸入{0}個(gè)字以?xún)?nèi)", emptyText: "真實(shí)姓名", allowBlank: false, flex: 1 } ] }]); } });
添加用戶(hù)的觸發(fā)動(dòng)作是在用戶(hù)列表頁(yè)面的添加按鈕,所以,還需要修改一下用戶(hù)列表頁(yè)面里對(duì)應(yīng)位置,加入觸發(fā)動(dòng)作,如下:
。。。。。 me.dockedItems = [{ xtype: "toolbar", items: [{ text: "添加", iconCls: baseConfig.appicon.add, tooltip: "添加", handler: function () { //create的時(shí)候,js會(huì)動(dòng)態(tài)加載進(jìn)來(lái)。 var win = Ext.create("luter.view.sys.user.UserAdd", { animateTarget: this//以這個(gè)按鈕為錨點(diǎn)動(dòng)畫(huà)打開(kāi)win }); win.loadView();//給form加入元素,可以在這里傳入一些參數(shù)給將要打開(kāi)的添加頁(yè)面 win.show();//顯示這個(gè)窗體 } }] }] 。。。。。。定義用戶(hù)信息修改窗口:app/luter/view/sys/user/UserEdit.js
Ext.define("luter.view.sys.user.UserEdit", { extend: "Ext.window.Window",//擴(kuò)展window組件 alias: "widget.usereditview", requires: [], constrain: true,//約束窗體彈出,別出瀏覽器可視范圍 modal: true,//模態(tài) maximizable: true,//可以最大化 iconCls: baseConfig.appicon.update,//圖標(biāo) layout: "fit",//自適應(yīng)布局 width: 700, autoHeight: true,//自適應(yīng)高度 initComponent: function () { var me = this; //加入一個(gè)表單,表單內(nèi)元素通過(guò)loadView方法添加 me.items = [{ xtype: "form", width: 700, autoHeight: true, fieldDefaults: { labelAlign: "right", labelStyle: "font-weight:bold;" }, border: false }] //操作按鈕直接加載window上 me.buttons = ["->", { text: "新增", cls: "green-btn", iconCls: baseConfig.appicon.add, handler: function () { var form = this.down("form"); if (form.isValid()) { form.submit({ url: "sys/user/update", method: "POST", waitTitle: "提示", waitMsg: "正在提交數(shù)據(jù),請(qǐng)稍后 ……", success: function (form, action) {//添加成功后提示消息,并且刷新用戶(hù)列表數(shù)據(jù) me.close(); DealAjaxResponse(action.response); Ext.data.StoreManager.lookup("UserStore").load(); }, failure: function (form, action) { DealAjaxResponse(action.response); } }); } else { toast({ msg: "表單填寫(xiě)錯(cuò)誤,請(qǐng)確認(rèn)" }) } }, scope: this }, "-", { text: "放棄", cls: "red-btn", iconCls: baseConfig.appicon.undo, handler: function () { me.close(); }, scope: this }] me.callParent(arguments); }, loadView: function (config) { var formCmp = this.getComponent(0); formCmp.add([{ columnWidth: 1, layout: "form", items: [{ xtype: "hidden",//這里放一個(gè)隱藏控件,因?yàn)槭切薷挠涗洠员仨毺峤籌D name: "id" }, { xtype: "textfield", fieldLabel: baseConfig.model.user.username, name: "username", maxLength: 250, maxLengthText: "請(qǐng)輸入{0}個(gè)字以?xún)?nèi)", emptyText: "登錄用的用戶(hù)名", allowBlank: false, flex: 1 }, { xtype: "textfield", fieldLabel: baseConfig.model.user.real_name, name: "real_name", maxLength: 10, maxLengthText: "請(qǐng)輸入{0}個(gè)字以?xún)?nèi)", emptyText: "真實(shí)姓名", allowBlank: false, flex: 1 } ] }]); } });
我們希望在雙擊用戶(hù)列表中的某一條記錄(某個(gè)用戶(hù))的時(shí)候,彈出用戶(hù)修改對(duì)話(huà)框,所以,修改用戶(hù)列表頁(yè)面代碼,添加列表行雙擊事件的監(jiān)聽(tīng),如下:
。。。。。。 me.listeners = { "itemdblclick": function (table, record, html, row, event, opt) { if (record) { var id = record.get("id"); var view = Ext.create("luter.view.sys.user.UserEdit", {title: "編輯數(shù)據(jù)", animateTarget: this}); view.loadView(); //為了保證數(shù)據(jù)完整性,拿到這條數(shù)據(jù)的ID后,需要從后臺(tái)獲取當(dāng)前這條數(shù)據(jù),然后再修改 //對(duì)于后臺(tái)而言,最好對(duì)數(shù)據(jù)設(shè)置@version功能,確保數(shù)據(jù)一致性。 loadFormDataFromDb(view, "app/testdata/user.json"); } else { showFailMesg({ msg: "加載信息失敗,請(qǐng)確認(rèn)。" }) } } } 。。。。。。添加記錄刪除操作
在用戶(hù)列表中,設(shè)置action列,實(shí)現(xiàn)刪除操作,如下:
....... me.columns = [{ xtype: "rownumberer", text: "序號(hào)", width: 60 }, { header: "操作", xtype: "actioncolumn", width: 60, sortable: false, items: [{ text: "刪除", iconCls: "icon-delete", tooltip: "刪除這條記錄", handler: function (grid, rowIndex, colIndex) { var record = grid.getStore().getAt(rowIndex); if (!record) { toast({ msg: "請(qǐng)選中一條要?jiǎng)h除的記錄" }) } else { showConfirmMesg({ message: "確定刪除這條記錄?", fn: function (btn) { if (btn === "yes") { showToastMessage("啥意思?");//測(cè)試一下而已,實(shí)際情況是執(zhí)行ajax刪除,如下。 // Ext.Ajax.request({ // url: "sys/user/delete", // method: "POST", // params: { // id: record.get("id") // }, // success: function (response, options) { // DealAjaxResponse(response); // Ext.data.StoreManager.lookup("UserStore").load(); // }, // failure: function (response, options) { // DealAjaxResponse(response); // } // }); } else { Ext.toast({ title:"看...", width:200, html: "不刪了....." }); return false; } } }) } } }] }, { header: baseConfig.model.user.id, dataIndex: "id", hidden: false, flex: 1 }, { header: baseConfig.model.user.username, dataIndex: "username", flex: 1 }, { header: baseConfig.model.user.real_name, dataIndex: "real_name", flex: 1 } ] .......extjs樣式覆蓋app/resource/css/admin.css
主要覆蓋了左側(cè)導(dǎo)航菜單treelist和中間tabpanel的部分風(fēng)格樣式,
記得在app.html中extjs樣式之后引入覆蓋樣式
.x-treelist-navigation { background-color: #32404e; background-position: 44px 0%; padding: 0 0 0 0 } .x-big .x-treelist-navigation { background-position: 0% } .x-treelist-navigation .x-treelist-toolstrip { background-color: #32404e } .x-treelist-navigation .x-treelist-item-selected.x-treelist-item-tool { background-color: #475360 } .x-treelist-navigation .x-treelist-item-selected.x-treelist-item-tool:after { height: 50px; position: absolute; top: 0; left: 0; content: " "; width: 5px; background-color: #35baf6 } .x-treelist-navigation .x-treelist-item-selected > .x-treelist-row { background-color: #475360 } .x-treelist-navigation .x-treelist-item-tool { padding-left: 10px; padding-right: 10px } .x-treelist-navigation .x-treelist-item-tool-floated:after { height: 50px; position: absolute; top: 0; left: 0; content: " "; width: 5px; background-color: #35baf6 } .x-treelist-navigation .x-treelist-item-icon:before, .x-treelist-navigation .x-treelist-item-tool:before, .x-treelist-navigation .x-treelist-item-expander { line-height: 50px } .x-treelist-navigation .x-treelist-item-icon, .x-treelist-navigation .x-treelist-item-tool, .x-treelist-navigation .x-treelist-item-expander { text-align: center; background-repeat: no-repeat; background-position: 0 center } .x-treelist-navigation .x-treelist-item-icon, .x-treelist-navigation .x-treelist-item-tool { color: #adb3b8; font-size: 18px; width: 44px } .x-treelist-navigation .x-treelist-item-tool { width: 50px } .x-treelist-navigation .x-treelist-item-expander { color: #fff; font-size: 16px; width: 24px } .x-treelist-navigation .x-treelist-item-text { color: #adb3b8; margin-left: 50px; margin-right: 24px; font-size: 14px; font-weight: 900; line-height: 50px } .x-treelist-navigation .x-treelist-row { padding-left: 10px; padding-right: 10px } .x-treelist-navigation .x-treelist-row-over:before, .x-treelist-navigation .x-treelist-item-selected > .x-treelist-row:before { content: " "; position: absolute; display: block; left: 0; top: 0; width: 5px; height: 100% } .x-treelist-navigation .x-treelist-row-over:before { background-color: transparent } .x-treelist-navigation .x-treelist-item-selected > .x-treelist-row-over:before { background-color: #57c6f8 } .x-treelist-navigation .x-treelist-item-selected > .x-treelist-row:before { background-color: #35baf6 } .x-treelist-navigation .x-treelist-item-floated .x-treelist-container { width: auto } .x-treelist-navigation .x-treelist-item-floated > .x-treelist-row { background-color: #32404e } .x-treelist-navigation .x-treelist-item-floated > .x-treelist-container { margin-left: -44px } .x-big .x-treelist-navigation .x-treelist-item-floated > .x-treelist-container { margin-left: 0 } .x-treelist-navigation .x-treelist-item-floated > * > * > .x-treelist-item-text { margin-left: 0 } .x-treelist-navigation .x-treelist-item-floated > * .x-treelist-row { padding-left: 0 } .x-treelist-navigation .x-treelist-item-floated .x-treelist-row:before { width: 0 } .x-treelist-navigation .x-treelist-item-floated > .x-treelist-row-over { background-color: #32404e } .x-treelist-navigation .x-treelist-item-floated > .x-treelist-row-over > * > .x-treelist-item-text { color: #adb3b8 } .x-treelist-navigation .x-treelist-item-expanded { background-color: #2c3845 } .x-treelist-navigation.x-treelist-highlight-path .x-treelist-item-over > * > .x-treelist-item-icon { color: #fff } .x-treelist-navigation.x-treelist-highlight-path .x-treelist-item-over > * > .x-treelist-item-text { color: #d6d9dc } .x-treelist-navigation.x-treelist-highlight-path .x-treelist-item-over > * > .x-treelist-item-expander { color: #fff } .x-treelist-navigation .x-treelist-row-over { background-color: #3c4a57 } .x-treelist-navigation .x-treelist-row-over > * > .x-treelist-item-icon { color: #fff } .x-treelist-navigation .x-treelist-row-over > * > .x-treelist-item-text { color: #d6d9dc } .x-treelist-navigation .x-treelist-row-over > * > .x-treelist-item-expander { color: #fff } .x-treelist-navigation .x-treelist-expander-first .x-treelist-item-icon { left: 24px } .x-treelist-navigation .x-treelist-expander-first .x-treelist-item-text { margin-left: 74px; margin-right: 0 } .x-treelist-navigation .x-treelist-expander-first .x-treelist-item-hide-icon > * > * > .x-treelist-item-text { margin-left: 30px } .x-treelist-navigation .x-treelist-item-hide-icon > * > * > .x-treelist-item-text { margin-left: 6px } .x-tab-bar-default{ height: 40px; /*background-color: #0e2349;*/ } .x-tab-default-top { -webkit-border-radius: 0; -moz-border-radius: 0; -ms-border-radius: 0; border-radius: 0; padding: 8px 10px 7px 10px; border-width: 0; border-style: solid; background-color: transparent } .x-tab-bar-default-top > .x-tab-bar-body-default{ padding:0 } .x-nbr .x-tab-default-top { padding: 0 !important; border-width: 0 !important; -webkit-border-radius: 0px; -moz-border-radius: 0px; -ms-border-radius: 0px; border-radius: 0px; background-color: transparent !important; box-shadow: none !important } .x-tab-default { border-color: transparent; cursor: pointer } .x-tab-default-top { margin: 0 4px 0 0 } .x-tab-default-top.x-tab-rotate-left { margin: 0 0 0 4px } .x-tab-default-top.x-tab-focus { -webkit-box-shadow: none; -moz-box-shadow: none; box-shadow: none } .x-tab-default-top.x-tab-focus.x-tab-over { -webkit-box-shadow: none; -moz-box-shadow: none; box-shadow: none } .x-tab-default-top.x-tab-focus.x-tab-active { -webkit-box-shadow: none; -moz-box-shadow: none; box-shadow: none; background-color: #1d9ce5; } .x-tab-button-default { padding-top: 5px; height: 20px } .x-tab-inner-default { font: 500 13px/20px "Open Sans", "Helvetica Neue", helvetica, arial, verdana, sans-serif; /*color: #f0f0f0;*/ max-width: 100% } .x-tab-bar-plain .x-tab-inner-default { color: #606060 } .x-tab-icon-right>.x-tab-inner-default, .x-tab-icon-left>.x-tab-inner-default { max-width: calc(100% - 20px) } .x-tab-icon-el-default { min-height: 20px; background-position: center center; font-size: 20px; line-height: 20px; color: #f0f0f0 } .x-tab-icon-left>.x-tab-icon-el-default, .x-tab-icon-right>.x-tab-icon-el-default { width: 20px } .x-tab-icon-top>.x-tab-icon-el-default, .x-tab-icon-bottom>.x-tab-icon-el-default { min-width: 20px } .x-tab-bar-plain .x-tab-icon-el-default { color: #606060 } .x-tab-icon-el-default.x-tab-glyph { opacity: 0.7 } .x-tab-text.x-tab-icon-left>.x-tab-icon-el-default { margin-right: 6px } .x-tab-text.x-tab-icon-right>.x-tab-icon-el-default { margin-left: 6px } .x-tab-text.x-tab-icon-top>.x-tab-icon-el-default { margin-bottom: 6px } .x-tab-text.x-tab-icon-bottom>.x-tab-icon-el-default { margin-top: 6px } .x-tab-focus.x-tab-default { border-color: transparent; background-color: transparent; outline: 1px solid #35baf6; outline-offset: -3px } .x-ie .x-tab-focus.x-tab-default, .x-ie10p .x-tab-focus.x-tab-default, .x-edge .x-tab-focus.x-tab-default { outline: none } .x-ie .x-tab-focus.x-tab-default:after, .x-ie10p .x-tab-focus.x-tab-default:after, .x-edge .x-tab-focus.x-tab-default:after { position: absolute; content: " "; top: 2px; right: 2px; bottom: 2px; left: 2px; border: 1px solid #35baf6; pointer-events: none } .x-tab-bar-plain .x-tab-focus.x-tab-default .x-tab-inner-default { color: #606060 } .x-tab-bar-plain .x-tab-focus.x-tab-default .x-tab-icon-el { color: #606060 } .x-tab-over.x-tab-default { border-color: #000; background-image: none; background-color: rgba(0, 0, 0, 0.08) } .x-ie8 .x-tab-over.x-tab-default { -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#14000000, endColorstr=#14000000)"; zoom: 1 } .x-ie8 .x-tab-over.x-tab-default.x-tab-rotate-left { -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=3)" } .x-ie8 .x-tab-over.x-tab-default.x-tab-rotate-right { -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=1)" } .x-tab-bar-plain .x-tab-over.x-tab-default .x-tab-inner-default { color: #606060 } .x-tab-bar-plain .x-tab-over.x-tab-default .x-tab-icon-el { color: #606060 } .x-tab-focus.x-tab-over.x-tab-default { border-color: #000; background-image: none; background-color: rgba(0, 0, 0, 0.08) } .x-ie8 .x-tab-focus.x-tab-over.x-tab-default { -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#14000000, endColorstr=#14000000)"; zoom: 1 } .x-ie8 .x-tab-focus.x-tab-over.x-tab-default.x-tab-rotate-left { -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=3)" } .x-ie8 .x-tab-focus.x-tab-over.x-tab-default.x-tab-rotate-right { -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=1)" } .x-tab-bar-plain .x-tab-focus.x-tab-over.x-tab-default .x-tab-inner-default { color: #606060 } .x-tab-bar-plain .x-tab-focus.x-tab-over.x-tab-default .x-tab-icon-el { color: #606060 } .x-tab.x-tab-active.x-tab-default { border-color: #fff; background-color: #fff } .x-tab.x-tab-active.x-tab-default .x-tab-inner-default { color: #105bf3 } .x-tab-bar-plain .x-tab.x-tab-active.x-tab-default .x-tab-inner-default { color: #404040 } .x-tab.x-tab-active.x-tab-default .x-tab-icon-el { color: #105bf3 } .x-ie8 .x-tab.x-tab-active.x-tab-default .x-tab-icon-el { color: #6ab5d6 } .x-tab-bar-plain .x-tab.x-tab-active.x-tab-default .x-tab-icon-el { color: #404040 } .x-tab-focus.x-tab-active.x-tab-default { border-color: #fff; background-color: #fff } .x-tab-bar-plain .x-tab-focus.x-tab-active.x-tab-default .x-tab-inner-default { color: #404040 } .x-tab-bar-plain .x-tab-focus.x-tab-active.x-tab-default .x-tab-icon-el { color: #404040 } .x-tab.x-tab-disabled.x-tab-default { border-color: transparent; background-color: transparent; cursor: default } .x-tab.x-tab-disabled.x-tab-default .x-tab-inner-default { -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=30)"; opacity: 0.3 } .x-tab-bar-plain .x-tab.x-tab-disabled.x-tab-default .x-tab-inner-default { color: #606060 } .x-tab.x-tab-disabled.x-tab-default .x-tab-icon-el-default { -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=50)"; opacity: 0.5 } .x-tab.x-tab-disabled.x-tab-default .x-tab-icon-el { color: #f0f0f0; opacity: 0.3; filter: none } .x-tab-bar-plain .x-tab.x-tab-disabled.x-tab-default .x-tab-icon-el { color: #606060 } .x-nbr .x-tab-default { background-image: none } .x-tab-default .x-tab-close-btn:before { content: "f00d" } .x-tab-default .x-tab-close-btn { top: 0; right: 0; width: 12px; height: 12px; font: 12px/1 FontAwesome; color: red } .x-tab-default.x-tab-active .x-tab-close-btn { color: red } .x-tab-default .x-tab-close-btn-over { background-position: -12px 0; color: red }
至此,應(yīng)該能看到基本的界面的樣子了:)
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/92693.html
摘要:例如,系統(tǒng)中某個(gè)用戶(hù)辭職了,只需要將系統(tǒng)中該用戶(hù)的角色授權(quán)撤銷(xiāo)即可。 Q0.有哪些概念需要知道? 一些概念的具體定義如下 用戶(hù)(user): 和計(jì)算機(jī)系統(tǒng)交互的人(在許多設(shè)計(jì)方案中,單個(gè)用戶(hù)可能擁有多個(gè)登錄標(biāo)識(shí)(ID),這些標(biāo)識(shí)可能同時(shí)處于活躍狀態(tài),但身份驗(yàn)證機(jī)制可以使多個(gè)標(biāo)識(shí)匹配到某個(gè)具體的人,即用戶(hù)對(duì)于計(jì)算機(jī)系統(tǒng)來(lái)說(shuō)具有唯一性) 主體(subject): 一個(gè)代表用戶(hù)行為的計(jì)算機(jī)...
摘要:結(jié)構(gòu)實(shí)踐三完善基本頁(yè)面一般經(jīng)典的后臺(tái)管理系統(tǒng),都是左側(cè)菜單右側(cè)結(jié)構(gòu)布局。不免俗,咱也這么實(shí)現(xiàn)定義左側(cè)導(dǎo)航菜單新建采用的組件構(gòu)建一個(gè)導(dǎo)航菜單為了顯示圖標(biāo),引入字體圖標(biāo),在引入引入定義導(dǎo)航菜單數(shù)據(jù)功能菜單展開(kāi)節(jié)點(diǎn)。 extjs-mvc結(jié)構(gòu)實(shí)踐(三):完善基本頁(yè)面2 一般經(jīng)典的后臺(tái)管理系統(tǒng),都是左側(cè)菜單右側(cè)tabs結(jié)構(gòu)布局。不免俗,咱也這么實(shí)現(xiàn)! 定義左側(cè)導(dǎo)航菜單 新建:app/luter/...
摘要:值得一提的是擴(kuò)展包不免費(fèi)用于商業(yè)用途,作者用一種人類(lèi)友好的方式說(shuō)你使用這個(gè)擴(kuò)展包就是應(yīng)該去掙錢(qián)的,而不是免費(fèi)的去工作這個(gè)擴(kuò)展包收費(fèi)美元。除了這些,還有五個(gè)沒(méi)有全面的審查的擴(kuò)展包。最后,還有三個(gè)優(yōu)質(zhì)的包選擇于。 showImg(https://segmentfault.com/img/remote/1460000012312105?w=2200&h=1125); 開(kāi)發(fā)者們都是懶惰的,不,...
摘要:值得一提的是擴(kuò)展包不免費(fèi)用于商業(yè)用途,作者用一種人類(lèi)友好的方式說(shuō)你使用這個(gè)擴(kuò)展包就是應(yīng)該去掙錢(qián)的,而不是免費(fèi)的去工作這個(gè)擴(kuò)展包收費(fèi)美元。除了這些,還有五個(gè)沒(méi)有全面的審查的擴(kuò)展包。最后,還有三個(gè)優(yōu)質(zhì)的包選擇于。 showImg(https://segmentfault.com/img/remote/1460000012312105?w=2200&h=1125); 開(kāi)發(fā)者們都是懶惰的,不,...
閱讀 1209·2021-11-22 12:05
閱讀 1336·2021-09-29 09:35
閱讀 630·2019-08-30 15:55
閱讀 3122·2019-08-30 14:12
閱讀 954·2019-08-30 14:11
閱讀 2875·2019-08-30 13:10
閱讀 2400·2019-08-29 16:33
閱讀 3327·2019-08-29 11:02