<address id="ttjl9"></address>

      <noframes id="ttjl9"><address id="ttjl9"><nobr id="ttjl9"></nobr></address>
      <form id="ttjl9"></form>
        <em id="ttjl9"><span id="ttjl9"></span></em>
        <address id="ttjl9"></address>

          <noframes id="ttjl9"><form id="ttjl9"></form>

          首頁

          mysql數據類型

          前端達人

          本文出自 “旋木的技術博客” 博客,請務必保留此出處http://mrxiong.blog.51cto.com/287318/1651098


          一.數值類型

          Mysql支持所有標準SQL中的數值類型,其中包括嚴格數據類型(INTEGER,SMALLINT,DECIMAL,NUMBERIC),以及近似數值數據類型(FLOAT,REAL,DOUBLE PRESISION),并在此基礎上進行擴展。

          擴展后增加了TINYINT,MEDIUMINT,BIGINT這3種長度不同的整形,并增加了BIT類型,用來存放位數據。


          整數類型        字節       范圍(有符號)      范圍(無符號)          用途 

          TINYINT        1字節        (-128,127)          (0,255)            極小整數值 

          SMALLINT       2字節     (-32 768,32 767)       (0,65 535)         小整數值 

          MEDIUMINT      3字節    (-8 388 608,8 388 607) (0,16 777 215)      中整數值 

          INT或INTEGER   4字節   (-2 147 483 648,2 147 483 647) (0,4 294 967 295) 大整數值 

          BIGINT         8字節   (-9 233 372 036 854 775 808,9 223 372 036 854 775 807) (0,18 446 744 073 709 551 615) 極大整數值 

          FLOAT          4字節   (-3.402 823 466 E+38,1.175 494 351 E-38),0,(1.175 494 351 E-38,3.402 823 466 351 E+38) 0,(1.175 494 351 E-38,3.402 823 466 E+38) 單精度浮點數值 

          DOUBLE         8字節 (1.797 693 134 862 315 7 E+308,2.225 073 858 507 201 4 E-308),0,(2.225 073 858 507 201 4 E-308,1.797 693 134 862 315 7 E+308) 0,(2.225 073 858 507 201 4 E-308,1.797 693 134 862 315 7 E+308) 雙精度浮點數值 

          DECIMAL 對DECIMAL(M,D) ,如果M>D,為M+2否則為D+2 依賴于M和D的值 依賴于M和D的值 小數值


          INT 類型:

          在 MySQL 中支持的 5 個主要整數類型是 TINYINT,SMALLINT,MEDIUMINT,INT 和 BIGINT。這些類型在很大程度上是相同的,只有它們存儲的值的大小是不相同的。

          MySQL 以一個可選的顯示寬度指示器的形式對 SQL 標準進行擴展,這樣當從數據庫檢索一個值時,可以把這個值加長到指定的長度。例如,指定一個字段的類型為 INT(6),

          就可以保證所包含數字少于 6 個的值從數據庫中檢索出來時能夠自動地用空格填充。需要注意的是,使用一個寬度指示器不會影響字段的大小和它可以存儲的值的范圍。

          萬一我們需要對一個字段存儲一個超出許可范圍的數字,MySQL 會根據允許范圍最接近它的一端截短后再進行存儲。還有一個比較特別的地方是,

          MySQL 會在不合規定的值插入表前自動修改為 0。


          UNSIGNED 修飾符規定字段只保存正值。因為不需要保存數字的正、負符號,可以在儲時節約一個“位”的空間。從而增大這個字段可以存儲的值的范圍。

          ZEROFILL 修飾符規定 0(不是空格)可以用來真補輸出的值。使用這個修飾符可以阻止 MySQL 數據庫存儲負值。


          FLOAT、DOUBLE 和 DECIMAL 類型

          MySQL 支持的三個浮點類型是 FLOAT、DOUBLE 和 DECIMAL 類型。FLOAT 數值類型用于表示單精度浮點數值,而 DOUBLE 數值類型用于表示雙精度浮點數值。

          與整數一樣,這些類型也帶有附加參數:一個顯示寬度指示器和一個小數點指示器。比如語句 FLOAT(7,3) 規定顯示的值不會超過 7 位數字,小數點后面帶有 3 位數字。


          對于小數點后面的位數超過允許范圍的值,MySQL 會自動將它四舍五入為最接近它的值,再插入它。

          DECIMAL 數據類型用于精度要求非常高的計算中,這種類型允許指定數值的精度和計數方法作為選擇參數。精度在這里指為這個值保存的有效數字的總個數,

          而計數方法表示小數點后數字的位數。比如語句 DECIMAL(7,3) 規定了存儲的值不會超過 7 位數字,并且小數點后不超過 3 位。


          忽略 DECIMAL 數據類型的精度和計數方法修飾符將會使 MySQL 數據庫把所有標識為這個數據類型的字段精度設置為 10,計算方法設置為 0。

          UNSIGNED 和 ZEROFILL 修飾符也可以被 FLOAT、DOUBLE 和 DECIMAL 數據類型使用。并且效果與 INT 數據類型相同。


          二.字符串類型

          MySQL 提供了8個基本的字符串類型,分別:CHAR、VARCHAR、BINARY、VARBINARY、BLOB、TEXT、ENUM 各SET等多種字符串類型。

          可以存儲的范圍從簡單的一個字符到巨大的文本塊或二進制字符串數據。


            字符串類型     字節大小         描述及存儲需求

              CHAR         0-255字節          定長字符串 

              VARCHAR      0-255字節          變長字符串 

              TINYBLOB     0-255字節        不超過 255 個字符的二進制字符串 

              TINYTEXT     0-255字節        短文本字符串 

              BLOB         0-65535字節      二進制形式的長文本數據 

              TEXT         0-65535字節      長文本數據 

              MEDIUMBLOB   0-16 777 215字節 二進制形式的中等長度文本數據 

              MEDIUMTEXT   0-16 777 215字節 中等長度文本數據 

              LOGNGBLOB    0-4 294 967 295字節 二進制形式的極大文本數據 

              LONGTEXT     0-4 294 967 295字節 極大文本數據

              VARBINARY(M)                   允許長度0-M個字節的定長字節符串,值的長度+1個字節

              BINARY(M)    M                 允許長度0-M個字節的定長字節符串


          CHAR 和 VARCHAR 類型

          CHAR 類型用于定長字符串,并且必須在圓括號內用一個大小修飾符來定義。這個大小修飾符的范圍從 0-255。比指定長度大的值將被截短,而比指定長度小的值將會用空格作填補。

          CHAR 類型可以使用 BINARY 修飾符。當用于比較運算時,這個修飾符使 CHAR 以二進制方式參于運算,而不是以傳統的區分大小寫的方式。

             CHAR 類型的一個變體是 VARCHAR 類型。它是一種可變長度的字符串類型,并且也必須帶有一個范圍在 0-255 之間的指示器。CHAR 和 VARCHGAR 不同之處在于 MYSQL 數據庫處理

          這個指示器的方式:CHAR 把這個大小視為值的大小,不長度不足的情況下就用空格補足。而 VARCHAR 類型把它視為最大值并且只使用存儲字符串實際需要的長度

          (增加一個額外字節來存儲字符串本身的長度)來存儲值。所以短于指示器長度的 VARCHAR 類型不會被空格填補,但長于指示器的值仍然會被截短。

          因為 VARCHAR 類型可以根據實際內容動態改變存儲值的長度,所以在不能確定字段需要多少字符時使用 VARCHAR 類型可以大大地節約磁盤空間、提高存儲效率。

          VARCHAR 類型在使用 BINARY 修飾符時與 CHAR 類型完全相同。


          TEXT 和 BLOB 類型

          對于字段長度要求超過 255 個的情況下,MySQL 提供了 TEXT 和 BLOB 兩種類型。根據存儲數據的大小,它們都有不同的子類型。這些大型的數據用于存儲文本塊或圖像、

          聲音文件等二進制數據類型。

          TEXT 和 BLOB 類型在分類和比較上存在區別。BLOB 類型區分大小寫,而 TEXT 不區分大小寫。大小修飾符不用于各種 BLOB 和 TEXT 子類型。

          比指定類型支持的最大范圍大的值將被自動截短。


          三.日期和時間類型

          在處理日期和時間類型的值時,MySQL 帶有 5 個不同的數據類型可供選擇。它們可以被分成簡單的日期、時間類型,和混合日期、時間類型。

          根據要求的精度,子類型在每個分類型中都可以使用,并且 MySQL 帶有內置功能可以把多樣化的輸入格式變為一個標準格式。


           類型     大小(字節)     范圍               格式          用途 

           DATE       4        1000-01-01/9999-12-31 YYYY-MM-DD    日期值 

           TIME       3        '-838:59:59'/'838:59:59' HH:MM:SS    時間值或持續時間 

           YEAR       1         1901/2155               YYYY       年份值 

           DATETIME   8       1000-01-01 00:00:00/9999-12-31 23:59:59 YYYY-MM-DD HH:MM:SS 混合日期和時間值 

           TIMESTAMP  4       1970-01-01 00:00:00/2037 年某時 YYYYMMDD HHMMSS 混合日期和時間值,時間戳


          DATE、TIME 和 TEAR 類型

          MySQL 用 DATE 和 YEAR 類型存儲簡單的日期值,使用 TIME 類型存儲時間值。這些類型可以描述為字符串或不帶分隔符的整數序列。如果描述為字符串,

          DATE 類型的值應該使用連字號作為分隔符分開,而 TIME 類型的值應該使用冒號作為分隔符分開。

          需要注意的是,沒有冒號分隔符的 TIME 類型值,將會被 MySQL 理解為持續的時間,而不是時間戳。


          MySQL 還對日期的年份中的兩個數字的值,或是 SQL 語句中為 TEAR 類型輸入的兩個數字進行最大限度的通譯。因為所有 TEAR 類型的值必須用 4 個數字存儲。

          MySQL 試圖將 2 個數字的年份轉換為 4 個數字的值。把在 00-69 范圍內的值轉換到 2000-2069 范圍內。把 70-99 范圍內的值轉換到 1970-1979 之內。

          如果 MySQL 自動轉換后的值并不符合我們的需要,請輸入 4 個數字表示的年份。

          DATETIME 和 TIMESTAMP 類型

          除了日期和時間數據類型,MySQL 還支持 DATETIME 和 TIMESTAMP 這兩種混合類型。它們可以把日期和時間作為單個的值進行存儲。

          這兩種類型通常用于自動存儲包含當前日期和時間的時間戳,并可在需要執行大量數據庫事務和需要建立一個調試和審查用途的審計跟蹤的應用程序中發揮良好作用。

          如果我們對 TIMESTAMP 類型的字段沒有明確賦值,或是被賦與了 null 值。MySQL 會自動使用系統當前的日期和時間來填充它。


          復合類型

          MySQL 還支持兩種復合數據類型 ENUM 和 SET,它們擴展了 SQL 規范。雖然這些類型在技術上是字符串類型,但是可以被視為不同的數據類型。

          一個 ENUM 類型只允許從一個集合中取得一個值;而 SET 類型允許從一個集合中取得任意多個值。


          ENUM 類型

          ENUM 類型因為只允許在集合中取得一個值,有點類似于單選項。在處理相互排拆的數據時容易讓人理解,比如人類的性別。ENUM 類型字段可以從集合中取得一個值或使用 null 值,

          除此之外的輸入將會使 MySQL 在這個字段中插入一個空字符串。另外如果插入值的大小寫與集合中值的大小寫不匹配,MySQL 會自動使用插入值的大小寫轉換成與集合中大小寫一致的值。

             ENUM 類型在系統內部可以存儲為數字,并且從 1 開始用數字做索引。一個 ENUM 類型最多可以包含 65536 個元素,其中一個元素被 MySQL 保留,用來存儲錯誤信息,

          這個錯誤值用索引 0 或者一個空字符串表示。

          MySQL 認為 ENUM 類型集合中出現的值是合法輸入,除此之外其它任何輸入都將失敗。這說明通過搜索包含空字符串或對應數字索引為 0 的行就可以很容易地找到錯誤記錄的位置。


          SET 類型

          SET 類型與 ENUM 類型相似但不相同。SET 類型可以從預定義的集合中取得任意數量的值。并且與 ENUM 類型相同的是任何試圖在 SET 類型字段中插入非預定義的值都會使 

          MySQL 插入一個空字符串。如果插入一個即有合法的元素又有非法的元素的記錄,MySQL 將會保留合法的元素,除去非法的元素。


          一個 SET 類型最多可以包含 64 項元素。在 SET 元素中值被存儲為一個分離的“位”序列,這些“位”表示與它相對應的元素?!拔弧笔莿摻ㄓ行蛟丶系囊环N簡單而有效的方式。

          并且它還去除了重復的元素,所以 SET 類型中不可能包含兩個相同的元素。

          希望從 SET 類型字段中找出非法的記錄只需查找包含空字符串或二進制值為 0 的行。


          通過對每種數據類型的用途,物理存儲,表示范圍等有一個概要的了解。這樣在面對具體應用時,就可以根據相應的特來來選擇合適的數據類型,使得我們能夠爭取在滿足應用的基礎上,

          用較小的存儲代價換來較高的數據庫性能。


          藍藍設計建立了UI設計分享群,每天會分享國內外的一些優秀設計,如果有興趣的話,可以進入一起成長學習,請掃碼藍小助,報下信息,藍小助會請您入群。歡迎您加入噢~~希望得到建議咨詢、商務合作,也請與我們聯系。

          截屏2021-05-13 上午11.41.03.png


          文章來源:csdn    

          分享此文一切功德,皆悉回向給文章原作者及眾讀者.
          免責聲明:藍藍設計尊重原作者,文章的版權歸原作者。如涉及版權問題,請及時與我們取得聯系,我們立即更正或刪除。

          藍藍設計www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務

          axios請求獲取到返回值

          前端達人

          axios請求獲取到返回值


          最近在學習Vue,碰到一個問題就是需要從后端獲取到某個返回值之后再運行后面的代碼。

          一般調用axios接口都是這樣的格式。

          this.$axios.post('api/xxxx/xxxxx', this.$qs.stringify({ username: 'qwerqw', password: '123456' })).then(res => { ... ... }).catch(error => { ... ... }) 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10

          這樣的格式要想獲取到返回值的話,就要將代碼都寫在then中,閱讀代碼的時候不是很清晰。于是網上各種搜,最后覺得這種方法能解決我的強迫癥。

          login: async function() { // result的值就是res.data let result = await new Promise((resolve,reject) => { this.$axios.post('api/xxxx/xxxxx', this.$qs.stringify({ username: 'qwerqw', password: '123456' })).then(res => { resolve(res.data) }).catch(error => { console.log(error) }) }) ... ... } 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16

          按照這種方式去獲取到后端的返回值,就可以將剩下的邏輯放在axios請求外面了。

          我的理解是,axios是一種異步請求方法,需要用await關鍵詞修飾,等到獲取到返回值后再執行后面的代碼。在使用await時,需要再function前添加async關鍵詞。



          藍藍設計建立了UI設計分享群,每天會分享國內外的一些優秀設計,如果有興趣的話,可以進入一起成長學習,請掃碼藍小助,報下信息,藍小助會請您入群。歡迎您加入噢~~希望得到建議咨詢、商務合作,也請與我們聯系。

          截屏2021-05-13 上午11.41.03.png


          文章來源:csdn     作者:灰羊駝

          分享此文一切功德,皆悉回向給文章原作者及眾讀者.
          免責聲明:藍藍設計尊重原作者,文章的版權歸原作者。如涉及版權問題,請及時與我們取得聯系,我們立即更正或刪除。

          藍藍設計www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務

          使用vue寫一個計時器

          前端達人

          **

          首先我們要知道setTimeout和setInterval的區別

          **
          setTimeout只在指定時間后執行一次,代碼如下:

          <script>  
          //定時器 異步運行  
          function hello(){  
          alert("hello");  
          }  
          //使用方法名字執行方法  
          var t1 = window.setTimeout(hello,1000);  
          var t2 = window.setTimeout("hello()",3000);//使用字符串執行方法  
          window.clearTimeout(t1);//去掉定時器  
          </script> 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10

          setInterval以指定時間為周期循環執行,代碼如下:

          //實時刷新時間單位為毫秒  
          setInterval('refreshQuery()',8000);   
          /* 刷新查詢 */  
          function refreshQuery(){  
             $("#mainTable").datagrid('reload',null);  
          } 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6

          一般情況下setTimeout用于延遲執行某方法或功能,
          setInterval則一般用于刷新表單,對于一些表單的實時指定時間刷新同步
          **

          計時器

          **
          HTML代碼

          <div class="father">
                  <ul>
                      <li>{{one}}<span>:</span></li>
                      <li>{{two}}<span>:</span></li>
                      <li>{{three}}</li>
                  </ul>
                  <el-button type="primary" @click="startHandler">開始</el-button>
                  <el-button type="primary" @click="endHandler">暫停</el-button>
              </div> 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9

          JAVASCRIPT代碼

          <script>
          export default {
            name: 'HelloWorld',
            data(){
                return {
                  flag: null,
                  one : '00', // 時
                  two : '00', // 分
                  three : '00', // 秒
                  abc : 0, // 秒的計數
                  cde : 0, // 分的計數
                  efg : 0, // 時的計數
                }
            },
            props: {
              msg: String
            },
            mounted() {
          
            },
            methods:{
            // 開始計時
              startHandler(){
                  this.flag = setInterval(()=>{
                      if(this.three === 60 || this.three === '60'){
                          this.three = '00';
                          this.abc = 0;
                          if(this.two === 60 || this.two === '60'){
                              this.two = '00';
                              this.cde = 0;
                              if(this.efg+1 <= 9){
                                  this.efg++;
                                  this.one = '0' + this.efg;
                              }else{
                                  this.efg++;
                                  this.one = this.efg;
                              }
                          }else{
                              if(this.cde+1 <= 9){
                                  this.cde++;
                                  this.two = '0' + this.cde;
                              }else{
                                  this.cde++;
                                  this.two = this.cde;
                              }
                          }
                      }else{
                          if(this.abc+1 <= 9){
                              this.abc++;
                              this.three = '0' + this.abc;
                          }else{
                              this.abc++;
                              this.three=this.abc;
                          }
                      }
          
                  },100)
              },
              // 暫停計時
              endHandler(){
                  this.flag = clearInterval(this.flag)
              }
            }
          }
          </script> 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20
          • 21
          • 22
          • 23
          • 24
          • 25
          • 26
          • 27
          • 28
          • 29
          • 30
          • 31
          • 32
          • 33
          • 34
          • 35
          • 36
          • 37
          • 38
          • 39
          • 40
          • 41
          • 42
          • 43
          • 44
          • 45
          • 46
          • 47
          • 48
          • 49
          • 50
          • 51
          • 52
          • 53
          • 54
          • 55
          • 56
          • 57
          • 58
          • 59
          • 60
          • 61
          • 62
          • 63
          • 64
          • 65

          效果如下:
          在這里插入圖片描述




          藍藍設計建立了UI設計分享群,每天會分享國內外的一些優秀設計,如果有興趣的話,可以進入一起成長學習,請掃碼藍小助,報下信息,藍小助會請您入群。歡迎您加入噢~~希望得到建議咨詢、商務合作,也請與我們聯系。

          截屏2021-05-13 上午11.41.03.png


          文章來源:csdn     作者:rock_23

          分享此文一切功德,皆悉回向給文章原作者及眾讀者.
          免責聲明:藍藍設計尊重原作者,文章的版權歸原作者。如涉及版權問題,請及時與我們取得聯系,我們立即更正或刪除。

          藍藍設計www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務

          VueJs里利用CryptoJs實現Md5加密和3Des加密及解密

          前端達人

          前言

          前我們介紹的用于vue用于數據簽名的操作,《【干貨】Vue TypeScript根據類生成簽名字符串》,其目的就是用于生成這個再轉MD5加密的模式進行校驗,原來我們在C#和Android里面已經實現這些方式,因為前端準備用Vue來做,所以加密這塊少不了也需要實現的。

          安裝Crypto

          Crypto里面可以把md5和3des都一起做了,所以我們直接安裝這個比較方便

          找到我們的程序目錄,按住Shift加鼠標右鍵,選擇在此處打開Powershell窗口

          然后在cmd窗口里面輸入npm install crypto-js -save-dev 

          安裝完成后可以看到紅框下面標注著成功了。


          代碼演示


          MD5加密

          我們還是用上次簽名的那個項目里面,首先要先引用Crypto-js


          getmd5,我們再寫一個GetMd5的方法,傳入的字符串直接生成MD5的字符返回,


          接下來再定義一個雙向綁定的字符串,在點擊簽名的時候同時生成md5的字符串顯示的頁面上

          運行后的效果




          3DES加密、解密

          核心代碼

          加密

             Encrypt3Des(str: string, aStrKey: string, ivstr: string): string {
                  const KeyHex = CryptoJS.enc.Utf8.parse(aStrKey);
                  const encrypted = CryptoJS.TripleDES.encrypt(str,
                      KeyHex,
                      {
                          mode: CryptoJS.mode.CBC,
                          padding: CryptoJS.pad.Pkcs7,
                          iv: CryptoJS.enc.Utf8.parse(ivstr)
                      });
                  let hexstr = encrypted.ciphertext.toString().toUpperCase();
                  console.log(hexstr);
                  return hexstr;
              }

          一般網上的加解密最后紅框這里我們直接是輸出 return encrypted.tostring(),但是因為我們自己的C#和Android的3Des的加解密都是最后輸出的16進制的字符串,所以我們改為紅框這里輸出的樣式。



          解密

              Decrypt3Des(str: string, aStrKey: string, ivstr: string): string {
                  const KeyHex = CryptoJS.enc.Utf8.parse(aStrKey);
                  //因為我們加密的時候用到的16進制字符串,需要進行轉換
                  //第一步把16進制字符串轉為WordArray格式
                  const WordArray = CryptoJS.enc.Hex.parse(str);
                  //第二步把WordArray再轉為base64的字符串
                  const base64str = CryptoJS.enc.Base64.stringify(WordArray);
                  //第三步再進行解密
                  const decrypted = CryptoJS.TripleDES.decrypt(base64str,
                      KeyHex,
                      {
                          mode: CryptoJS.mode.CBC,
                          padding: CryptoJS.pad.Pkcs7,
                          iv: CryptoJS.enc.Utf8.parse(ivstr)
                      });

                  return decrypted.toString(CryptoJS.enc.Utf8);
              }

          這里比較重要就是紅框里面,因為我們的加密最后輸出的是16進制的字符串,所以我們解密的時候首先要把16進制字符串轉為WordArray格式,再轉換為BASE64的字符串,最后再進行解密。因為我也是個前端小白,就是這個問題我也是研究了一下午才搞明白。

          最后下面的黃框要注意輸出的字符要轉為Utf8。




          其余設置

          我們在test.ts里面定義了兩個字符串,一個des3encryptstr的加密后的字符串,一個des3decryptstr是解密后的字符串,然后又加上了兩個方法,一個是加密的方法btnencrypt,一個是解密的方法btndecrypt,分別調用的就是我們剛才寫的兩段核心代碼。


          然后在test.vue.html里面加上雙向綁定顯示以及一個加密按鈕和一個解密按鈕。


          頁面效果

          未加密的效果

          點擊加密后的效果

          點擊解密后的效果


          藍藍設計建立了UI設計分享群,每天會分享國內外的一些優秀設計,如果有興趣的話,可以進入一起成長學習,請掃碼藍小助,報下信息,藍小助會請您入群。歡迎您加入噢~~希望得到建議咨詢、商務合作,也請與我們聯系。

          截屏2021-05-13 上午11.41.03.png


          文章來源:https://my.oschina.net/u/4582134/blog/4582375

          分享此文一切功德,皆悉回向給文章原作者及眾讀者.
          免責聲明:藍藍設計尊重原作者,文章的版權歸原作者。如涉及版權問題,請及時與我們取得聯系,我們立即更正或刪除。

          藍藍設計www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務

          手把手教你利用js給圖片打馬賽克

          前端達人

          效果演示

          在這里插入圖片描述

          Canvas簡介

          這個 HTML 元素是為了客戶端矢量圖形而設計的。它自己沒有行為,但卻把一個繪圖 API 展現給客戶端 JavaScript 以使腳本能夠把想繪制的東西都繪制到一塊畫布上。

          HTML5 標簽用于繪制圖像(通過腳本,通常是 JavaScript)

          不過, 元素本身并沒有繪制能力(它僅僅是圖形的容器) - 您必須使用腳本來完成實際的繪圖任務

          getContext() 方法可返回一個對象,該對象提供了用于在畫布上繪圖的方法和屬性

          本手冊提供完整的 getContext(“2d”) 對象屬性和方法,可用于在畫布上繪制文本、線條、矩形、圓形等等

          標記和 SVG 以及 VML 之間的差異:

          標記和 SVG 以及 VML 之間的一個重要的不同是, 有一個基于 JavaScript 的繪圖 API,而 SVG 和 VML 使用一個 XML 文檔來描述繪圖。

          這兩種方式在功能上是等同的,任何一種都可以用另一種來模擬。從表面上看,它們很不相同,可是,每一種都有強項和弱點。例如,SVG 繪圖很容易編輯,只要從其描述中移除元素就行。

          要從同一圖形的一個 標記中移除元素,往往需要擦掉繪圖重新繪制它。
          在這里插入圖片描述

          知識點簡介

          • 利用js創建圖片
          let img = new Image() //可以給圖片一個鏈接 img.src = 'https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=826495019,1749283937&fm=26&gp=0.jpg' //或者本地已有圖片的路徑 //img.src = './download.jpg' //添加到HTML中 document.body.appendChild(img)  
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8

          • canvas.getContext(“2d”)

          語法:
          參數 contextID 指定了您想要在畫布上繪制的類型。當前唯一的合法值是 “2d”,它指定了二維繪圖,并且導致這個方法返回一個環境對象,該對象導出一個二維繪圖 API

          let ctx = Canvas.getContext(contextID)  
          
          • 1

          • ctx.drawImage()

          JavaScript 語法 1:
          在畫布上定位圖像:

          context.drawImage(img,x,y);  
          
          • 1

          JavaScript 語法 2:
          在畫布上定位圖像,并規定圖像的寬度和高度:

          context.drawImage(img,x,y,width,height);  
          
          • 1

          JavaScript 語法 3:
          剪切圖像,并在畫布上定位被剪切的部分:

          context.drawImage(img,sx,sy,swidth,sheight,x,y,width,height);  
          
          • 1

          • ctx.getImageData()

          JavaScript 語法
          getImageData() 方法返回 ImageData 對象,該對象拷貝了畫布指定矩形的像素數據。
          對于 ImageData 對象中的每個像素,都存在著四方面的信息,即 RGBA 值:
          R - 紅色 (0-255)
          G - 綠色 (0-255)
          B - 藍色 (0-255)
          A - alpha 通道 (0-255; 0 是透明的,255 是完全可見的)
          color/alpha 以數組形式存在,并存儲于 ImageData 對象的 data 屬性中

          var imgData=context.getImageData(x,y,width,height);  
          
          • 1

          • ctx.putImageData()

          putImageData() 方法將圖像數據(從指定的 ImageData 對象)放回畫布上。

          接下來跟著我一步一步做完這個小功能叭~
          在這里插入圖片描述

          step-by-step

          準備好我們的圖片,并添加上我們的方法

          <body> <img src="./download.jpg"> <button onclick="addCanvas()">生成Canvas</button> <button onclick="generateImg()">生成圖片</button> </body>  
          
          • 1
          • 2
          • 3
          • 4
          • 5

          在這里插入圖片描述
          接下來寫addCanvas方法

          function addCanvas() { let bt = document.querySelector('button') let img = new Image(); //1.準備賦值復制一份圖片 img.src = './download.jpg'; img.onload = function() { //2.待圖片加載完成 let width = this.width let height = this.height let canvas = document.createElement('canvas') //3.創建畫布 let ctx = canvas.getContext("2d"); //4.獲得該畫布的內容 canvas.setAttribute('width', width) //5.為了統一,設置畫布的寬高為圖片的寬高 canvas.setAttribute('height', height) ctx.drawImage(this, 0, 0, width, height); //5.在畫布上繪制該圖片 document.body.insertBefore(canvas, bt) //5.把canvas插入到按鈕前面 } }  
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20
          • 21

          成功在畫布上得到圖片:
          在這里插入圖片描述

          嗯,我們已經成功走出了成功的一小步,接下來是干什么呢?…嗯,我們需要利用原生的onmouseuponmousedown事件,代表我們按下鼠標這個過程,那么這兩個事件添加到哪呢?

          沒錯,既然我們要在canvas上進行馬賽克操作,那我們必然要給canvas元素添加這兩個事件

          考慮到我們創建canvas的過程復雜了一點,我們做一個模塊封裝吧!

          function addCanvas() { let bt = document.querySelector('button') let img = new Image(); img.src = './download.jpg'; //這里放自己的圖片 img.onload = function() { let width = this.width let height = this.height let { canvas, ctx } = createCanvasAndCtx(width, height) //對象解構接收canvas和ctx ctx.drawImage(this, 0, 0, width, height); document.body.insertBefore(canvas, bt) } } function createCanvasAndCtx(width, height) { let canvas = document.createElement('canvas') canvas.setAttribute('width', width) canvas.setAttribute('height', height) canvas.setAttribute('onmouseout', 'end()') //修補鼠標不在canvas上離開的補丁 canvas.setAttribute('onmousedown', 'start()') //添加鼠標按下 canvas.setAttribute('onmouseup', 'end()') //添加鼠標彈起 let ctx = canvas.getContext("2d"); return { canvas, ctx } } function start() { let canvas = document.querySelector('canvas') canvas.onmousemove = () => { console.log('你按下了并移動了鼠標') } } function end() { let canvas = document.querySelector('canvas') canvas.onmousemove = null }  
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20
          • 21
          • 22
          • 23
          • 24
          • 25
          • 26
          • 27
          • 28
          • 29
          • 30
          • 31
          • 32
          • 33
          • 34
          • 35
          • 36
          • 37
          • 38
          • 39
          • 40
          • 41
          • 42
          • 43
          • 44
          • 45
          • 46

          測試一下我們的start()end()是否生效了
          在這里插入圖片描述
          嗯,目前來看,我們的代碼依然如我們所愿的正常工作

          接下來的挑戰更加嚴峻,我們需要去獲取像素和處理像素,讓我們再重寫start()函數

           function start() { let img = document.querySelector('img') let canvas = document.querySelector('canvas') let ctx = canvas.getContext("2d"); imgData = ctx.getImageData(0, 0, img.clientWidth, img.clientHeight); canvas.onmousemove = (e) => { let w = imgData.width; //1.獲取圖片寬高 let h = imgData.height; //馬賽克的程度,數字越大越模糊 let num = 10; //獲取鼠標當前所在的像素RGBA let color = getXY(imgData, e.offsetX, e.offsetY); for (let k = 0; k < num; k++) { for (let l = 0; l < num; l++) { //設置imgData上坐標為(e.offsetX + l, e.offsetY + k)的的顏色 setXY(imgData, e.offsetX + l, e.offsetY + k, color); } } //更新canvas數據 ctx.putImageData(imgData, 0, 0); } } //這里為你提供了setXY和getXY兩個函數,如果你有興趣,可以去研究獲取的原理 function setXY(obj, x, y, color) { var w = obj.width; var h = obj.height; var d = obj.data; obj.data[4 * (y * w + x)] = color[0]; obj.data[4 * (y * w + x) + 1] = color[1]; obj.data[4 * (y * w + x) + 2] = color[2]; obj.data[4 * (y * w + x) + 3] = color[3]; } function getXY(obj, x, y) { var w = obj.width; var h = obj.height; var d = obj.data; var color = []; color[0] = obj.data[4 * (y * w + x)]; color[1] = obj.data[4 * (y * w + x) + 1]; color[2] = obj.data[4 * (y * w + x) + 2]; color[3] = obj.data[4 * (y * w + x) + 3]; return color; }  
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20
          • 21
          • 22
          • 23
          • 24
          • 25
          • 26
          • 27
          • 28
          • 29
          • 30
          • 31
          • 32
          • 33
          • 34
          • 35
          • 36
          • 37
          • 38
          • 39
          • 40
          • 41
          • 42
          • 43
          • 44
          • 45
          • 46
          • 47
          • 48
          • 49

          嗯,我們離成功不遠拉,最后一步就是生成圖片

          好在canavs給我們提供了直接的方法,可以直接將畫布導出為Base64編碼的圖片:

          function generateImg() { let canvas = document.querySelector('canvas') var newImg = new Image(); newImg.src = canvas.toDataURL("image/png"); document.body.insertBefore(newImg, canvas) }  
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6

          最終效果:
          在這里插入圖片描述

          是不是無比輕松呢~,來看看你手寫的代碼是否和下面一樣叭:

          完整代碼

          <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <body> <img src="./download.jpg"> <button onclick="addCanvas()">生成Canvas</button> <button onclick="generateImg()">生成圖片</button> </body> <script> function addCanvas() { let bt = document.querySelector('button') let img = new Image(); img.src = './download.jpg'; //這里放自己的圖片 img.onload = function() { let width = this.width let height = this.height let { canvas, ctx } = createCanvasAndCtx(width, height) ctx.drawImage(this, 0, 0, width, height); document.body.insertBefore(canvas, bt) } } function createCanvasAndCtx(width, height) { let canvas = document.createElement('canvas') canvas.setAttribute('width', width) canvas.setAttribute('height', height) canvas.setAttribute('onmouseout', 'end()') canvas.setAttribute('onmousedown', 'start()') canvas.setAttribute('onmouseup', 'end()') let ctx = canvas.getContext("2d"); return { canvas, ctx } } function start() { let img = document.querySelector('img') let canvas = document.querySelector('canvas') let ctx = canvas.getContext("2d"); imgData = ctx.getImageData(0, 0, img.clientWidth, img.clientHeight); canvas.onmousemove = (e) => { let w = imgData.width; //1.獲取圖片寬高 let h = imgData.height; //馬賽克的程度,數字越大越模糊 let num = 10; //獲取鼠標當前所在的像素RGBA let color = getXY(imgData, e.offsetX, e.offsetY); for (let k = 0; k < num; k++) { for (let l = 0; l < num; l++) { //設置imgData上坐標為(e.offsetX + l, e.offsetY + k)的的顏色 setXY(imgData, e.offsetX + l, e.offsetY + k, color); } } //更新canvas數據 ctx.putImageData(imgData, 0, 0); } } function generateImg() { let canvas = document.querySelector('canvas') var newImg = new Image(); newImg.src = canvas.toDataURL("image/png"); document.body.insertBefore(newImg, canvas) } function setXY(obj, x, y, color) { var w = obj.width; var h = obj.height; var d = obj.data; obj.data[4 * (y * w + x)] = color[0]; obj.data[4 * (y * w + x) + 1] = color[1]; obj.data[4 * (y * w + x) + 2] = color[2]; obj.data[4 * (y * w + x) + 3] = color[3]; } function getXY(obj, x, y) { var w = obj.width; var h = obj.height; var d = obj.data; var color = []; color[0] = obj.data[4 * (y * w + x)]; color[1] = obj.data[4 * (y * w + x) + 1]; color[2] = obj.data[4 * (y * w + x) + 2]; color[3] = obj.data[4 * (y * w + x) + 3]; return color; } function end() { let canvas = document.querySelector('canvas') canvas.onmousemove = null } </script> </body> </html>  
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20
          • 21
          • 22
          • 23
          • 24
          • 25
          • 26
          • 27
          • 28
          • 29
          • 30
          • 31
          • 32
          • 33
          • 34
          • 35
          • 36
          • 37
          • 38
          • 39
          • 40
          • 41
          • 42
          • 43
          • 44
          • 45
          • 46
          • 47
          • 48
          • 49
          • 50
          • 51
          • 52
          • 53
          • 54
          • 55
          • 56
          • 57
          • 58
          • 59
          • 60
          • 61
          • 62
          • 63
          • 64
          • 65
          • 66
          • 67
          • 68
          • 69
          • 70
          • 71
          • 72
          • 73
          • 74
          • 75
          • 76
          • 77
          • 78
          • 79
          • 80
          • 81
          • 82
          • 83
          • 84
          • 85
          • 86
          • 87
          • 88
          • 89
          • 90
          • 91
          • 92
          • 93
          • 94
          • 95
          • 96
          • 97
          • 98
          • 99
          • 100
          • 101
          • 102
          • 103
          • 104
          • 105
          • 106
          • 107
          • 108
          • 109
          • 110
          • 111
          • 112
          • 113
          • 114
          • 115
          • 116

          當然,你可以做更多創作,比如上面打的馬賽克是正方形的,你可以利用你的數學知識讓其變為圓形,以圓心為鼠標中心擴散

          你也可以選擇完善一些過程,例如馬賽克位置打錯了,可以選擇將畫布清空然后重新開始~
          或者做一些善后處理,導出圖片后隱藏canvas畫布
          點個贊吧

          藍藍設計建立了UI設計分享群,每天會分享國內外的一些優秀設計,如果有興趣的話,可以進入一起成長學習,請掃碼藍小助,報下信息,藍小助會請您入群。歡迎您加入噢~~希望得到建議咨詢、商務合作,也請與我們聯系。

          截屏2021-05-13 上午11.41.03.png


          文章來源:csdn   作者: VGtime

          分享此文一切功德,皆悉回向給文章原作者及眾讀者.
          免責聲明:藍藍設計尊重原作者,文章的版權歸原作者。如涉及版權問題,請及時與我們取得聯系,我們立即更正或刪除。

          藍藍設計www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務


          Slick.js使用方法——幻燈片

          前端達人

            
          和Swiper.js一樣

          簡介

          slick 是一個基于 jQuery 的響應觸摸式幻燈片插件,支持IE8+,Chrome, Firefox, and Safari,具有以下特點:

          • 支持響應式
          • 瀏覽器支持 CSS3 時,則使用 CSS3 過度/動畫
          • 支持移動設備滑動
          • 支持桌面瀏覽器鼠標拖動
          • 支持循環
          • 支持左右控制
          • 支持動態添加、刪除、過濾
          • 支持自動播放、圓點、箭頭、回調等等

          兼容

          瀏覽器兼容:兼容 IE7+ 及其他主流瀏覽器,若要兼容 IE7,需修改 CSS(slick.css)。

          jQuery兼容:兼容 1.7 及以上版本。

          使用方法

          1、引入文件

            
              
          <link rel="stylesheet" href="style/slick.css">
          <script src="script/jquery.min.js"></script>
          <script src="script/slick.min.js"></script>

          注意:需jQuery 1.7

          2、HTML

            
              
          <div class="slick">
              <div><a ><img src="images/1.jpg" alt=""></a></div>
              <div><a ><img src="images/2.jpg" alt=""></a></div>
              <div><a ><img src="images/4.jpg" alt=""></a></div>
              <div><a ><img src="images/3.jpg" alt=""></a></div>
              <div><a ><img src="images/5.jpg" alt=""></a></div>
          </div>

          3、JavaScript

            
              
          $(function(){
              $('.slick').slick({
                  dots: true
          });
          });

          參數

          參數 類型 默認值 說明
          accessibility 布爾值 true 啟用Tab鍵和箭頭鍵導航
          autoplay 布爾值 false 自動播放
          autoplaySpeed 整數 3000 自動播放間隔
          centerMode 布爾值 false 中心模式
          centerPadding 字符串 ’50px’ 中心模式左右內邊距
          cssEase 字符串 ‘ease’ CSS3 動畫
          customPaging function n/a 自定義分頁
          dots 布爾值 false 指示點
          draggable 布爾值 true 啟用桌面拖動
          easing 字符串 ‘linear’ animate() fallback easing
          fade 布爾值 false 淡入淡出
          arrows 布爾值 true 左右箭頭
          infinite 布爾值 true 循環播放
          lazyLoad 字符串 ‘ondemand’ 延遲加載,可選 ondemand 和 progressive
          onBeforeChange(this, index) method null 開始切換前的回調函數
          onAfterChange(this, index) method null 切換后的回調函數
          onInit(this) method null 第一次初始化后的回調函數
          onReInit(this) method null 再次初始化后的回調函數
          pauseOnHover 布爾值 true 鼠標懸停暫停自動播放
          responsive object null 斷點觸發設置
          slide 字符串 ‘div’ 滑動元素查詢
          slidesToShow 整數 1 幻燈片每屏顯示個數
          slidesToScroll 整數 1 幻燈片每次滑動個數
          speed 整數 300 滑動時間
          swipe 布爾值 true 移動設備滑動事件
          touchMove 布爾值 true 觸摸滑動
          touchThreshold 整數 5 滑動切換閾值,即滑動多少像素后切換
          useCSS 布爾值 true 使用 CSS3 過度
          vertical 布爾值 false 垂直方向

          方法

          方法 Argument 說明
          slick() options : object 初始化 slick
          unslick()   銷毀 slick
          slickNext()   切換下一張
          slickPrev()   切換上一張
          slickPause()   暫停自動播放
          slickPlay()   開始自動播放
          slickGoTo() index : int 切換到第 x 張
          slickCurrentSlide()   返回當前幻燈片索引
          slickAdd() element : html or DOM object, index: int, addBefore: bool Add a slide. If an index is provided, will add at that index, or before if addBefore is set. If no index is provided, add to the end or to the beginning if addBefore is set. Accepts HTML String
          slideRemove() index: int, removeBefore: bool Remove slide by index. If removeBefore is set true, remove slide preceding index, or the first slide if no index is specified. If removeBefore is set to false, remove the slide following index, or the last slide if no index is set.
          slickFilter() filter : selector or function Filters slides using jQuery .filter syntax
          slickUnfilter()   Removes applied filter
          slickSetOption(option,value,refresh) option : string(option name), value : depends on option, refresh : 布爾值 Sets an option live. Set refresh to true if it is an option that changes the display

          演 示 下 載



          GitHub:https://github.com/kenwheeler/slick


          藍藍設計建立了UI設計分享群,每天會分享國內外的一些優秀設計,如果有興趣的話,可以進入一起成長學習,請掃碼藍小助,報下信息,藍小助會請您入群。歡迎您加入噢~~希望得到建議咨詢、商務合作,也請與我們聯系。

          截屏2021-05-13 上午11.41.03.png


          文章來源:csdn   作者:cc蒲公英

          分享此文一切功德,皆悉回向給文章原作者及眾讀者.
          免責聲明:藍藍設計尊重原作者,文章的版權歸原作者。如涉及版權問題,請及時與我們取得聯系,我們立即更正或刪除。

          藍藍設計www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務

          vue電商后臺管理系統保姆級教程(八)——角色列表結構功能

          前端達人

          8、角色列表

          8.1 通過路由展示角色列表組件

          在power中新建一個roles.vue(角色列表)初始化基本結構:
          在這里插入圖片描述

          在路由中加載導入:
          在這里插入圖片描述
          在這里插入圖片描述

          8.2 繪制基本布局結構并獲取列表數據

          效果圖:
          在這里插入圖片描述
          面包屑導航:
          在這里插入圖片描述
          卡片視圖:
          在這里插入圖片描述
          API:
          在這里插入圖片描述
          渲染數據:
          定義數據date:
          在這里插入圖片描述
          生命周期函數:
          在這里插入圖片描述

          8.3 渲染角色列表數據

          先渲染索引列:
          在這里插入圖片描述
          優化樣式:
          在這里插入圖片描述

          在索列之前加和 展開列:
          在這里插入圖片描述

          8.4 說明角色列表需要完成的功能模塊

          現在還沒有具體的樣式,后面會寫
          角色信息的添加,刪除功能前面做了,所以這里就不寫了

          點擊對應按鈕出現對應的彈出層,然后執行對應的操作。

          8.5 分析角色下權限渲染的思路

          在展開行中拿到渲染的數據
          在請求數據列表中返回了數據children,通過作用域插槽來拿
          在這里插入圖片描述
          實現效果:
          在這里插入圖片描述
          拿到數據之后通過三層for循環渲染出對應的ui結構

          8.6 通過第一層for循環渲染一級權限

          先做一下柵格布局,區分出三個區域用來放三層for循環:

          scope.row是當前對象的數據。 .children 是一級權限的數據, :key每次循環綁定一個唯一的key值,通過插值表達式渲染出數據
          在這里插入圖片描述
          放在el-tag標簽中美化樣式
          在這里插入圖片描述

          8.7 美化一級權限

          思路:
          每行之間隔開距離,給每行放一個buttom的邊框,第一行放一個top邊框(這里使用三元表達判斷) 加圖標
          在這里插入圖片描述
          每行都放buttom,利用三元表達式,如果i1===0.則bdtop否則空
          在這里插入圖片描述

          8.8 通過二層for循環渲染二級權限

          使用柵格布局分出2級權限和3級權限,,方法和之前的一樣。
          在這里插入圖片描述
          添加邊框 線(上邊框)第一個不添加,利用三元表達式判斷:
          在這里插入圖片描述
          動態綁定class類,然后判斷
          在這里插入圖片描述
          最終效果:
          在這里插入圖片描述

          8.9 通過第三層for循環渲染三級權限

          柵格布局:
          注使用item2的children
          在這里插入圖片描述
          通過作用域插槽拿到數據 children 拿到子組件數據,通過柵格分隔樣式,動態綁定邊框值。

          8.10 美化角色權限下的UI結構

          設置最小寬度:
          設置body的最小寬度為1366px
          在這里插入圖片描述

          角色列表設置居中:
          定義一個類:哪里用到往哪里加
          在這里插入圖片描述
          最后把代碼插槽刪了

          8.11 點擊刪除權限按鈕彈出確認提示框

          使用element組件中的可移除標簽屬性:
          在這里插入圖片描述
          closable屬性:
          在這里插入圖片描述
          綁定點擊事件:
          removeRightById:
          在這里插入圖片描述
          定義事件:
          在這里插入圖片描述
          然后彈框提示用戶是否要刪除,使用的還是element組件L

          在這里插入圖片描述
          catch捕獲錯誤:在這里插入圖片描述
          結果判斷用戶操作:
          在這里插入圖片描述
          這里只是打印了結果,沒有向后端發起請求。

          8.12 完成刪除角色下指定權限的功能

          上一節點擊了刪除按鈕后需要向后端發起刪除的請求,刪除用戶在數據庫中的權限:
          API:
          在這里插入圖片描述
          發起delect請求:
          先把item3.id傳進去:
          在這里插入圖片描述
          在處理函數的形參中j接收一下:
          在這里插入圖片描述
          然后再發起delect請求的時候用之前的參數字符串拼接
          然后進行判斷:
          在這里插入圖片描述
          有個缺點:刪除之后展開欄就被關閉了 解決辦法:
          在這里插入圖片描述
          把close權限賦值給一級標簽二級標簽
          在這里插入圖片描述



          藍藍設計建立了UI設計分享群,每天會分享國內外的一些優秀設計,如果有興趣的話,可以進入一起成長學習,請掃碼藍小助,報下信息,藍小助會請您入群。歡迎您加入噢~~希望得到建議咨詢、商務合作,也請與我們聯系。

          截屏2021-05-13 上午11.41.03.png


          文章來源:csdn   作者:十九萬里

          分享此文一切功德,皆悉回向給文章原作者及眾讀者.
          免責聲明:藍藍設計尊重原作者,文章的版權歸原作者。如涉及版權問題,請及時與我們取得聯系,我們立即更正或刪除。

          藍藍設計www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務

          Jquery選擇器中使用變量實現動態選擇例子

          前端達人

          這篇文章主要介紹了Jquery選擇器中使用變量實現動態選擇例子,這樣做的好處我們可以動態選擇一些元素,核心思想其實就是用字符串組合,需要的朋友可以參考下


          例子一:

          例子二:


          <table>
            <tr>
              <th>用戶名</th>
              <th>狀態</th>
            <tr>
            <tr>
              <td>張三</td>
              <td data-uid="10000">正常</td>
            <tr>
            <tr>
              <td>李四</td>
              <td data-uid="10001">凍結</td>
            <tr>
            <tr>
              <td>王二麻子</td>
              <td data-uid=10002>凍結</td>
            <tr>
          </table>
           
          <script type="text/javascript">
          $(document).ready(function(){
            var uid = 1001;
            $("td[data-uid = "+ uid +"]").html('正常');
          }
          </script>





          <script type="text/javascript">
           $(function(){
            alert(123);
            var v=4;
            var test=$("input[type='radio'][value='"+v+"']");//直接拼接字符串就可以了
            console.info(test);
            var testValue=test.attr({"checked":true});
            console.info(testValue);
           });
           </script>
            
           <body>
            This is my JSP page. <br>
            <table>
           <tr>
           <td>性別:</td>
           <td>
            <input name="sex" type="radio" value="0"/>男 0
            <input name="sex" type="radio" value="1"/>女 1
            <input name="sex" type="radio" value="2"/>女 2
            <input name="sex" type="radio" value="3"/>女 3
            <input name="sex" type="radio" value="4"/>女 4
           </td>
           </tr>
            </table>
           </body>




          例子三、jQuery中選擇器參數使用變量應該注意的問題

          這是原來的代碼


          var li_index = $(this).index();
           
          var $content_index = li_index + 2;
           
          var $content_progress = $(“div.content:eq(” + $content_index + “)”);
           
          var $newavalue = $(this).find(“a”).attr(“name”);
           
          var $resource = $(this).find(“a”).html().replace(“首頁”,$newavalue);
           
          var $afterresource = $resource.replace($newavalue,””);
           
          var $afterresource = $newavalue + $afterresource.replace(“首頁”,$newavalue);


          實現的是關鍵詞替換,不過到第三行時候不執行了,調試啊,替換啊,都不行。 從早上到剛才一直在各種群里面發問,終于 …… 俺們大本營 的Lomu大神一陣見血:

          你的寫法不對

          要連接符

          $(“div.content:nth-child($content_index)”);

          $(“div.content:nth-child(” + $content_index + “)”);


          關鍵是外面有引號

          有引號被當字符串處理了

          說真的現在感覺,有些基礎的東西出錯,光靠自己調試根本找不出問題所在。比如剛才那個 + 號,我看書就沒見過。出現這種錯誤百度也不知道什么關鍵詞。真不知道  選擇器 里面用變量 還要用到+號,那個《鋒利的jQuery 》也沒有明確的說 選擇器 里面用變量 還要用到+號,包括我們的w3cschool。





            藍藍設計建立了UI設計分享群,每天會分享國內外的一些優秀設計,如果有興趣的話,可以進入一起成長學習,請掃碼藍小助,報下信息,藍小助會請您入群。歡迎您加入噢~~希望得到建議咨詢、商務合作,也請與我們聯系。

          截屏2021-05-13 上午11.41.03.png


          文章來源:腳本之家   作者:junjie  

          分享此文一切功德,皆悉回向給文章原作者及眾讀者.

          免責聲明:藍藍設計尊重原作者,文章的版權歸原作者。如涉及版權問題,請及時與我們取得聯系,我們立即更正或刪除。

          藍藍設計www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務



          SpringBoot + Shiro + Mybatis-plus + Kaptcha + vue實現權限管理登錄功能

          前端達人

          登錄功能

          在這里插入圖片描述

          使用到的技術

          • shiro
          • Mybatis-plus
          • Springboot
          • kaptcha

          參考優秀博文

          一個博主做的shiro筆記:https://www.guitu18.com/post/2019/07/26/43.html

          引入依賴

           <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!-- shiro --> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.7.0</version> </dependency> <!--mybatis-plus 持久層--> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.4.1</version> </dependency> <!--   整合swagger     --> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.8.0</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>2.8.0</version> </dependency> <!-- kaptcha 驗證碼 --> <dependency> <groupId>com.github.penggle</groupId> <artifactId>kaptcha</artifactId> <version>2.3.2</version> </dependency> </dependencies> 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20
          • 21
          • 22
          • 23
          • 24
          • 25
          • 26
          • 27
          • 28
          • 29
          • 30
          • 31
          • 32
          • 33
          • 34
          • 35
          • 36
          • 37
          • 38
          • 39
          • 40
          • 41
          • 42
          • 43
          • 44
          • 45
          • 46
          • 47
          • 48
          • 49
          • 50
          • 51
          • 52
          • 53
          • 54

          配置shiro

          package com.unclebb.zlgl.config; import com.unclebb.zlgl.utils.CustomRealm; import org.apache.shiro.authc.credential.HashedCredentialsMatcher; import org.apache.shiro.mgt.DefaultSecurityManager; import org.apache.shiro.spring.web.ShiroFilterFactoryBean; import org.apache.shiro.util.ThreadContext; import org.apache.shiro.web.mgt.DefaultWebSecurityManager; import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.util.HashMap; import java.util.Map; /**
           * @program: zlgl
           * @description: Shiro配置類:將SecurityManager以及Realm都注入到Spring容器中
           * @author: LiuZhiliang
           * @create: 2021-05-10 08:56
           **/ @Configuration public class ShiroConfig { /** 
              * @Description: 代理生成器,需要借助SpringAOP來掃描@RequiresRoles和@RequiresPermissions等注解。生成代理類實現功能增強,從而實現權限控制。需要配合AuthorizationAttributeSourceAdvisor一起使用,否則權限注解無效。
              * @Param:
              * @return:
              * @Author: Liuzhiliang
              * @Date:
              */ @Bean public DefaultAdvisorAutoProxyCreator lifecycleBeanProcessor(){ DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator(); defaultAdvisorAutoProxyCreator.setProxyTargetClass(true); return defaultAdvisorAutoProxyCreator; } /** 
              * @Description:  上面配置的DefaultAdvisorAutoProxyCreator相當于一個切面,下面這個類就相當于切點了,兩個一起才能實現注解權限控制。
              * @Param:  
              * @return:  
              * @Author: Liuzhiliang
              * @Date:  
              */ @Bean public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager){ AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor(); advisor.setSecurityManager(securityManager); return advisor; } /**
               * @Description: Filter工廠,設置對應的過濾條件和跳轉條件
               * @Param:
               * @return:
               * @Author: Liuzhiliang
               * @Date:
               */ //權限管理,配置主要是Realm的管理認證 @Bean public DefaultWebSecurityManager securityManager(){ DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setRealm(myShiroRealm()); ThreadContext.bind(securityManager); return securityManager; } //將自己的驗證方式加入容器 @Bean public CustomRealm myShiroRealm() { HashedCredentialsMatcher matcher = new HashedCredentialsMatcher(); //加密 matcher.setHashAlgorithmName("md5"); matcher.setHashIterations(1); CustomRealm customRealm = new CustomRealm(); customRealm.setCredentialsMatcher(matcher); return customRealm; } @Bean public ShiroFilterFactoryBean shiroFilter(DefaultSecurityManager securityManager){ ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); shiroFilterFactoryBean.setSecurityManager(securityManager); //        Map<String,String> maps = new HashMap<>(); //        maps.put("/logout","logout"); //        maps.put("/**","authc"); //        shiroFilterFactoryBean.setLoginUrl("/login"); //        shiroFilterFactoryBean.setUnauthorizedUrl("/403.html"); //        shiroFilterFactoryBean.setSuccessUrl("/index"); //        shiroFilterFactoryBean.setFilterChainDefinitionMap(maps); return shiroFilterFactoryBean; } } 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20
          • 21
          • 22
          • 23
          • 24
          • 25
          • 26
          • 27
          • 28
          • 29
          • 30
          • 31
          • 32
          • 33
          • 34
          • 35
          • 36
          • 37
          • 38
          • 39
          • 40
          • 41
          • 42
          • 43
          • 44
          • 45
          • 46
          • 47
          • 48
          • 49
          • 50
          • 51
          • 52
          • 53
          • 54
          • 55
          • 56
          • 57
          • 58
          • 59
          • 60
          • 61
          • 62
          • 63
          • 64
          • 65
          • 66
          • 67
          • 68
          • 69
          • 70
          • 71
          • 72
          • 73
          • 74
          • 75
          • 76
          • 77
          • 78
          • 79
          • 80
          • 81
          • 82
          • 83
          • 84
          • 85
          • 86
          • 87
          • 88
          • 89
          • 90
          • 91
          • 92
          • 93
          • 94
          • 95
          • 96

          配置swagger

          package com.unclebb.zlgl.config; import com.google.common.base.Predicates; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.PathSelectors; import springfox.documentation.service.ApiInfo; import springfox.documentation.service.Contact; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.swagger2.annotations.EnableSwagger2; /**
           * @Author unclebb
           * @Description Swagger配置類
           * @Date 2021/5/9
           **/ @Configuration @EnableSwagger2 public class Swagger2Config { @Bean public Docket webApiConfig(){ return new Docket(DocumentationType.SWAGGER_2) .groupName("webApi") .apiInfo(webApiInfo()) .select() //過濾掉admin路徑下的所有頁面 .paths(Predicates.and(PathSelectors.regex("/user/.*"))) //過濾掉所有error或error.*頁面 //.paths(Predicates.not(PathSelectors.regex("/error.*"))) .build(); } private ApiInfo webApiInfo(){ return new ApiInfoBuilder() .title("網站-API文檔") .description("本文檔描述了網站微服務接口定義") .version("1.0") .contact(new Contact("qy", "http://atguigu.com", "55317332@qq.com")) .build(); } } 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20
          • 21
          • 22
          • 23
          • 24
          • 25
          • 26
          • 27
          • 28
          • 29
          • 30
          • 31
          • 32
          • 33
          • 34
          • 35
          • 36
          • 37
          • 38
          • 39
          • 40
          • 41
          • 42
          • 43
          • 44
          • 45
          • 46
          • 47
          • 48

          配置kaptcha

          package com.unclebb.zlgl.config; import com.google.code.kaptcha.impl.DefaultKaptcha; import com.google.code.kaptcha.util.Config; import org.springframework.context.annotation.Bean; import org.springframework.stereotype.Component; import java.util.Properties; /**
           * @program: zlgl
           * @description: Kaptcha配置類
           * @author: LiuZhiliang
           * @create: 2021-05-12 09:03
           **/ @Component public class KaptchaConfig { @Bean public DefaultKaptcha getKaptcha(){ DefaultKaptcha dk = new DefaultKaptcha(); Properties properties = new Properties(); // 圖片邊框 properties.setProperty("kaptcha.border", "yes"); // 邊框顏色 properties.setProperty("kaptcha.border.color", "105,179,90"); // 字體顏色 properties.setProperty("kaptcha.textproducer.font.color", "red"); // 圖片寬 properties.setProperty("kaptcha.image.width", "110"); // 圖片高 properties.setProperty("kaptcha.image.height", "40"); // 字體大小 properties.setProperty("kaptcha.textproducer.font.size", "30"); // session key properties.setProperty("kaptcha.session.key", "code"); // 驗證碼長度 properties.setProperty("kaptcha.textproducer.char.length", "4"); // 字體 properties.setProperty("kaptcha.textproducer.font.names", "宋體,楷體,微軟雅黑"); Config config = new Config(properties); dk.setConfig(config); return dk; } } 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20
          • 21
          • 22
          • 23
          • 24
          • 25
          • 26
          • 27
          • 28
          • 29
          • 30
          • 31
          • 32
          • 33
          • 34
          • 35
          • 36
          • 37
          • 38
          • 39
          • 40
          • 41
          • 42
          • 43
          • 44
          • 45
          • 46

          pojo

          User

          package com.unclebb.zlgl.pojo; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; import java.util.Set; /**
           * @Author unclebb
           * @Description 用戶實體類
           * @Date 2021/5/9
           **/ @Data @TableName(value = "user") public class User { @TableId(value = "id",type = IdType.AUTO)//指定自增策略 private int id; @TableField(value = "username") private String username; @TableField(value = "password") private String password; @TableField(exist = false) private Set<Role> rolesSet; private String salt; } 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20
          • 21
          • 22
          • 23
          • 24
          • 25
          • 26
          • 27
          • 28

          Role

          package com.unclebb.zlgl.pojo; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import lombok.Data; import java.util.Set; /**
           * @Author unclebb
           * @Description 角色實體類
           * @Date 2021/5/9
           **/ @Data public class Role { @TableId(value = "id",type = IdType.AUTO)//指定自增策略 private int id; @TableField(value = "user_name") private String userName; @TableField(value = "role_name") private String roleName; @TableField(exist = false) private Set<Permission> permissionSet; } 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20
          • 21
          • 22
          • 23
          • 24
          • 25
          • 26

          Permission

          package com.unclebb.zlgl.pojo; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import lombok.Data; /**
           * @Author unclebb
           * @Description 權限實體類
           * @Date 2021/5/9
           **/ @Data public class Permission { @TableId(value = "id",type = IdType.AUTO)//指定自增策略 private int id; @TableField(value = "role_name") private String roleName; @TableField(value = "permission_name") private String permissionName; } 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20
          • 21
          • 22

          Mapper

          基本格式:

          package com.unclebb.zlgl.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.unclebb.zlgl.pojo.User; import org.apache.ibatis.annotations.Mapper; /**
           * @Author unclebb
           * @Description 用戶映射
           * @Date 2021/5/9
           **/ @Mapper public interface UserMapper extends BaseMapper<User> { } 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15

          Service

          Interface

          LoginService

          package com.unclebb.zlgl.service; import com.baomidou.mybatisplus.extension.service.IService; import com.unclebb.zlgl.pojo.User; import org.springframework.stereotype.Service; /**
           * @Author unclebb
           * @Description 用戶登錄接口
           * @Date 2021/5/9
           **/ @Service public interface LoginService extends IService<User> { public User getByUsername(String username); } 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16

          RoleService

          package com.unclebb.zlgl.service; import com.baomidou.mybatisplus.extension.service.IService; import com.unclebb.zlgl.pojo.Role; import org.springframework.stereotype.Service; import java.util.List; @Service public interface RoleService extends IService<Role> { public List<Role> getRole(String userName); } 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13

          PermissionService

          package com.unclebb.zlgl.service; import com.baomidou.mybatisplus.extension.service.IService; import com.unclebb.zlgl.pojo.Permission; import org.springframework.stereotype.Service; import java.util.List; @Service public interface PermissionService extends IService<Permission> { public List<Permission> getPermissions(String roleName); } 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13

          ServiceImpl

          LoginServiceImpl

          package com.unclebb.zlgl.service.impl; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.unclebb.zlgl.mapper.UserMapper; import com.unclebb.zlgl.pojo.Role; import com.unclebb.zlgl.pojo.User; import com.unclebb.zlgl.service.LoginService; import com.unclebb.zlgl.service.PermissionService; import com.unclebb.zlgl.service.RoleService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.HashSet; import java.util.List; import java.util.Set; /**
           * @Author unclebb
           * @Description 登錄實現類
           * @Date 2021/5/9
           **/ @Service public class LoginServiceImpl extends ServiceImpl<UserMapper, User> implements LoginService { @Autowired RoleService roleService; @Override public User getByUsername(String username) { QueryWrapper<User> wrapper = new QueryWrapper<>(); wrapper.eq("username",username); User user = this.getOne(wrapper); List<Role> roleList = roleService.getRole(user.getUsername()); user.setRolesSet(new HashSet<Role>(roleList)); return user; } } 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20
          • 21
          • 22
          • 23
          • 24
          • 25
          • 26
          • 27
          • 28
          • 29
          • 30
          • 31
          • 32
          • 33
          • 34
          • 35
          • 36
          • 37
          • 38
          • 39

          RoleServiceImpl

          package com.unclebb.zlgl.service.impl; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.unclebb.zlgl.mapper.RoleMapper; import com.unclebb.zlgl.pojo.Permission; import com.unclebb.zlgl.pojo.Role; import com.unclebb.zlgl.service.PermissionService; import com.unclebb.zlgl.service.RoleService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.HashSet; import java.util.List; import java.util.Set; /**
           * @program: zlgl
           * @description: Role實現類
           * @author: LiuZhiliang
           * @create: 2021-05-10 16:16
           **/ @Service public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService { @Autowired PermissionService permissionService; @Override public List<Role> getRole(String userName) { QueryWrapper wrapper = new QueryWrapper(); wrapper.eq("user_name",userName); List<Role> roleList = this.list(wrapper); for (Role role:roleList){ List<Permission> permissions = permissionService.getPermissions(role.getRoleName()); role.setPermissionSet(new HashSet<Permission>(permissions)); } return roleList; } } 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20
          • 21
          • 22
          • 23
          • 24
          • 25
          • 26
          • 27
          • 28
          • 29
          • 30
          • 31
          • 32
          • 33
          • 34
          • 35
          • 36
          • 37
          • 38
          • 39

          PermissionServiceImpl

          package com.unclebb.zlgl.service.impl; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.unclebb.zlgl.mapper.PermissionMapper; import com.unclebb.zlgl.pojo.Permission; import com.unclebb.zlgl.pojo.User; import com.unclebb.zlgl.service.PermissionService; import org.springframework.stereotype.Service; import java.util.List; import java.util.Set; /**
           * @program: zlgl
           * @description: Permission實現類
           * @author: LiuZhiliang
           * @create: 2021-05-10 16:18
           **/ @Service public class PermissionServiceImpl extends ServiceImpl<PermissionMapper, Permission> implements PermissionService { @Override public List<Permission> getPermissions(String roleName) { QueryWrapper<Permission> wrapper = new QueryWrapper<>(); wrapper.eq("role_name",roleName); return this.list(wrapper); } } 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20
          • 21
          • 22
          • 23
          • 24
          • 25
          • 26
          • 27
          • 28

          Controller

          package com.unclebb.zlgl.controller; import com.unclebb.zlgl.pojo.Role; import com.unclebb.zlgl.pojo.User; import com.unclebb.zlgl.service.RoleService; import com.unclebb.zlgl.utils.Result; import io.swagger.annotations.ApiOperation; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.authz.AuthorizationException; import org.apache.shiro.session.Session; import org.apache.shiro.subject.Subject; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpSession; import java.util.Enumeration; import java.util.HashMap; import java.util.List; import java.util.Map; /**
           * @Author unclebb
           * @Description 登錄控制器
           * @Date 2021/5/9
           **/ @RestController public class LoginController { @Autowired RoleService roleService; /** 
              * @Description: 登錄接口 
              * @Param:  
              * @return:  
              * @Author: Liuzhiliang
              * @Date:  
              */ @ApiOperation(value = "登錄接口") @RequestMapping("/user/login") public Result login(@RequestBody User user){ System.out.println("進入/user/login API接口"); if (StringUtils.isEmpty(user.getUsername())||StringUtils.isEmpty(user.getPassword())){ return Result.fail("請輸入用戶名密碼"); } Subject subject = SecurityUtils.getSubject(); Session session = subject.getSession(); Object sessionId = session.getId(); Map ret = new HashMap<String,Object>(); ret.put("token",sessionId); UsernamePasswordToken token = new UsernamePasswordToken(user.getUsername(),user.getPassword()); try { //登錄成功 subject.login(token); return Result.ok(ret); } catch (AuthenticationException e) { e.printStackTrace(); //登錄失敗 return Result.fail("用戶名密碼錯誤"); } } /** 
              * @Description: 基本測試接口 
              * @Param:  
              * @return:  
              * @Author: Liuzhiliang
              * @Date:  
              */ @RequestMapping("/user/noauthority") public Result noauthority(){ return Result.fail("沒有權限"); } /** 
              * @Description: 測試session接口 
              * @Param:  
              * @return:  
              * @Author: Liuzhiliang
              * @Date:  
              */ @RequestMapping("/user/demoSession") @ResponseBody public String demoSession(HttpSession session){ System.out.println("測試session"); Enumeration<String> names = session.getAttributeNames(); while (names.hasMoreElements()){ String name = names.nextElement(); Object value = session.getAttribute(name); System.out.println(name + " -------  "+ value); } return "session 取值"; } /** 
              * @Description: 測試session接口 
              * @Param:  
              * @return:  
              * @Author: Liuzhiliang
              * @Date:  
              */ @RequestMapping("/user/demoSession2") @ResponseBody public String demoSession2(){ Subject subject = SecurityUtils.getSubject(); Session session = subject.getSession(); System.out.println(session.getHost()); System.out.println(session.getId()); System.out.println(session.getLastAccessTime().getTime()); System.out.println(session.getTimeout()); System.out.println(session.getAttribute("test")); return "session 取值"; } /** 
              * @Description: 測試session接口 
              * @Param:  
              * @return:  
              * @Author: Liuzhiliang
              * @Date:  
              */ @RequestMapping("/user/checkPermission") @ResponseBody public Result checkPermission(User user){ if (StringUtils.isEmpty(user.getUsername())||StringUtils.isEmpty(user.getPassword())){ return Result.fail("請輸入用戶名密碼"); } Subject subject = SecurityUtils.getSubject(); Session session = subject.getSession(); session.setAttribute("test","test"); UsernamePasswordToken token = new UsernamePasswordToken(user.getUsername(),user.getPassword()); token.setRememberMe(true); try { //登錄成功 subject.login(token); } catch (AuthenticationException e) { e.printStackTrace(); //登錄失敗 return Result.fail("用戶名密碼錯誤"); } try { subject.checkRole("admin"); return Result.ok("權限檢查成功"); } catch (AuthorizationException e) { e.printStackTrace(); return Result.fail("檢查權限失敗"); } } /** 
              * @Description: 根據token獲取用戶授權信息接口 
              * @Param:  
              * @return:  
              * @Author: Liuzhiliang
              * @Date:  
              */ @RequestMapping("/user/checkRole") public Result checkRole(@RequestParam String token){ Subject subject = SecurityUtils.getSubject(); Session session = subject.getSession(); List<Role> roleList = null; if (token.equals(session.getId().toString())){ String username = session.getAttribute("org.apache.shiro.subject.support.DefaultSubjectContext_PRINCIPALS_SESSION_KEY").toString(); System.out.println(username); roleList = roleService.getRole(username); } return Result.ok(roleList); } /** 
              * @Description: 測試kaptcha ,獲取驗證碼
              * @Param:  
              * @return:  
              * @Author: Liuzhiliang
              * @Date:  
              */ @RequestMapping("/user/testKaptcha") @ResponseBody public String TestKaptcha(HttpServletRequest request, HttpServletResponse response) throws IOException { byte[] captcha = null; ByteArrayOutputStream out = new ByteArrayOutputStream(); try { // 將生成的驗證碼保存在session中 String createText = defaultKaptcha.createText(); request.getSession().setAttribute("rightCode", createText); BufferedImage bi = defaultKaptcha.createImage(createText); ImageIO.write(bi, "jpg", out); } catch (Exception e) { response.sendError(HttpServletResponse.SC_NOT_FOUND); } captcha = out.toByteArray(); response.setHeader("Cache-Control", "no-store"); response.setHeader("Pragma", "no-cache"); response.setDateHeader("Expires", 0); response.setContentType("image/jpeg"); ServletOutputStream sout = response.getOutputStream(); sout.write(captcha); sout.flush(); sout.close(); return "測試Kaptcha"; } /**
               * 校對驗證碼
               *
               * @param request
               * @param response
               * @return
               */ @RequestMapping(value = "/user/verifyKaptcha") public Result imgvrifyControllerDefaultKaptcha(HttpServletRequest request, HttpServletResponse response) { ModelAndView model = new ModelAndView(); String rightCode = (String) request.getSession().getAttribute("rightCode"); String tryCode = request.getParameter("tryCode"); System.out.println("rightCode:" + rightCode + " ———— tryCode:" + tryCode); if (!rightCode.equals(tryCode)) { model.addObject("info", "驗證碼錯誤,請再輸一次!"); model.setViewName("login"); return Result.fail("驗證碼錯誤"); } else { model.addObject("info", "登陸成功"); model.setViewName("index"); return Result.ok("驗證成功"); } } /** 
              * @Description: 測試 校驗權限 permission 
              * @Param:  
              * @return:  
              * @Author: Liuzhiliang
              * @Date:  
              */ @RequestMapping("/user/testShiroPermission") @RequiresPermissions("user:add") public Result TestShiroPermissions(){ System.out.println("訪問 TestShiroPermissions API"); Subject subject = SecurityUtils.getSubject(); String username = (String) subject.getPrincipal(); System.out.println(username); return Result.ok(username); } /** 
              * @Description: 登出功能API
              * @Param:  
              * @return:  
              * @Author: Liuzhiliang
              * @Date:  
              */ @RequestMapping("/user/logout") public Result logout(){ Subject subject = SecurityUtils.getSubject(); String username = (String) subject.getPrincipal(); subject.logout(); return Result.ok(username); } /** 
              * @Description:  測試校驗 角色 role
              * @Param:  
              * @return:  
              * @Author: Liuzhiliang
              * @Date:  
              */ @RequestMapping("/user/TestRole") @RequiresRoles("admin") public Result TestRole(){ System.out.println("測試TestRole"); return Result.ok("測試Role"); } } 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20
          • 21
          • 22
          • 23
          • 24
          • 25
          • 26
          • 27
          • 28
          • 29
          • 30
          • 31
          • 32
          • 33
          • 34
          • 35
          • 36
          • 37
          • 38
          • 39
          • 40
          • 41
          • 42
          • 43
          • 44
          • 45
          • 46
          • 47
          • 48
          • 49
          • 50
          • 51
          • 52
          • 53
          • 54
          • 55
          • 56
          • 57
          • 58
          • 59
          • 60
          • 61
          • 62
          • 63
          • 64
          • 65
          • 66
          • 67
          • 68
          • 69
          • 70
          • 71
          • 72
          • 73
          • 74
          • 75
          • 76
          • 77
          • 78
          • 79
          • 80
          • 81
          • 82
          • 83
          • 84
          • 85
          • 86
          • 87
          • 88
          • 89
          • 90
          • 91
          • 92
          • 93
          • 94
          • 95
          • 96
          • 97
          • 98
          • 99
          • 100
          • 101
          • 102
          • 103
          • 104
          • 105
          • 106
          • 107
          • 108
          • 109
          • 110
          • 111
          • 112
          • 113
          • 114
          • 115
          • 116
          • 117
          • 118
          • 119
          • 120
          • 121
          • 122
          • 123
          • 124
          • 125
          • 126
          • 127
          • 128
          • 129
          • 130
          • 131
          • 132
          • 133
          • 134
          • 135
          • 136
          • 137
          • 138
          • 139
          • 140
          • 141
          • 142
          • 143
          • 144
          • 145
          • 146
          • 147
          • 148
          • 149
          • 150
          • 151
          • 152
          • 153
          • 154
          • 155
          • 156
          • 157
          • 158
          • 159
          • 160
          • 161
          • 162
          • 163
          • 164
          • 165
          • 166
          • 167
          • 168
          • 169
          • 170
          • 171
          • 172
          • 173
          • 174
          • 175
          • 176
          • 177
          • 178
          • 179
          • 180
          • 181
          • 182
          • 183
          • 184
          • 185
          • 186
          • 187
          • 188
          • 189
          • 190
          • 191
          • 192
          • 193
          • 194
          • 195
          • 196
          • 197
          • 198
          • 199
          • 200
          • 201
          • 202
          • 203
          • 204
          • 205
          • 206
          • 207
          • 208
          • 209
          • 210
          • 211
          • 212
          • 213
          • 214
          • 215
          • 216
          • 217
          • 218
          • 219
          • 220
          • 221
          • 222
          • 223
          • 224
          • 225
          • 226
          • 227
          • 228
          • 229
          • 230
          • 231
          • 232
          • 233
          • 234
          • 235
          • 236
          • 237
          • 238
          • 239
          • 240
          • 241
          • 242
          • 243
          • 244
          • 245
          • 246
          • 247
          • 248
          • 249
          • 250
          • 251
          • 252
          • 253
          • 254
          • 255
          • 256
          • 257
          • 258
          • 259
          • 260
          • 261
          • 262
          • 263
          • 264
          • 265
          • 266
          • 267
          • 268
          • 269
          • 270
          • 271
          • 272
          • 273
          • 274
          • 275
          • 276
          • 277
          • 278
          • 279

          util

          Result

          package com.unclebb.zlgl.utils; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; /**
           * @Author unclebb
           * @Description 統一返回API格式
           * @Date 2021/5/9
           **/ @Data @ApiModel(value = "全局統一返回結果") public class Result<T> { @ApiModelProperty(value = "返回碼") private Integer code; @ApiModelProperty(value = "返回消息") private String message; @ApiModelProperty(value = "返回數據") private T data; public Result(){} public static <T> Result<T> build(T data) { Result<T> result = new Result<T>(); if (data != null) result.setData(data); return result; } public static <T> Result<T> build(T body, ResultCodeEnum resultCodeEnum) { Result<T> result = build(body); result.setCode(resultCodeEnum.getCode()); result.setMessage(resultCodeEnum.getMessage()); return result; } public static<T> Result<T> ok(){ return Result.ok(null); } /**
               * 操作成功
               * @param data
               * @param <T>
               * @return
               */ public static<T> Result<T> ok(T data){ Result<T> result = build(data); return build(data, ResultCodeEnum.SUCCESS); } public static<T> Result<T> fail(){ return Result.fail(null); } /**
               * 操作失敗
               * @param data
               * @param <T>
               * @return
               */ public static<T> Result<T> fail(T data){ Result<T> result = build(data); return build(data, ResultCodeEnum.FAIL); } public Result<T> message(String msg){ this.setMessage(msg); return this; } public Result<T> code(Integer code){ this.setCode(code); return this; } } 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20
          • 21
          • 22
          • 23
          • 24
          • 25
          • 26
          • 27
          • 28
          • 29
          • 30
          • 31
          • 32
          • 33
          • 34
          • 35
          • 36
          • 37
          • 38
          • 39
          • 40
          • 41
          • 42
          • 43
          • 44
          • 45
          • 46
          • 47
          • 48
          • 49
          • 50
          • 51
          • 52
          • 53
          • 54
          • 55
          • 56
          • 57
          • 58
          • 59
          • 60
          • 61
          • 62
          • 63
          • 64
          • 65
          • 66
          • 67
          • 68
          • 69
          • 70
          • 71
          • 72
          • 73
          • 74
          • 75
          • 76
          • 77
          • 78
          • 79
          • 80
          • 81

          ResultCode

          package com.unclebb.zlgl.utils; import lombok.Getter; /**
           * @Author unclebb
           * @Description API狀態信息
           * @Date 2021/5/9
           **/ @Getter public enum ResultCodeEnum { SUCCESS(200,"成功"), FAIL(201, "失敗"), SERVICE_ERROR(202, "服務異常"), DATA_ERROR(204, "數據異常"), SIGN_ERROR(300, "簽名錯誤"), PAY_PASSWORD_ERROR(401, "支付密碼錯誤"), REPEAT_ERROR(402, "重復提交"), INVEST_AMMOUNT_MORE_ERROR(501, "出借金額已經多余標的金額"), RETURN_AMMOUNT_MORE_ERROR(502, "還款金額不正確"), PROJECT_AMMOUNT_ERROR(503, "標的金額不一致") ; private Integer code; private String message; private ResultCodeEnum(Integer code, String message) { this.code = code; this.message = message; } } 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20
          • 21
          • 22
          • 23
          • 24
          • 25
          • 26
          • 27
          • 28
          • 29
          • 30
          • 31
          • 32
          • 33
          • 34
          • 35
          • 36
          • 37

          CustomRealm

          package com.unclebb.zlgl.utils; import com.unclebb.zlgl.pojo.Permission; import com.unclebb.zlgl.pojo.Role; import com.unclebb.zlgl.pojo.User; import com.unclebb.zlgl.service.LoginService; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.AuthenticationInfo; import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authc.SimpleAuthenticationInfo; import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.authz.SimpleAuthorizationInfo; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection; import org.apache.shiro.util.ByteSource; import org.springframework.beans.factory.annotation.Autowired; /**
           * @program: zlgl
           * @description: 自定義Realm
           * @author: LiuZhiliang
           * @create: 2021-05-10 09:09
           **/ public class CustomRealm extends AuthorizingRealm { @Autowired LoginService loginService; /** 
              * @Description: 授權配置
              * @Param:  
              * @return:  
              * @Author: Liuzhiliang
              * @Date:  
              */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { String username = (String) principals.getPrimaryPrincipal(); User user = loginService.getByUsername(username); if (user == null){ return null; }else { SimpleAuthorizationInfo  simpleAuthorizationInfo = new SimpleAuthorizationInfo(); for (Role role : user.getRolesSet()){ simpleAuthorizationInfo.addRole(role.getRoleName()); for (Permission permission : role.getPermissionSet()){ simpleAuthorizationInfo.addStringPermission(permission.getPermissionName()); } } return simpleAuthorizationInfo; } } /** 
              * @Description: 認證配置 
              * @Param:  
              * @return:  
              * @Author: Liuzhiliang
              * @Date:  
              */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { String username = token.getPrincipal().toString(); User user = loginService.getByUsername(username); if (user == null){ return null; }else { //匹配密碼 SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(username,user.getPassword(),getName()); simpleAuthenticationInfo.setCredentialsSalt(ByteSource.Util.bytes(user.getSalt())); return simpleAuthenticationInfo; } } } 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20
          • 21
          • 22
          • 23
          • 24
          • 25
          • 26
          • 27
          • 28
          • 29
          • 30
          • 31
          • 32
          • 33
          • 34
          • 35
          • 36
          • 37
          • 38
          • 39
          • 40
          • 41
          • 42
          • 43
          • 44
          • 45
          • 46
          • 47
          • 48
          • 49
          • 50
          • 51
          • 52
          • 53
          • 54
          • 55
          • 56
          • 57
          • 58
          • 59
          • 60
          • 61
          • 62
          • 63
          • 64
          • 65
          • 66
          • 67
          • 68
          • 69
          • 70
          • 71
          • 72
          • 73
          • 74
          • 75

          前端代碼

          前端我這里直接用了 開源的管理系統框架
          附地址:

          https://github.com/PanJiaChen/vue-admin-template

          運行截圖如下
          在這里插入圖片描述
          在這里插入圖片描述

          完事兒只需要改一下它的 返回狀態碼校驗,配置下跨域就可以了
          在這里插入圖片描述

          整合驗證碼

          驗證碼部分包含兩個API接口

          /user/testKaptcha 獲取驗證碼信息
          /user/verifyKaptcha 校驗

          其中獲取驗證碼圖片信息相當于請求靜態圖片資源,直接將驗證碼圖片的src指向 該接口即可,前端源碼如下:

           <el-image :src="kaptcha" @click="refreshCode()" alt="加載失敗" style="margin-left:10px;height:40px;margin-top:5px"> <div slot="placeholder" class="image-slot"> <i class="el-icon-loading"></i> </div> </el-image> 
          
          • 1
          • 2
          • 3
          • 4
          • 5

          其中路徑定義為:

          kaptcha:"http://localhost:8082/user/testKaptcha?t="+ new Date().getTime(), 
          
          • 1

          后面加的時間參數是為了刷新url用的
          前端的刷新函數就是將kaptcha重新賦值

           refreshCode(){ console.log("測試切換驗證碼") this.kaptcha = "http://localhost:8082/user/testKaptcha?t="+ new Date().getTime() console.log(this.kaptcha) }, 
          
          • 1
          • 2
          • 3
          • 4
          • 5

          登錄、權限校驗、登出效果如下

          登錄

          登錄首先會驗證 驗證碼的正確性,登陸成功進入主界面

          驗證碼錯誤如下:
          在這里插入圖片描述
          用戶名密碼錯誤如下:
          在這里插入圖片描述
          登陸成功后請求校驗角色 校驗成功
          在這里插入圖片描述請求校驗權限 校驗成功
          在這里插入圖片描述

          退出,執行兩次,data為null
          在這里插入圖片描述

          再次校驗權限,報出異常

          在這里插入圖片描述


           藍藍設計建立了UI設計分享群,每天會分享國內外的一些優秀設計,如果有興趣的話,可以進入一起成長學習,請掃碼藍小助,報下信息,藍小助會請您入群。歡迎您加入噢~~希望得到建議咨詢、商務合作,也請與我們聯系。

          截屏2021-05-13 上午11.41.03.png


          文章來源:csdn   作者:黑胡子大叔的小屋

          分享此文一切功德,皆悉回向給文章原作者及眾讀者.
          免責聲明:藍藍設計尊重原作者,文章的版權歸原作者。如涉及版權問題,請及時與我們取得聯系,我們立即更正或刪除。

          藍藍設計www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務

          SpringBoot + Spring Cloud +Vue 管理系統前端搭建(二、visual studio code開發前端項目)

          前端達人

          我們打開visual studio code , 選擇文件------------->將文件夾添加到工作區,導入我們的項目

           

          安裝Element

          導入后,我們安裝以下element

          官網:https://element.eleme.cn/#/zh-CN/component/installation

          安裝命令:npm add element-ui或者也可以用yarn

          安裝完成后,我們在main.js中引入Element

          import Vue from 'vue'

          import App from './App'

          import router from './router'

          import ElementUI from 'element-ui'

          import 'element-ui/lib/theme-chalk/index.css'

          Vue.config.productionTip = false

           

          /* eslint-disable no-new */

          Vue.use(ElementUI)

          new Vue({

          el: '#app',

          router,

          components: { App },

          template: '<App/>'

          })

          頁面路由

           我們把components改名為views,并在目錄下添加3個頁面:Login.vue、Home.vue、404.vue。

          頁面內容類似:

          <template>

          <div class="page">

          <h2>Login Page</h2>

          </div>

          </template>

           

          <script>

          export default {

          name: 'Login'

          }

          </script>

          配置路由

          打開router/index.js,添加3個路由分別對應主頁、登錄、404頁面

          import Vue from 'vue'

          import Router from 'vue-router'

          import Login from '@/views/Login'

          import Home from '@/views/Home'

          import NotFound from '@/views/404'

           

          Vue.use(Router)

           

          export default new Router({

          routes: [

          {

          path: '/',

          name: 'Home',

          component: Home

          }, {

          path: '/login',

          name: 'Login',

          component: Login

          }, {

          path: '/404',

          name: 'notFound',

          component: NotFound

          }

          ]

          })

          配置完后啟動項目,在瀏覽器訪問測試

          http://localhost:8080/#/

          http://localhost:8080/#/login

           

          http://localhost:8080/#/404

          說明我們的配置已經生效了

          安裝scss

          安裝依賴:

          npm uninstall sass-loader //卸載當前版本) 
          npm install sass-loader@7.3.1 --save-dev //卸了重新安裝了一個低版本
          npm install node-sass@4.14.1 --save-dev //安裝node-sass 
          

          安裝的時候注意對應版本,版本不對應,啟動會報錯

          安裝后修改404頁面

          <template>

          <div class="site-wrapper site-page--not-found">

          <div class="site-content__wrapper">

          <div class="site-content">

          <h2 class="not-found-title">404</h2>

          <p class="not-found-desc">抱歉!您訪問的頁面<em>失聯</em>啦 ...</p>

          <el-button @click="$router.go(-1)">返回上一頁</el-button>

          <el-button type="primary" class="not-found-btn-gohome" @click="$router.push('/')">進入首頁</el-button>

          </div>

          </div>

          </div>

          </template>

           

          <script>

          export default {

          name: '404'

          }

          </script>

           

          <style lang="scss">

          .site-wrapper.site-page--not-found {

          position: absolute;

          top: 60px;

          right: 0;

          bottom: 0;

          left: 0;

          overflow: hidden;

          .site-content__wrapper {

          padding: 0;

          margin: 0;

          background-color: #fff;

          }

          .site-content {

          position: fixed;

          top: 15%;

          left: 50%;

          z-index: 2;

          padding: 30px;

          text-align: center;

          transform: translate(-50%, 0);

          }

          .not-found-title {

          margin: 20px 0 15px;

          font-size: 8em;

          font-weight: 500;

          color: rgb(55, 71, 79);

          }

          .not-found-desc {

          margin: 0 0 30px;

          font-size: 26px;

          text-transform: uppercase;

          color: rgb(118, 131, 143);

          > em {

          font-style: normal;

          color: #ee8145;

          }

          }

          .not-found-btn-gohome {

          margin-left: 30px;

          }

          }

          </style>

          再瀏覽器訪問http://localhost:8080/#/404

           

          可以看到樣式改變了

          安裝axios

          命令:npm install axios

          安裝完成后修改Home頁面,進行一個簡單的測試

          <template>

          <div class="page">

          <h2>Home Page</h2>

          <el-button type="primary" @click="testAxios()">測試Axios調用</el-button>

          </div>

          </template>

           

          <script>

          import axios from 'axios'

          import mock from '@/mock/mock.js'

          export default {

          name: 'Home',

          methods: {

          testAxios() {

          axios.get('http://localhost:8080').then(res => { alert(res.data) })

          }

          }

          }

          </script>

          可以看到我們的請求已經成功了

          安裝Mock.js

          為了模擬后臺接口提供頁面需要的數據,引入mock.js

          安裝依賴:npm install mockjs -dev

          安裝完成,在src新建一個mock目錄,創建mock.js,在里面模擬兩個接口,分別攔截用戶和菜單的請求并返回相應數據。

          import Mock from 'mockjs'

           

          Mock.mock('http://localhost:8080/user', {

          'name': '@name', // 隨機生成姓名

          'name': '@email', // 隨機生成郵箱

          'age|1-12': 7, // 年齡1-12之間

          })

          Mock.mock('http://localhost:8080/menu', {

          'id': '@increment', // id自增

          'name': 'menu', // 名稱為menu

          'order|1-10': 6, // 排序1-10之間

          })

          修改Home.vue,在頁面添加兩個按鈕,分別觸發用戶和菜單請求。成功后彈出返回結果

          注意:要在頁面引入mock    import mock from '@/mock/mock.js'

          Home.vue

          <template>
            <div class="page">
              <h2>Home Page</h2>
              <el-button type="primary" @click="testAxios()">測試Axios調用</el-button>
              <el-button type="primary" @click="getUser()">獲取用戶信息</el-button>
              <el-button type="primary" @click="getMenu()">獲取菜單信息</el-button>
            </div>
          </template>

          <script>
          import axios from 'axios'
          import mock from '@/mock/mock.js'
          export default {
            name: 'Home',
            methods: {
              testAxios() {
                axios.get('http://localhost:8080').then(res => { alert(res.data) })
              },
              getUser() {
                axios.get('http://localhost:8080/user').then(res => { alert(JSON.stringify(res.data)) })
              },
              getMenu() {
                axios.get('http://localhost:8080/menu').then(res => { alert(JSON.stringify(res.data)) })
              }
            }
          }
          </script>

          訪問http://localhost:8080/#/

          點擊獲取用戶信息

          點擊獲取菜單信息

          可以看到我們已經得到響應數據,這樣mock就集成進來了

          看完記得點贊哦

            藍藍設計建立了UI設計分享群,每天會分享國內外的一些優秀設計,如果有興趣的話,可以進入一起成長學習,請掃碼藍小助,報下信息,藍小助會請您入群。歡迎您加入噢~~希望得到建議咨詢、商務合作,也請與我們聯系。

          截屏2021-05-13 上午11.41.03.png


          文章來源:csdn   作者:Java璐到底

          分享此文一切功德,皆悉回向給文章原作者及眾讀者.
          免責聲明:藍藍設計尊重原作者,文章的版權歸原作者。如涉及版權問題,請及時與我們取得聯系,我們立即更正或刪除。

          藍藍設計www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 平面設計服務


          日歷

          鏈接

          個人資料

          藍藍設計的小編 http://www.syprn.cn

          存檔

          亚洲va欧美va天堂v国产综合