前言:

jsplumb 有2个版本一个Toolkit Edition(付费版),另外一个就是Community Edition(社区版本)。Toolkit Edition版本功能集成的比较丰富,社区版本的就差好多,很多功能都没有,需要我们自己去添加,当然了自己添加多多少少有些麻烦,而且也不完善。但是我们还是用Community Edition(社区版本),毕竟不收费,没办法,下边所说的版本默认都是以社区版。

最近公司项目有用到这个流程图,所以也就看到了这个框架,这个框架是英文版本的,地址:https://jsplumbtoolkit.com/community/doc/home.html(可以用浏览器翻译了看)。他的缺陷就是文档不全,api感觉也有点乱,实例交代的也不清楚,github地址是:https://github.com/jsplumb/jsplumb (里面有demo,自己可以下载运行,多动手试试)。如果只是简单的画个图,这个框架是没有什么问题的,demo里也有,但是如果要实现高级的动能呢鞥,还是得多多尝试。此文也是记录一下我自己用到的一些功能,很多我还没用到,用到了在慢慢补充。

 
jsplumb.png

上图也就是我这次用到的jsplumb实现的功能,连接线能够拖拽生成,也可以删除,编辑label。

1、数据结构

  1. {
  2. "nodes": [{ //节点集合
  3. "icon": "el-icon-loading",
  4. "id": "start",
  5. "nodeStyle": {
  6. "top": 100,
  7. "left": 200
  8. },
  9. "text": "开始",
  10. "type": "circle"
  11. }, {
  12. "icon": "el-icon-upload",
  13. "id": "end",
  14. "nodeStyle": {
  15. "top": 300,
  16. "left": 400
  17. },
  18. "text": "结束",
  19. "type": "circle"
  20. }] ,
  21. "connections": [{ //连接线集合
  22. "sourceId": "start",
  23. "targetId": "end",
  24. "label":"编辑"
  25. }]
  26. }

jsplumb实例里面的数据结构就是这样的,这里我们沿用他的数据结构,你也可以自己定义自己想的数据结构,但是对比起来这个结构是最清晰也最方便的。

2、初始化

jsplumb在DOM渲染完毕之后才会执行,所以需要为jsplumb的执行代码绑定一个ready事件:

  1. jsPlumb.ready(function() {
  2. // your jsPlumb related init code goes here
  3. });

jsplumb默认是注册在浏览器窗口的,将整个页面提供给我们作为一个实例,但我们也可以使用getInstance方法建立页面中一个独立的实例:

  1. var _instance = jsPlumb.getInstance();

3、功能实现(允许哪些元素拖拽,允许拆卸连接)

  1. let instance = jsPlumb.getInstance({
  2. PaintStyle:{
  3. strokeWidth:2,
  4. stroke:"#567567",
  5. }
  6. })
  7. //拖拽功能
  8. var els = document.querySelectorAll(".box");//.box是允许拖拽的元素class类名
  9. instance.draggable(els,{
  10. containment:true,
  11. filter: ".ep",//除去不能拖拽的,这里是个class类名
  12. });
  13. //不允许拆卸连接,不设置的话默认是可以的
  14. instance.importDefaults({
  15. ConnectionsDetachable:false
  16. });

4、连线监听事件(拖动connection 事件)

  1. // 监听拖动connection 事件,判断是否有重复链接
  2. instance.bind("beforeDrop", function(info) {
  3. // info.connection.getOverlay("label").setLabel(info.connection.id);
  4. // 判断是否已有该连接
  5. let isSame = true;
  6. //下边的forEach循环就是处理数据结构里的connections不能自己跟自己连线。当然你也可以处理其他
  7. _this.chartData.connections.forEach(item => {
  8. if ((item.targetId === info.targetId && item.sourceId === info.sourceId) || (item.targetId === info.sourceId && item.sourceId === info.targetId)) {
  9. isSame = false;
  10. }
  11. });
  12. if (isSame) {
  13. //允许连线后处理的情况
  14. } else {
  15. alert("不允许重复连接!");
  16. }
  17. return isSame;//这里返回了ture就会自定进行连线。
  18. });

5、上图实现的完整代码

下边代码就是实现上图的,需要指出的是运用了vue,但是里面掺杂了jquery,和jquery-ui,其实不想用这2个的,但是项目紧,之前项目也用到了,所以就延续了。还有就是上面代码是我自己的测试代码,写的可能有些杂乱,就是测试一个一个功能而写,写的有点乱。

还有一个想说的就是之前想实现,缩放,引入了panzoom.js,流程图也实现了滚动鼠标放大放小,但是有个问题就是滚动鼠标放大放小后如果拖动单个元素或者连线,你就会发现鼠标点对不齐了,这点还没有解决,如果有好的方案,可以告知我下。Toolkit Edition(付费版)的这些功能都有,就不会出现这样的问题。

  1. <template>
  2. <div id="test6" style="height:100%;position:relative">
  3. <section id="focal" style="position:relative;overflow:hidden;width:610px;height:610px;background:#fff;border:1px solid red">
  4. <div class="parent" id="parent" style="height:100%;">
  5. <div class="panzoom" id="panzoom" style="border:1px solid blue;width:6000px;height:6000px; transform:translate(-50%, -50%);position:absolute;">
  6. <div class="box" :id="item.id" :style="{'top':item.nodeStyle.top+'px','left':item.nodeStyle.left+'px'}" v-for="item in chartData.nodes" :key="item.id">
  7. <i :class="item.icon" class="oldIcon" :title="item.text"></i>
  8. <i class="el-icon-circle-close" style="display:none" :title="item.text" :id="item.id"></i>
  9. <div class="ep"></div>
  10. </div>
  11. </div>
  12. </div>
  13. </section>
  14. <div class="source">
  15. <ul>
  16. <li v-for="(item,index) in list" :id="item.id" :key="index" class="sourceLi" :disabled="true" :data-icon="item.icon" :data-text="item.text" :data-type="item.type">{{item.text}}</li>
  17. </ul>
  18. </div>
  19. <el-dialog
  20. title="修改label名称"
  21. :visible.sync="dialogVisible"
  22. width="30%"
  23. :before-close="handleClose">
  24. <el-input v-model="labelName" placeholder="请输入"></el-input>
  25. <span slot="footer" class="dialog-footer">
  26. <el-button @click="dialogVisible = false">取 消</el-button>
  27. <el-button type="primary" @click="changeNote">确 定</el-button>
  28. </span>
  29. </el-dialog>
  30. </div>
  31. </template>
  32. <script>
  33. import ChartNode from "@/components/ChartNode";
  34. export default {
  35. name: "test6",
  36. data() {
  37. return {
  38. dialogVisible:false,
  39. labelName:"",
  40. curSourceId:'',
  41. curTargetId:'',
  42. addLabelText:'',//拖拽后生成的连线label文字
  43. jsp:null,
  44. myscale:1,
  45. curScreen:[],//当前屏幕宽高
  46. chartData: {
  47. nodes: [],
  48. connections: [],//{ "targetId": "box2", "sourceId": "box1" }
  49. props: {},
  50. screen:[610,610]//提交屏幕宽高
  51. },
  52. list: [
  53. {
  54. icon: "el-icon-goods",
  55. text: "伴随车牌",
  56. type: "circle",
  57. id:'li1'
  58. },
  59. {
  60. icon: "el-icon-bell",
  61. text: "常住人口筛选",
  62. type: "diamond",
  63. id:"li2"
  64. },
  65. {
  66. icon: "el-icon-date",
  67. text: "伴随imsi",
  68. type: "circle",
  69. id:"li3"
  70. }
  71. ]
  72. };
  73. },
  74. mounted() {
  75. let _this = this
  76. jsPlumb.ready(function() {
  77. var $section = $('#focal');
  78. var $panzoom = $section.find('.panzoom').panzoom({
  79. minScale: 0.3,
  80. maxScale:2,
  81. eventNamespace: ".panzoom",
  82. $zoomRange: $(".jtk-endpoint"),
  83. $set: $section.find('.jtk-overlay'),
  84. eventsListenerElement: document.querySelector('.box')
  85. });
  86. $(document).on('mouseover','.box,.jtk-draggable,.jtk-overlay,.ep',function(){
  87. $('.panzoom').panzoom("disable");
  88. })
  89. $(document).on('mouseleave','.box,.jtk-draggable,.jtk-overlay,.ep',function(){
  90. $('.panzoom').panzoom("enable");
  91. })
  92. let instance = jsPlumb.getInstance({
  93. PaintStyle:{
  94. strokeWidth:2,
  95. stroke:"#567567",
  96. },
  97. // Connector: ["Straight", { stub: [0,0], gap:[-30,-30] }],
  98. Connector:[ "Straight", { curviness: 0 } ],
  99. Endpoint: ["Blank",{ cssClass: "chart-dot", hoverClass: "chart-dot-hover", radius: 5 }],
  100. EndpointStyle : { fill: "blue" },
  101. HoverPaintStyle:{
  102. stroke:"red",
  103. },
  104. DragOptions: { cursor: "pointer", zIndex: 2000 },
  105. ConnectionOverlays: [
  106. [
  107. "Arrow",
  108. {
  109. location: 1,
  110. visible: true,
  111. width: 11,
  112. length: 11,
  113. id: "ARROW",
  114. events: {
  115. click: function() {
  116. alert("you clicked on the arrow overlay");
  117. }
  118. }
  119. }
  120. ],
  121. ["Label", { label: "", id: "label", cssClass: "aLabel" }]
  122. ],
  123. Container: "panzoom"
  124. })
  125. _this.jsp = instance;
  126. //拖拽功能
  127. var els = document.querySelectorAll(".box");
  128. instance.draggable(els,{
  129. containment:true,
  130. filter: ".ep",//除去不能拖拽的
  131. grid:[50,50]
  132. });
  133. //不允许拆卸连接,不设置的话默认是可以的
  134. instance.importDefaults({
  135. ConnectionsDetachable:false
  136. });
  137. // 监听拖动connection 事件,判断是否有重复链接
  138. instance.bind("beforeDrop", function(info) {
  139. // info.connection.getOverlay("label").setLabel(info.connection.id);
  140. console.log(info);
  141. // 判断是否已有该连接
  142. let isSame = true;
  143. _this.chartData.connections.forEach(item => {
  144. if ((item.targetId === info.targetId && item.sourceId === info.sourceId) || (item.targetId === info.sourceId && item.sourceId === info.targetId)) {
  145. isSame = false;
  146. }
  147. });
  148. if (isSame) {
  149. _this.addLabelText = "新label"
  150. _this.chartData.connections.push({
  151. sourceId: info.sourceId,
  152. targetId: info.targetId,
  153. label:_this.addLabelText
  154. });
  155. } else {
  156. alert("不允许重复连接!");
  157. }
  158. return isSame;
  159. });
  160. var initNode = function(el) {
  161. instance.draggable(el, {
  162. // containment: true,
  163. start(params) {
  164. // 拖动开始
  165. // console.log(params);
  166. },
  167. drag(params) {
  168. // 拖动中
  169. // console.log(params);
  170. },
  171. stop(params) {
  172. // 拖动结束
  173. console.log(params);
  174. let id = params.el.id;
  175. _this.chartData.nodes.forEach(item => {
  176. if (item.id === id) {
  177. item.nodeStyle.left = params.pos[0];
  178. item.nodeStyle.top = params.pos[1] ;
  179. }
  180. });
  181. }
  182. });
  183. instance.makeSource(el, {
  184. filter: ".ep",
  185. anchor: ["Perimeter", { shape: "Rectangle" }],
  186. // anchor: ["Perimeter", { shape: "Dot" }],
  187. connectorStyle: {
  188. stroke: "#5c96bc",
  189. strokeWidth: 2,
  190. outlineStroke: "transparent",
  191. outlineWidth: 4
  192. },
  193. extract: {
  194. action: "the-action"
  195. },
  196. maxConnections: -1,
  197. onMaxConnections: function(info, e) {
  198. alert("Maximum connections (" + info.maxConnections + ") reached");
  199. }
  200. });
  201. instance.makeTarget(el, {
  202. dropOptions: { hoverClass: "dragHover" },
  203. anchor: ["Perimeter", { shape: "Rectangle" }],
  204. allowLoopback: false
  205. });
  206. // instance.fire("jsPlumbDemoNodeAdded", el);
  207. };
  208. //初始化遮罩层
  209. var init = function(connection) {
  210. if(_this.addLabelText){
  211. connection.getOverlay("label").setLabel(_this.addLabelText);
  212. }else{
  213. connection.getOverlay("label").setLabel('编辑');
  214. }
  215. $(connection.getOverlay("label").canvas).attr('mySourceId',connection.sourceId)
  216. $(connection.getOverlay("label").canvas).attr('myTargetId',connection.targetId)
  217. };
  218. // 将模块拖入画板中
  219. $(".sourceLi").draggable({
  220. scope: "plant",
  221. helper: "clone",
  222. opacity: 0.7,
  223. containment: $("#test1")
  224. });
  225. $("#panzoom").droppable({
  226. scope: "plant",
  227. drop: function(ev, ui) {
  228. console.log(ev, ui);
  229. let helper = ui.helper;
  230. let id = jsPlumbUtil.uuid();
  231. let item = {
  232. id,
  233. icon: helper.attr("data-icon"),
  234. type: helper.attr("data-type"),
  235. text: helper.attr("data-text"),
  236. nodeStyle: {
  237. top: ui.offset.top - $("#panzoom").offset().top ,
  238. left: ui.offset.left - $("#panzoom").offset().left
  239. }
  240. };
  241. console.log(ui.position)
  242. _this.chartData.nodes.push(item);
  243. _this.$nextTick(() => {
  244. initNode(id);
  245. });
  246. }
  247. });
  248. instance.batch(() => {
  249. jsPlumb.getSelector(".box").forEach(item => {
  250. console.log(item)
  251. initNode(item);
  252. });
  253. instance.bind("connection", function(connInfo, originalEvent) {
  254. init(connInfo.connection);
  255. //显示删除按钮
  256. $(connInfo.connection.getOverlay("label").canvas).hover(function() {
  257. $(this).append('<div class="x" style="position: absolute;">X</div>');
  258. }, function() {
  259. $(this).find(".x").stop().remove();
  260. })
  261. //删除连接
  262. $(connInfo.connection.getOverlay("label").canvas).on('click','.x',function(){
  263. console.log("shanchu")
  264. let _connections = _this.chartData.connections;
  265. _connections.forEach((val,index)=>{
  266. if(val.targetId == connInfo.connection.targetId && val.sourceId == connInfo.connection.sourceId){
  267. _connections.splice(index,1)
  268. }
  269. })
  270. instance.deleteConnection(connInfo.connection);
  271. $('.panzoom').panzoom("enable");//这个是为了杜绝删除前的禁止拖拽事件
  272. })
  273. //label双击事件
  274. $(connInfo.connection.getOverlay("label").canvas).on("dblclick",function(conn, connInfo){
  275. let _allConnections = _this.jsp.getAllConnections();
  276. _this.dialogVisible = true
  277. _this.curSourceId = $(conn.target).attr('mySourceId')
  278. _this.curTargetId = $(conn.target).attr('myTargetId')
  279. _allConnections.forEach((val,index)=>{
  280. if(val.targetId == $(conn.target).attr('myTargetId') && val.sourceId == $(conn.target).attr('mySourceId')){
  281. _this.labelName = val.getOverlay('label').label
  282. }
  283. })
  284. })
  285. });
  286. });
  287. instance.fire("jsPlumbDemoLoaded", instance);
  288. $(document).on("dblclick",".box",function(){
  289. $(this).find(".oldIcon").css('display','none')
  290. $(this).find('.el-icon-circle-close').css('display','inline-block')
  291. })
  292. $(document).on("click",".el-icon-circle-close",function(){
  293. let _note = _this.chartData.nodes
  294. let _id = $(this).attr("id")
  295. let _connections = _this.chartData.connections;
  296. let _allConnections = instance.getAllConnections();
  297. _this.chartData.connections = _connections.filter((val)=>{
  298. return (val.targetId != _id && val.sourceId != _id)
  299. })
  300. _note.forEach((val,index)=>{
  301. if(val.id == _id){
  302. _note.splice(index,1)
  303. }
  304. })
  305. _allConnections.forEach((val,index)=>{
  306. if(val.targetId == _id || val.sourceId == _id){
  307. instance.deleteConnectionsForElement(_id)
  308. }
  309. })
  310. })
  311. _this.handleClickTemp(1)
  312. });
  313. },
  314. methods:{
  315. myclick(){
  316. alert("myclickmyclickmyclickmyclick")
  317. },
  318. // 初始化node节点
  319. initNode(el) {
  320. // initialise draggable elements.
  321. // 元素拖动,基于 katavorio.js 插件
  322. let _self = this;
  323. this.jsp.draggable(el, {
  324. // containment: true,
  325. start(params) {
  326. // 拖动开始
  327. // console.log(params);
  328. },
  329. drag(params) {
  330. // 拖动中
  331. // console.log(params);
  332. },
  333. stop(params) {
  334. // 拖动结束
  335. console.log(params);
  336. let id = params.el.id;
  337. _self.chartData.nodes.forEach(item => {
  338. if (item.id === id) {
  339. item.nodeStyle.left = params.pos[0]
  340. item.nodeStyle.top = params.pos[1]
  341. }
  342. });
  343. }
  344. });
  345. this.jsp.makeSource(el, {
  346. filter: ".ep",
  347. // anchor: "Continuous",
  348. anchor: ["Perimeter", { shape: "Rectangle" }],
  349. connectorStyle: {
  350. stroke: "#5c96bc",
  351. strokeWidth: 2,
  352. outlineStroke: "transparent",
  353. outlineWidth: 4
  354. },
  355. extract: {
  356. action: "the-action"
  357. },
  358. maxConnections: -1,
  359. onMaxConnections: function(info, e) {
  360. alert("Maximum connections (" + info.maxConnections + ") reached");
  361. }
  362. });
  363. this.jsp.makeTarget(el, {
  364. dropOptions: { hoverClass: "dragHover" },
  365. anchor: ["Perimeter", { shape: "Rectangle" }],
  366. allowLoopback: false
  367. });
  368. // this is not part of the core demo functionality; it is a means for the Toolkit edition's wrapped
  369. // version of this demo to find out about new nodes being added.
  370. //
  371. this.jsp.fire("jsPlumbDemoNodeAdded", el);
  372. },
  373. handleClickTemp(key) {
  374. this.chartData = {
  375. nodes: [],
  376. connections: [],
  377. props: {}
  378. };
  379. this.jsp.empty("panzoom");
  380. if (key) {
  381. let url = "/static/json/" + 1 + ".json";
  382. this.$axios
  383. .get(url)
  384. .then(resp => {
  385. console.log(resp);
  386. let _data = resp.data
  387. let _reloatScreen = _data.screen
  388. let _scale = $("#focal").width() / _data.screen[0]
  389. let _focalWidth = $("#focal").width()
  390. let _focalHeight = $("#focal").height()
  391. let _panzoomWidth = $("#panzoom").width()
  392. debugger
  393. _data.nodes.forEach((val,index)=>{
  394. val.nodeStyle.left = parseInt(val.nodeStyle.left) * _scale - (_panzoomWidth*_scale-_panzoomWidth)/2
  395. val.nodeStyle.top = parseInt(val.nodeStyle.top) * _scale - (_panzoomWidth*_scale-_panzoomWidth)/2
  396. })
  397. // $("#panzoom").css({'width':_panzoomWidth*_scale+'px','height':_panzoomWidth*_scale+'px'})
  398. this.chartData = _data;
  399. this.$nextTick(() => {
  400. this.chartData.nodes.forEach(item => {
  401. this.initNode(item.id);
  402. });
  403. this.chartData.connections.forEach(item => {
  404. let _connects = this.jsp.connect({
  405. source: item.sourceId,
  406. target: item.targetId
  407. });
  408. _connects.getOverlay("label").setLabel(item.label)
  409. $(_connects.getOverlay("label").canvas).attr('mySourceId',item.sourceId)
  410. $(_connects.getOverlay("label").canvas).attr('myTargetId',item.targetId)
  411. });
  412. });
  413. })
  414. .catch(err => {
  415. console.log(err);
  416. });
  417. } else {
  418. this.$nextTick(() => {
  419. this.chartData.nodes.push({
  420. id: "start",
  421. icon: "el-icon-loading",
  422. type: "circle",
  423. text: "开始",
  424. nodeStyle: {
  425. top: "100px",
  426. left: "300px"
  427. }
  428. });
  429. this.$nextTick(() => {
  430. this.jsp.batch(() => {
  431. this.initNode(jsPlumb.getSelector("#start"));
  432. });
  433. });
  434. });
  435. }
  436. },
  437. changeNote(){//修改label
  438. if(!this.labelName){
  439. alert("名称没有填写")
  440. return false
  441. }
  442. let _allConnections = this.jsp.getAllConnections();
  443. _allConnections.forEach((val,index)=>{
  444. if(val.sourceId == this.curSourceId && val.targetId == this.curTargetId ){
  445. val.getOverlay("label").setLabel(this.labelName)
  446. }
  447. })
  448. this.chartData.connections.forEach(val => {
  449. if(val.sourceId == this.curSourceId && val.targetId == this.curTargetId ){
  450. val.label = this.labelName
  451. }
  452. });
  453. this.dialogVisible = false
  454. },
  455. handleClose(){
  456. this.dialogVisible = false
  457. }
  458. },
  459. components: {
  460. ChartNode
  461. }
  462. };
  463. </script>
  464. <style lang="scss" scoped>
  465. #test1{
  466. position:relative;
  467. width:90%;
  468. height:90%;
  469. border:1px solid #ddd;
  470. background:#fff;
  471. }
  472. .box{
  473. border-radius:50%;
  474. text-align: center;
  475. cursor: pointer;
  476. background-color: white;
  477. border: 1px solid #346789;
  478. text-align: center;
  479. z-index: 24;
  480. cursor: pointer;
  481. box-shadow: 2px 2px 19px #aaa;
  482. -o-box-shadow: 2px 2px 19px #aaa;
  483. -webkit-box-shadow: 2px 2px 19px #aaa;
  484. -moz-box-shadow: 2px 2px 19px #aaa;
  485. position: absolute;
  486. color: black;
  487. padding: 0.5em;
  488. width: 40px;
  489. height: 40px;
  490. display: flex;
  491. align-items: center;
  492. justify-content: center;
  493. -webkit-transition: -webkit-box-shadow 0.15s ease-in;
  494. -moz-transition: -moz-box-shadow 0.15s ease-in;
  495. -o-transition: -o-box-shadow 0.15s ease-in;
  496. transition: box-shadow 0.15s ease-in;
  497. .ep {
  498. opacity: 0;
  499. position: absolute;
  500. right: -10px;
  501. top: 0;
  502. width: 10px;
  503. height: 10px;
  504. background: #409eff;
  505. border-radius: 5px;
  506. }
  507. &:hover {
  508. .ep {
  509. opacity: 1;
  510. }
  511. }
  512. &.dragHover {
  513. .ep {
  514. opacity: 0;
  515. }
  516. }
  517. }
  518. .box:hover {
  519. border: 1px solid #123456;
  520. box-shadow: 2px 2px 19px #444;
  521. -o-box-shadow: 2px 2px 19px #444;
  522. -webkit-box-shadow: 2px 2px 19px #444;
  523. -moz-box-shadow: 2px 2px 19px #fff;
  524. opacity: 0.9;
  525. }
  526. .box:hover,
  527. .box.jtk-source-hover,
  528. .box.jtk-target-hover {
  529. border: 1px solid orange;
  530. color: orange;
  531. }
  532. .box1{
  533. top:50px;
  534. left:50px;
  535. }
  536. .box2{
  537. top:160px;
  538. left:250px;
  539. }
  540. .box3{
  541. top:360px;
  542. left:150px;
  543. }
  544. .box4{
  545. top:350px;
  546. left:450px;
  547. }
  548. .chart-dot-hover{
  549. display: block;
  550. background: red
  551. }
  552. .source{
  553. position:absolute;
  554. top:50px;
  555. right:50px;
  556. border:1px solid red;
  557. width:200px;
  558. height:300px;
  559. li{
  560. line-height:36px;
  561. border:1px solid #ddd;
  562. margin-bottom:10px;
  563. cursor:pointer
  564. }
  565. }
  566. </style>
  567. <style>.aLabel{
  568. border: 1px solid blue;
  569. padding: 4px;
  570. }
  571. .x{
  572. top:-10px;
  573. right:-10px;
  574. cursor: pointer;
  575. }
  576. .jtk-overlay{
  577. padding: 0
  578. }
  579. </style>

 

jsplumb 流程图,常用功能配置记录的更多相关文章

  1. Nginx常用功能配置一

    Nginx常用功能配置 参数include配置 说明:如果日常工作中server标签存在太多,可以采用include配置模式,Nginx的主配置文件包含的所有虚拟主机的子配置文件会统一放入extra目 ...

  2. Nginx常用功能配置二

    Nginx常用功能配置二 Nginx location匹配设置 location作用:可以根据用户请求的URI来执行不同的应用,根据用户请求的网站的地址URL匹配. location语法: locat ...

  3. Apache运维中常用功能配置笔记梳理

    Apache 是一款使用量排名第一的 web 服务器,LAMP 中的 A 指的就是它.由于其开源.稳定.安全等特性而被广泛使用.下边记录了使用 Apache 以来经常用到的功能,做此梳理,作为日常运维 ...

  4. nginx常用功能配置

    一.规范优化nginx配置文件 nginx的主配置文件为nginx.conf,主配置文件包含的所有虚拟主机的子配置文件会统一放入extra目录中,虚拟主机的配置文件按照网站的域名或功能取名,例如www ...

  5. Ubuntu 常用环境配置记录

    引言 经常使用 Ubuntu 虚拟机,双系统,WSL,服务器等等,每次配置常用开发环境都要去百度细节,故在此记录一下. 更换软件源 阿里云镜像 清华镜像 # 更新 sudo apt update &a ...

  6. vim 常用命令逐渐熟悉以及常用的配置记录

    本篇博客记录的是我自己学习vim的常用命令的过程中,各个命令的逐渐熟悉的顺序(有一部分已经熟悉的命令没有列出),已经对vim编辑器本身的一些设置的记录 1.G 快速将光标切换到文件的最底部 2.u 撤 ...

  7. nginx下目录浏览及其验证功能配置记录

    工作中常常有写不能有网页下载东西的需求,在Apache下搭建完成后直接导入文件即可达到下载/显示文件的效果;而Nginx的目录列表功能默认是关闭的,如果需要打开Nginx的目录列表功能,需要手动配置, ...

  8. Echarts图表常用功能配置,Demo示例

    先看下效果图: 就如上图所示,都是些常用的基本配置. Legend分页,X轴设置,Y轴设置,底部缩放条设置, 数值显示样式设置,工具箱设置,自定义工具按钮, 绑定点击事件等等.这些配置代码中都做了简单 ...

  9. centos中apache自用常用额外配置记录(xwamp)

    xwamp套件中apache配置,记录下,以免忘记. 配置路径 ${wwwroot_dir}/conf/httpd.conf 配置内容 <ifmodule mod_deflate.c> D ...

随机推荐

  1. go常量的定义和枚举类型

    const a,b int = 1,2 const a,b     = 1,2 const ( a = "hello" b,c =3,4 ) 常量数值可作为各种类型使用 枚举类型的 ...

  2. CSS定位有几种?分别描述其不同

    static(静态定位):即默认值,元素框正常生成的,top.right.bottom.left这些偏移属性不会影响静态定位的正常显示(属性不应用): relative(相对定位):元素相对自身偏移某 ...

  3. js 数组中如何删除字典

    区别: []表示是一个数组,如var strs = ['a','b','c'].{}表示是一个对象,比如,var obj = {name: '宙斯',sex: 1} 如何在数组中删除指定对象呢?? [ ...

  4. Spring框架加案例

    依赖: <!-- https://mvnrepository.com/artifact/org.springframework/spring-beans --> <dependenc ...

  5. Oracle 绑定变量窥视

    绑定变量窥视功能是数据库的一个特性,自ORACLE9i版本开始引入,默认是开启的. “绑定变量窥视”表示,查询优化器在第一次调用游标时,会观察用户定义的绑定变量的值,允许优化器来确认过滤条件的选择性, ...

  6. Elasticsearch 索引文档的增删改查

    利用Elasticsearch-head可以在界面上(http://127.0.0.1:9100/)对索引进行增删改查 1.RESTful接口使用方法 为了方便直观我们使用Head插件提供的接口进行演 ...

  7. 【原创】go语言学习(十七)接口应用实战--日志库

    目前 日志库需求分析 日志库接口设计 文件日志库开发 Console日志开发 日志使用以及测试 日志库需求分析 1.日志库需求分析 A. 程序运行是个黑盒B. 而日志是程序运行的外在表现C. 通过日志 ...

  8. 修改rabbitmq web-UI端口号

    一.拷贝配置文件 [root@test03 ~]# cd /usr/share/doc/rabbitmq-server-3.6.15/ [root@test03 rabbitmq-server-3.6 ...

  9. 【SPOJ】Longest Common Substring

    [SPOJ]Longest Common Substring 求两个字符串的最长公共子串 对一个串建好后缀自动机然后暴力跑一下 废话 讲一下怎么跑吧 从第一个字符开始遍历,遍历不到了再沿着\(pare ...

  10. 搞定TADA68机械键盘的固件修改

    一.先到http://config.qmk.fm,在键盘型号中选择tada68,千万不要选择错了,可在kdemap name中为自己的键位名个名,例如:vimgood 二.修改自己的键位,都是可视化的 ...