<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>

          首頁

          Sass開發注意點

          seo達人

          避免選擇器嵌套:

          選擇器嵌套最大的問題是將使最終的代碼難以閱讀。開發者需要花費巨大精力計算不同縮進級別下的選擇器具體的表現效果。

          選擇器越具體則聲明語句越冗長,而且對最近選擇器的引用(&)也越頻繁。在某些時候,出現混淆選擇器路徑和探索下一級選擇器的錯誤率很高,這非常不值得。



          混合宏

          在 Sass 中通過 @mixin 關鍵詞聲明了一個混合宏,那么在實際調用中,其匹配了一個關鍵詞“@include”來調用聲明好的混合宏。



          @mixin border-radius{

            -webkit-border-radius: 3px;

            border-radius: 3px;

          }



          .box {

            @include border-radius;

            margin-bottom: 5px;

          }



          .btn {

            @include border-radius;

          }



          繼承 @extend

          在 Sass 中也具有繼承一說,也是繼承類中的樣式代碼塊。在 Sass 中是通過關鍵詞 “@extend”來繼承已存在的類樣式塊,從而實現代碼的繼承。如下所示:



          //SCSS

          .btn {

            border: 1px solid #ccc;

            padding: 6px 10px;

            font-size: 14px;

          }



          .btn-primary {

            background-color: #f36;

            color: #fff;

            @extend .btn;

          }



          .btn-second {

            background-color: orange;

            color: #fff;

            @extend .btn;

          }



          編譯后



          //CSS

          .btn, .btn-primary, .btn-second {

            border: 1px solid #ccc;

            padding: 6px 10px;

            font-size: 14px;

          }



          .btn-primary {

            background-color: #f36;

            color: #fff;

          }



          .btn-second {

            background-clor: orange;

            color: #fff;

          }



          占位符 %

          Sass 中的占位符 %placeholder 功能是一個很強大,很實用的一個功能,這也是我非常喜歡的功能。他可以取代以前 CSS 中的基類造成的代碼冗余的情形。因為 %placeholder 聲明的代碼,如果不被 @extend 調用的話,不會產生任何代碼。



          //SCSS

          %mt5 {

            margin-top: 5px;

          }

          %pt5{

            padding-top: 5px;

          }



          .btn {

            @extend %mt5;

            @extend %pt5;

          }



          .block {

            @extend %mt5;



            span {

              @extend %pt5;

            }

          }



          編譯后(代碼相同的會自動整合)



          //CSS

          .btn, .block {

            margin-top: 5px;

          }



          .btn, .block span {

            padding-top: 5px;

          }





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

          關于Vue中的slot的理解

          seo達人

          今天在做vue項目的時候,遇到一個問題就是slot插槽的概念。這突然讓我想起用過類似于element-ui前端框架時,用他們組件的時候接觸過slot,如下圖: 







          這是element-ui對話框的api,當時我記得我百度過,就是這樣寫就ok了,當時也沒深究。



          <el-dialog :visible.sync="dialogVisible" width="30%" :before-close="handleClose">

            <span slot="title">

              我是對話框標題

            </span>

            <!-- 這邊寫對話框的內容 -->

            <span>我是對話框內容</span>

            <span slot="footer" class="dialog-footer">

              我是對話框footer

            </span>

          </el-dialog>

          效果是這樣:







          今天研究了,我就查看了源碼:







          百度的發現這邊有兩個概念:



          1.單個插槽也叫匿名插槽



          slot不帶name,如下:



          <slot></slot>

          一個子組件只有一個匿名插槽,就好比對話框的內容沒有被含有slot="xx"屬性的標簽包裹,那么就會替換掉匿名插槽



          2.具名插槽



          slot 有name,如下



          <slot name='xx'></slot>

          具名插槽就可以有多個,就好比對話框含有slot='header'屬性的標簽會替換掉子組件<slot name='header'></slot>


          JavaScript雜記(雜而又雜)

          seo達人

          JavaScript雜記

          JavaScript可以直接寫入 HTML 輸出流

          JavaScript 能夠直接寫入 HTML 輸出流中:



          之間的代碼行包含了 JavaScript: 您可以在 HTML 文檔中放入不限數量的腳本。 腳本可位于 HTML 的 或 部分中,或者同時存在于兩個部分中。 通常的做法是把函數放入 部分中,或者放在頁面底部。這樣就可以把它們安置到同一處位置,不會干擾頁面的內容。 6. 外部的 JavaScript 也可以把腳本保存到外部文件中。外部文件通常包含被多個網頁使用的代碼。 外部 JavaScript 文件的文件擴展名是 .js。 如需使用外部文件,請在

          這個程序寫的不好,因為它沒有觸法程序,不能體現JS的作用

          ? 使用 document.write() 方法將內容寫到 HTML 文檔中。

          ? 使用 innerHTML 寫入到 HTML 元素。

          ? 使用 console.log() 寫入到瀏覽器的控制臺。

          console.log() 方法能夠讓你看到你在頁面中的輸出內容,讓你更容易調試javascript;與alert相比,console不會打斷你頁面的操作,console里面的內容非常豐富,你可以在控制臺輸入 console。

          您知道嗎?

          Note 程序中調試是測試,查找及減少bug(錯誤)的過程。

          8. JavaScript 數據類型

          JavaScript 有多種數據類型:數字,字符串,數組,對象等等:



          var length = 16; // Number 通過數字字面量賦值

          var points = x * 10; // Number 通過表達式字面量賦值

          var lastName = “Johnson”; // String 通過字符串字面量賦值

          var cars = [“Saab”, “Volvo”, “BMW”]; // Array 通過數組字面量賦值

          var person = {firstName:“John”, lastName:“Doe”}; // Object 通過對象字面量賦值

          9. Value = undefined

          在計算機程序中,經常會聲明無值的變量。未使用值來聲明的變量,其值實際上是 undefined。



          在執行過以下語句后,變量 carname 的值將是 undefined:



          var carname;

          10. Undefined 和 Null

          Undefined 這個值表示變量不含有值。



          可以通過將變量的值設置為 null 來清空變量。

          11. 聲明變量類型

          當您聲明新變量時,可以使用關鍵詞 “new” 來聲明其類型:



          var carname=new String;

          var x= new Number;

          var y= new Boolean;

          var cars= new Array;

          var person= new Object;



          JavaScript 變量均為對象。當您聲明一個變量時,就創建了一個新的對象。



          JavaScript函數

          在JavaScript中,函數即對象,可以隨意地被程序操控,函數可以嵌套在其他函數中定義,這樣可以訪問它們被定義時所處的作用域中的任何變量。

          函數是由事件驅動的或者當它被調用時執行的可重復使用的代碼塊。

          <1>JavaScript 函數語法

          函數就是包裹在花括號中的代碼塊,前面使用了關鍵詞 function:



          function functionname()

          {

          執行代碼

          }



          當調用該函數時,會執行函數內的代碼。



          可以在某事件發生時直接調用函數(比如當用戶點擊按鈕時),并且可由 JavaScript 在任何位置進行調用。



          lamp JavaScript 對大小寫敏感。關鍵詞 function 必須是小寫的,并且必須以與函數名稱相同的大小寫來調用函數。

          提示:function 中的花括號是必需的,即使函數體內只包含一條語句,仍然必須使用花括號將其括起來。



          <2>帶有返回值的函數

          有時,我們會希望函數將值返回調用它的地方。



          通過使用 return 語句就可以實現。



          在使用 return 語句時,函數會停止執行,并返回指定的值。

          <3>在您僅僅希望退出函數時 ,也可使用 return 語句。返回值是可選的:



          function myFunction(a,b)

          {

          if (a>b)

          {

          return;

          }

          x=a+b

          }

          如果 a 大于 b,則上面的代碼將退出函數,并不會計算 a 和 b 的總和。



          <3>局部 JavaScript 變量

          在 JavaScript 函數內部聲明的變量(使用 var)是局部變量,所以只能在函數內訪問它。(該變量的作用域是局部的)。

          您可以在不同的函數中使用名稱相同的局部變量,因為只有聲明過該變量的函數能識別出該變量。

          只要函數運行完畢,本地變量就會被刪除。

          局部變量比同名全局變量的優先級高,所以局部變量會隱藏同名的全局變量。



          全局 JavaScript 變量

          在函數外聲明的變量是全局變量,網頁上的所有腳本和函數都能訪問它。



          JavaScript 變量的生存期

          JavaScript 變量的生命期從它們被聲明的時間開始。

          局部變量會在函數運行以后被刪除。

          全局變量會在頁面關閉后被刪除。



          向未聲明的 JavaScript 變量分配值

          如果您把值賦給尚未聲明的變量,該變量將被自動作為全局變量聲明。

          這條語句:

          carname=“Volvo”;

          將聲明一個全局變量 carname,即使它在函數內執行。

          13. JavaScript 作用域

          作用域是可訪問變量的集合。



          在JavaScript中,能夠定義全局作用域或者局部作用域。



          HTML 中的全局變量

          在 HTML 中, 全局變量是 window 對象: 所有數據變量都屬于 window 對象。

          實例

          //此處可使用 window.carName



          function myFunction() {

          carName = “Volvo”;

          }



          ? 你的全局變量,或者函數,可以覆蓋 window 對象的變量或者函數。

          ? 局部變量,包括 window 對象可以覆蓋全局變量和函數。

          也就是說全局變量可以覆蓋全局變量,局部可以在局部作用域里面覆蓋全局變量



          JavaScript事件

          JavaScript 事件

          事件是可以被 JavaScript 偵測到的行為。

          HTML 事件是發生在 HTML 元素上的事情。



          當在 HTML 頁面中使用 JavaScript 時, JavaScript 可以觸發這些事件。

          HTML 事件

          HTML 事件可以是瀏覽器行為,也可以是用戶行為。

          HTML 網頁中的每個元素都可以產生某些可以觸發 JavaScript 函數的事件。

          以下是 HTML 事件的實例:

          ? HTML 頁面完成加載

          ? HTML input 字段改變時

          ? HTML 按鈕被點擊

          通常,當事件發生時,你可以做些事情。

          在事件觸發時 JavaScript 可以執行一些代碼。

          HTML 元素中可以添加事件屬性,使用 JavaScript 代碼來添加 HTML 元素。

          單引號:



          雙引號:

          常見的HTML事件

          下面是一些常見的HTML事件的列表:

          事件 描述

          onchange HTML 元素改變

          onclick 用戶點擊 HTML 元素

          onmouseover 用戶在一個HTML元素上移動鼠標

          onmouseout 用戶從一個HTML元素上移開鼠標

          onkeydown 用戶按下鍵盤按鍵

          onload 瀏覽器已完成頁面的加載

          15. JavaScript 字符串

          JavaScript 字符串用于存儲和處理文本。



          字符串長度

          可以使用內置屬性 length 來計算字符串的長度:



          字符串屬性和方法

          原始值字符串,如 “John”, 沒有屬性和方法(因為他們不是對象)。

          原始值可以使用 JavaScript 的屬性和方法,因為 JavaScript 在執行方法和屬性時可以把原始值當作對象。

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

          調整瀏覽器分辨率的插件下載方法

          seo達人

          前端開發在開發過程中經常會被UI小姐姐要求開發的各個頁面都按照她的理想效果顯示,所以就需要前端經常調整自己的瀏覽器分辨率,而今天筆者給大家帶來的就是谷歌調整瀏覽器分辨率的插件下載配置方法:



          點擊不同的分辨率,瀏覽器就會開始切換了。



          接下來筆者給大家分享如何下載和配置這個插件:

          下載地址:https://me.csdn.net/download/weixin_43606158



          或者關注筆者后加筆者QQ/微信筆者私聊發你:1336791007



          下載后請先在谷歌瀏覽器上方輸入 chrome://extensions/ 進入到谷歌的拓展程序。



          而后將下載后的文件移動到谷歌拓展程序界面上。





          PS如果出現程序包無效:“CRX_HEADER_INVALID”。這個提示,請看下方的解決辦法鏈接。





          解決 程序包無效:“CRX_HEADER_INVALID” 方法的鏈接:https://blog.csdn.net/weixin_43606158/article/details/97517104

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

          更改this指向的方法及其區別

          seo達人

          今天給朋友們帶來更改this指向的三種方法,以及它們的區別:



          一:call用法

          window.color = 'red';

          document.color = 'yellow';

          var s1 = {color: 'blue'};

          function changeColor () {

          console.log(this.color);

          }

          changeColor.call() //不傳參數默認指向window

          changeColor.call(window) //指向window

          changeColor.call(document) //指向document

          changeColor.call(this) //構造函數的this如果打括號調用默認指向window

          changeColor.call(s1) //指向s1對象



          //例二:

          var Pet = {

          words: '...',

          speak: function (say) {

          console.log(say + '' + this.words)

          }

          }

          Pet.speak('123') //輸出123...

          var Dog = {

          words: 'WangWangWang'

          }

          Pet.speak.call(Dog,'123') //輸出123WangWangWang



          二:apply用法:

          window.number = 'one';

          document.number = 'two';

          var s1 = {number: 'three'};



          function changeNum() {

          console.log(this.number)

          }

          changeNum.apply(); //one

          changeNum.apply(window); //one

          changeNum.apply(document);//two

          changeNum.apply(this);//one

          changeNum.apply(s1);//three



          //例二:

          function Pet(words){

          this.words = words;

          this.speak = function(){

          console.log(this.words)

          }

          }

          function Dog(words){

          Pet.call(this,words);//結果wang

          // Pet.apply(this,arguments);//結果wang

          }

          var dog = new Dog('wang');

          dog.speak(); //wang



          apply與call的區別:

          接收的參數不同

          apply()方法接收倆個參數,一個是函數運行的作用域(this),另一個是參數數組。

          call()方法第一個參數和apply()方法的一樣,但是傳遞給函數的參數必須一 一列舉出來。

          語法:

          apply([thisObj [,argArray]]);

          調用一個對象的一個方法,另一個對象替換當前對象

          call([thisObj [,arg1[,arg2[…,argn]]]]);

          說明:

          如果thisObj是null或者undefined的時候,默認指向window。

          如果argArray不是一個有效數組或不是arguments對象,那么將導致一個TypeError,如果沒有提供argArray和thisObj任何一個參數,那么Global對象將用作thisObj。

          call方法可以用來代替另一個對象的一個方法,call方法可以將一個函數的對象上下文從初始的上下文改變為thisObj指定的新對象,如果沒有提供thisObj參數,那么Global對象被用于thisObj。



          三:bind的用法:

          var obj = {

          name: 'WuXiaoDi'

          }

          function printName() {

          console.log(this.name)

          }

          var wuXiaoDi = printName.bind(obj)

          console.log(wuXiaoDi) //function(){...}

          wuXiaoDi() //WuXiaoDi



          //例二:

          function fn(a, b, c) {

          console.log(a, b, c);

          }

          var fn1 = fn.bind(null, 'Dot');

          fn('A', 'B', 'C'); //A B C

          fn1('A', 'B', 'C');           // Dot A B

          fn1('B', 'C');                // Dot B C

          fn.call(null, 'Dot');      // Dot undefined undefined



          //例三:實現函數珂里化

          var add = function(x) {

          return function(y) {

          return x + y;

          };

          };

          var increment = add(1);

          var addTen = add(10);

          increment(2) //3

          addTen(2) //12



          小總結:

          Function.prototype.bind(thisArg) - - ES5



          能夠返回一個新函數,該新函數的主體與原函數主體一致,但當新函數被調用執行時,函數體中的this指向的是thisArg所表示的對象。



          Function.prototype.call(this.Arg,val1,val2, …)



          調用函數執行,在函數執行時將函數體中的this指向修改為thisArg所表示的對象



          val1, val2, … 表示傳遞給調用函數的實際參數列表



          Function.prototype.apply(thisArg, array|arguments)



          調用函數執行,在函數執行時將函數體中的this指向修改為thisArg所表示的對象,



          array|arguments 表示調用函數的參數列表,使用數組或類數組的格式



          區別:

          bind與call和apply的區別:

          返回值的區別:

          bind的返回值是一個函數,而call和apply是立即調用。

          參數使用的區別:

          bind與call一樣是從第二個參數開始將想要傳遞的參數一 一寫入。但call是把第二個及以后的參數作為fn方法的實參傳進去,而fn1方法的實參實則是在bind中參數的基礎上再往后排。

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

          Vue cli之全家桶搭建項目

          seo達人

          一、搭建cli

          1.事先安裝好cnpm(淘寶鏡像)



          npm install -g cnpm --registry=https://registry.npm.taobao.org

          1

          2.cnpm install -g vue-cli



          全局安裝vue腳手架工具。(下載一次就好)



          3.vue init webpack your_project_name



          創建一個腳手架項目(每次創建需要)



          eg:這時在命令行中有需要你填的信息{

          你的項目名;

          你的項目描述;

          還有你想是否下載的插件(y/n);

          }



          4.使用 npm run dev來運行項目



          就這樣,一個簡單的vue開發項目模板就這樣下載完成了。



          eg:

          i 是install 的簡寫。

          全局安裝依賴:



          cnpm i   依賴名

          1

          局部安裝依賴:



          cnpm i -D  依賴名

          1

          二、vue-router

          一般事先安裝模板時,已經安裝上了。

          可以查看package.json中。

          如果沒有安裝



          cnpm i -D vue-router

          1

          安裝好之后,在src目錄中會生成一個router目錄,里面放著index.js,

          一般有兩種配置

          第一種:



          import Vue from 'vue';

          import Router from 'vue-router';

          Vue.use(Router);

          export default new Router({

              routes: [

          // 一進入就顯示頁面

                  {

                      path: '/',

                      redirect: '/index'

                  },

                  {

                      path: '/',

                      component: pather => require(['../components/common/bodys.vue'], pather),

                      meta: { title: '主體' },

                      children:[

                          {

                              path: '/index',

                              component: pather => require(['../components/page/index.vue'], pather),

                              meta: { title: '系統首頁' }

                          },

                          {

                              path: '/biaoge',

                              component: pather => require(['../components/page/biaoge.vue'], pather),

                              meta: { title: '基礎表格' }

                          },

                          {

                              path: '/Tab',

                              component: pather => require(['../components/page/Tab.vue'], pather),

                              meta: { title: 'tab選項卡' }

                          },

                          {

                              path: '/jibenbiaodan',

                              component: pather => require(['../components/page/jibenbiaodan.vue'], pather),

                              meta: { title: '基本表單' }

                          },

                          {

                              path: '/fuwenben',

                              component: pather => require(['../components/page/fuwenben.vue'], pather),

                              meta: { title: '富文本編輯器' }

                          },

                          {

                              path: '/bianjiqi',

                              component: pather => require(['../components/page/bianjiqi.vue'], pather),

                              meta: { title: 'markdown編輯器' }    

                          },

                          {

                              path: '/shangchuan',

                              component: pather => require(['../components/page/shangchuan.vue'], pather),

                              meta: { title: '文件上傳' }   

                          },

                          {

                              path: '/scharts',

                              component: pather => require(['../components/page/scharts.vue'], pather),

                              meta: { title: 'schart圖表' }

                          },

                          {

                              path: '/tuozhuai',

                              component: pather => require(['../components/page/tuozhuai.vue'], pather),

                              meta: { title: '拖拽列表' }

                          },

                          {

                              path: '/quanxianceshi',

                              component: pather => require(['../components/page/quanxianceshi.vue'], pather),

                              meta: { title: '權限測試', permission: true }

                          }             

                      ]

                  },

                  {

                      path: '/login',

                      component: pather => require(['../components/page/login.vue'], pather)

                  },



                  {

                      path: '/cuowu404',

                      component: pather => require(['../components/page/cuowu404.vue'], pather)

                  },

                  {

                      path: '/cuowu403',

                      component: pather => require(['../components/page/cuowu403.vue'], pather)

                  },

                  {

                      path: '*',

                      redirect: '/404'

                  }

              ],

          // 去掉#號

          mode:"history"

          })





          第二種:



          import Vue from 'vue'

          import Router from 'vue-router'

          import HelloWorld from '@/components/HelloWorld'

          Vue.use(Router)



          export default new Router({

            routes: [

              {

                path: '/',

                name: 'HelloWorld',

                component: HelloWorld

              }

            ]

          })



          三、axios

          先安裝



          cnpm i -D axios

          1

          然后在main.js寫入



          import axios from 'axios'



          Vue.prototype.$axios = axios

          1

          2

          3

          這樣就可以在組件中使用axios 獲取數據了



              loadData(){

                      this.$axios.get(['
                          .then((response) => {

                              // success

                              console.log(response.data);

                          })

                          .catch((error) => {

                              //error

                              console.log(error);

                          })

                  },



          四、vuex

          1、安裝



          cnpm i -D vuex

          1

          2、然后需要手動創建一個文件夾store在src目錄當中,

          接著在store文件夾中創建store.js

          例:



          import Vue from 'vue'

          import Vuex from 'vuex'

          Vue.use(Vuex)



          export default new Vuex.Store({

            state: {

              count: 0

            },

            mutations: {

              increment: state => state.count++,

              decrement: state => state.count--,

            }

          })

          1

          2

          3

          4

          5

          6

          7

          8

          9

          10

          11

          12

          13

          3、然后在main.js引入注冊



          import Vuex from 'vuex'

          import store from './store/store'



          Vue.use(Vuex)



          new Vue({

            el: '#app',

            router,

            store,

            components: { App },

            template: '<App/>'

          })



          比如在headers.vue使用vuex



          <template>

              <div class="headers">

               <p>{{count}}</p>

               <button @click="increment">+</button>

               <button @click="decrement">-</button>

              </div>

          </template>

          <script>

          import { mapState } from 'vuex'

          export default {

            name: 'headers',

            data () {

              return {

                msg: 'Welcome to Your Vue.js App'

              }

            },

            methods: {

                  increment(){

                    this.$store.commit('increment')

                  },

                  decrement(){

                    this.$store.commit('decrement')

                  }

            },

              computed:{

                  count(){

                      return this.$store.state.count

                  },

              }



          }

          </script>

          <style scoped lang="scss" >

          </style>





          五、sass

          1、需要安裝sass

          (1)安裝node-sass

          (2)安裝sass-loader

          (3)安裝style-loader 有些人安裝的是 vue-style-loader 其實是一樣的!



          cnpm install node-sass --save-dev 

          cnpm install sass-loader --save-dev  

          cnpm install style-loader --save-dev

          1

          2

          3

          2、接著需要更改build文件夾下面的webpack.base.config.js



          'use strict'

          const path = require('path')

          const utils = require('./utils')

          const config = require('../config')

          const vueLoaderConfig = require('./vue-loader.conf')



          function resolve (dir) {

            return path.join(dirname, '..', dir)

          }







          module.exports = {

            context: path.resolve(
          dirname, '../'),

            entry: {

              app: './src/main.js'

            },

            output: {

              path: config.build.assetsRoot,

              filename: '[name].js',

              publicPath: process.env.NODE_ENV === 'production'

                ? config.build.assetsPublicPath

                : config.dev.assetsPublicPath

            },

            resolve: {

              extensions: ['.js', '.vue', '.json'],

              alias: {

                'vue$': 'vue/dist/vue.esm.js',

                '@': resolve('src'),

              }

            },

            module: {

              rules: [

                {

                  test: /.vue$/,

                  loader: 'vue-loader',

                  options: vueLoaderConfig

                },

                {

                  test: /.js$/,

                  loader: 'babel-loader',

                  include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')]

                },

                {

                  test: /.(png|jpe?g|gif|svg)(\?.)?$/,

                  loader: 'url-loader',

                  options: {

                    limit: 10000,

                    name: utils.assetsPath('img/[name].[hash:7].[ext]')

                  }

                },

                {

                  test: /.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.
          )?$/,

                  loader: 'url-loader',

                  options: {

                    limit: 10000,

                    name: utils.assetsPath('media/[name].[hash:7].[ext]')

                  }

                },

                {

                  test: /.(woff2?|eot|ttf|otf)(\?.*)?$/,

                  loader: 'url-loader',

                  options: {

                    limit: 10000,

                    name: utils.assetsPath('fonts/[name].[hash:7].[ext]')

                  }

                },

                { //從這一段上面是默認的!不用改!下面是沒有的需要你手動添加,相當于是編譯識別sass! 

                  test: /.scss$/,

                  loaders: ["style", "css", "sass"]

                }

              ]

            },

            node: {

              // prevent webpack from injecting useless setImmediate polyfill because Vue

              // source contains it (although only uses it if it's native).

              setImmediate: false,

              // prevent webpack from injecting mocks to Node native modules

              // that does not make sense for the client

              dgram: 'empty',

              fs: 'empty',

              net: 'empty',

              tls: 'empty',

              child_process: 'empty'

            }

          }





          3、在你需要使用sass的地方寫入即可



           <style lang="scss" scoped="" type="text/css"> 

           $primary-color: #333; 

             body {

                  color: $primary-color;

                 } 

          </style>



          六、vue UI庫

          這里已著名的Element組件庫為例

          https://element.eleme.cn/#/zh-CN/component/carousel



          1、安裝



          npm i element-ui -S

          1

          2、使用

          在main.js寫入



          import ElementUI from 'element-ui'

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



          Vue.use(ElementUI)

          1

          2

          3

          4

          3、然后在組件使用就可以了

          例:輪播圖



          <template>

            <el-carousel indicator-position="outside">

              <el-carousel-item v-for="item in 4" :key="item">

                <h3>{{ item }}</h3>

              </el-carousel-item>

            </el-carousel>

          </template>



          <style>

            .el-carouselitem h3 {

              color: #475669;

              font-size: 18px;

              opacity: 0.75;

              line-height: 300px;

              margin: 0;

            }

            

            .el-carousel
          item:nth-child(2n) {

              background-color: #99a9bf;

            }

            

            .el-carousel__item:nth-child(2n+1) {

              background-color: #d3dce6;

            }

          </style>

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

          Java中this關鍵字的詳解

          seo達人

          在java的學習中,當接觸到類這一章的時候,就會避免不了的接觸到this關鍵字。



          首先,this關鍵字指向的是當前對象的引用



          作用:

                       this.屬性名稱                

                             指的是訪問類中的成員變量,用來區分成員變量和局部變量(重名問題)



                        



          class Test_08{

          public static void main(String [] args){

          //調用無參構造函數,

          Person p1 = new Person();

          p1.setAge(20);

          p1.setName("張三");

          p1.setGender("男");

          System.out.println(""+p1.getName()+" 今年"+p1.getAge()+"歲 性別為:"+p1.getGender());

          }



          }

          class Person{

          private String name;

          private int age;

          private String gender;

          Person(){}

          Person(String name,int age,String gender){

          this.name = name;

          this.age = age;

          this.gender = gender;

          }

          public void setName(String name){

          name = name;

          }

          public String getName(){

          return name;

          }

          public void setAge(int age){

          age = age;

          }

          public int getAge(){

          return age;

          }

          public void setGender(String gender){

          gender = gender;

          }

          public String getGender(){

          return gender;

          }

          }

           







          對Test_08運行后發現,調用的set方法并沒有對 對象中的變量進行賦值,是因為,傳入的參數變量名與類中屬性變量名重復,因此我們在set方法和有參構造方法中加上了this.類屬性名稱,這樣就可以完成對 對象變量的賦值。如下圖:







                       this.方法名稱              

                                          用來訪問本類的成員方法



                        this();                              

                                                              訪問本類的構造方法



                                                              ()中可以有參數的 如果有參數 就是調用指定的有參構造

                     注意事項:

                                      1.this() 不能使用在普通方法中 只能寫在構造方法中

                                      2.必須是構造方法中的第一條語句



          例如,當我們把this()放在有參構造函數的末尾時,例如用this("哈哈");我們先不管語法是否有錯誤,試著按照程序的運行來判斷一下結果,我們可以看出,當在創建對象時,假定調用含有this(“哈哈”)的構造函數,則剛開始存放的值,會被this(“哈哈”)調用的只含有一個參數的構造函數覆蓋,也就是說,最后的name會變成“哈哈”,這是與我們的初衷相違背的,而且運行結果也是報錯,



          當我們換到構造方法的第一句時,則不會有這種錯誤,因為它并不會影響到后面name的賦值。







           







           



          我們接下來把this語句放在構造函數的第一句位置,



          就不會有報錯







           

          ————————————————

          版權聲明:本文為CSDN博主「BetterShon」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。

          原文鏈接:https://blog.csdn.net/weixin_42386014/article/details/81138684

          移動端實現導航的左右滑動

          seo達人

          實現導航的左右滑動類似于騰訊新聞,網易等導航,一下貼上代碼:



          <!doctype html>



          <html>

          <head>

          <meta charset="UTF-8">

          <title>Untitled Document</title>

          <meta name="viewport" content="width=device-width, initial-scale=1.0">

          </head>

          <style>

          body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,form,input,p,th,td,table,textarea,select{margin:0;padding:0;}

          h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal;}

          th,em{font-style:normal;font-weight:normal;}

          ol,ul{list-style:none;}

          table{border-collapse:collapse;border-spacing:0;}

          img,a img{border:0;}

          body{font:12px 'Microsoft YaHei',Arial;color:#666;background-color:#eee;}

          .nav{width:100%;overflow:hidden;margin:0 auto;height:35px;position:relative; line-height:35px;background-color:#000;}

          .nav ul{position:absolute;left:0;top:0;width:640px;z-index:1;}

          .nav ul li{width:80px; float:left; overflow:hidden;}

          .nav a{color:#fff;width:100%; display:block; text-decoration:none; text-align:center;}

          </style>





          <body>









          <div class="nav" id="nav">

          <ul>

          <li><a href="#">菜單1</a></li>

          <li><a href="#">菜單2</a></li>

          <li><a href="#">菜單3</a></li>

          <li><a href="#">菜單4</a></li>

          <li><a href="#">菜單5</a></li>

          <li><a href="#">菜單6</a></li>

          <li><a href="#">菜單7</a></li>

          <li><a href="#">菜單8</a></li>

          <li><a href="#">菜單9</a></li>

          <li><a href="#">菜單10</a></li>

          </ul>

          </div>





















          <script>

          window.Swipe = function(b, a) {

              if (!b) {

                  return null

              }

              this.options = a || {};

              this.index = this.options.startSlide || 0;//開始的導航頁的第幾屏

              this.speed = this.options.speed || 300;//速度

          this.lwidth = this.options.width || 80;//導航li寬度

              this.delay = this.options.auto || 0;//自動滾動菜單速度0為不自動滾動

              this.container = b;//在那個容器內

              this.element = this.container.children[0];//

              

              this.setup();

             

              if (this.delay != 0) {

                  this.begin();

              }

              if (this.element.addEventListener) {

                  this.element.addEventListener("touchstart", this, false);

                  this.element.addEventListener("touchmove", this, false);

                  this.element.addEventListener("touchend", this, false);

                  this.element.addEventListener("touchcancel", this, false);

                  this.element.addEventListener("webkitTransitionEnd", this, false);

                  this.element.addEventListener("msTransitionEnd", this, false);

                  this.element.addEventListener("oTransitionEnd", this, false);

                  this.element.addEventListener("transitionend", this, false);//監聽過度動畫是否結束

                  window.addEventListener("resize", this, false)

              }

          };

          Swipe.prototype = {

          //設置其基本樣式

              setup: function() {

                  this.slides = this.element.children;

                  this.width = Math.ceil(("getBoundingClientRect" in this.container) ? this.container.getBoundingClientRect().width: this.container.offsetWidth);

                  if (!this.width||this.slides.length < 1) {//沒有子節點,獲取不到屏幕寬度均返回

                      return null

                  }

                  this.element.style.width = Math.ceil(this.slides.length this.lwidth) + "px";

                  var a = this.slides.length;

                  while (a--) {

                      var b = this.slides[a];

                      b.style.width = this.lwidth + "px";

                  }

                  this.slide(this.index, 0);

              },

              slide: function(a, c) {

                  var b = this.element.style;

                  if (c == undefined) {

                      c = this.speed

                  }

                  //過度效果需要花費時間

                  b.webkitTransitionDuration = b.MozTransitionDuration = b.msTransitionDuration = b.OTransitionDuration = b.transitionDuration = c + "ms";

                  this.index = a

                  //console.log(a
          this.width,Math.ceil((this.slides.lengththis.lwidth)/this.width));

                  if(a
          this.width>(Math.ceil((this.slides.lengththis.lwidth)/this.width)-1)this.width){

          //          b.MozTransform = b.webkitTransform = "translate3d(" + -((Math.ceil((this.slides.lengththis.lwidth)/this.width)-1) this.width) + "px,0,0)";

          //       b.msTransform = b.OTransform = "translateX(" + -((Math.ceil((this.slides.lengththis.lwidth)/this.width)-1) this.width) + "px)";

                  return false;

                  }

                  else{

                  b.MozTransform = b.webkitTransform = "translate3d(" + -(a this.width) + "px,0,0)";

                b.msTransform = b.OTransform = "translateX(" + -(a
          this.width) + "px)";

                  }

                 

              },

              getPos: function() {

                  return this.index

              },

              //前一個,

              prev: function(a) {

                  this.delay = a || 0;

                  clearTimeout(this.interval);

                 // console.log(this.index);

                  if (this.index) {

                      this.slide(this.index - 1, this.speed)

                      //console.log( this.index);

                  } else {

                      this.slide(this.length - 1, this.speed)

                  }

              },

              //后一個

              next: function(a) {

                  this.delay = a || 0;

                  clearTimeout(this.interval);

                  if (this.index < this.length - 1) {

                      this.slide(this.index + 1, this.speed)

                  } else {

                      this.slide(0, this.speed)

                  }

              },

              begin: function() {

                  var a = this;

                  console.log(a);

                  this.interval = (this.delay) ? setTimeout(function() {

                      a.next(a.delay)

                  },

                  this.delay) : 0

              },

              stop: function() {

                  this.delay = 0;

                  clearTimeout(this.interval)

              },

              resume: function() {

                  this.delay = this.options.auto || 0;

                  this.begin()

              },

              handleEvent: function(a) {

                  switch (a.type) {

                  case "touchstart":

                      this.onTouchStart(a);

                      break;

                  case "touchmove":

                      this.onTouchMove(a);

                      break;

                  case "touchcancel":

                  case "touchend":

                      this.onTouchEnd(a);

                      break;

                  case "webkitTransitionEnd":

                  case "msTransitionEnd":

                  case "oTransitionEnd":

                  case "transitionend":

                      this.transitionEnd(a);

                      break;

                  case "resize":

                      this.setup();

                      break

                  }

              },

              transitionEnd: function(a) {

                  if (this.delay) {

                      this.begin()

                  }

                  

              },

              onTouchStart: function(a) {

                  this.start = {

                      pageX: a.touches[0].pageX,

                      pageY: a.touches[0].pageY,

                      time: Number(new Date())

                      

                  };

                 // console.log(this.start)

                  this.isScrolling = undefined;

                  this.deltaX = 0;

                  this.element.style.MozTransitionDuration = this.element.style.webkitTransitionDuration = 0;

                  a.stopPropagation()

              },

              onTouchMove: function(a) {

                  if (a.touches.length > 1 || a.scale && a.scale !== 1) {

                      return

                  }

                  this.deltaX = a.touches[0].pageX - this.start.pageX;

                  if (typeof this.isScrolling == "undefined") {

                  //判斷是橫向還是樹向滑動

                      this.isScrolling = !!(this.isScrolling || Math.abs(this.deltaX) < Math.abs(a.touches[0].pageY - this.start.pageY))

                  }

                  if (!this.isScrolling) {

                      a.preventDefault();

                      clearTimeout(this.interval);

                      this.deltaX = this.deltaX / ((!this.index && this.deltaX > 0 || this.index == this.length - 1 && this.deltaX < 0) ? (Math.abs(this.deltaX) / this.width + 1) : 1);

                      this.element.style.MozTransform = this.element.style.webkitTransform = "translate3d(" + (this.deltaX - this.index * this.width) + "px,0,0)";

                      a.stopPropagation()

                  }

              },

              onTouchEnd: function(c) {

                  var b = Number(new Date()) - this.start.time < 250 && Math.abs(this.deltaX) > 20 || Math.abs(this.deltaX) > this.width / 2,

                  a = !this.index && this.deltaX > 0 || this.index == this.length - 1 && this.deltaX < 0;

                  if (!this.isScrolling) {

                      this.slide(this.index + (b && !a ? (this.deltaX < 0 ? 1: -1) : 0), this.speed)

                  }

                  c.stopPropagation()

              }

          };





          //開始調用插件





          var slider=new Swipe(document.getElementById('nav'),{speed:500,auto:0,width:100,col:4,});

          </script>

          </body>

          </html>

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

          vue移動端 實現手機左右滑動入場動畫

          seo達人

          app.vue



          <template>

            <div id="app">

              <transition :name="transitionName">

                <keep-alive >

                  <router-view v-if="$route.meta.keepAlive" class="Router"></router-view>

                </keep-alive>

              </transition >

              <transition :name="transitionName">

                <router-view v-if="!$route.meta.keepAlive"  class="Router"></router-view>

              </transition >

              <Play></Play>

            </div>

          </template>

          <script>import Play from './components/play'

          export default {

            name: 'App',

            data () {

              return {

                transitionName: 'slide-left'

              }

            },

            watch: {

              '$route' (to, from) {

                // 切換動畫

                let isBack = this.$router.isBack // 監聽路由變化時的狀態為前進還是后退

                if (isBack === true) {

                  this.transitionName = 'slide-right'

                  // from.meta.keepAlive = false

                  // to.meta.keepAlive = true

                } else {

                  // from.meta.keepAlive = true

                  // to.meta.keepAlive = false

                  // this.transitionName = 'slide-left'

                  if (this.$route.path.split('/').length < 3) {

                    this.transitionName = 'slide-fade'

                  } else {

                    this.transitionName = 'slide-left'

                  }

                }

                this.$router.isBack = false

              }

            },

            components: {

              Play

            }

          }

          </script>



          <style>

          .Router {

            font-family: Roboto, Lato, sans-serif;

            position: absolute;

            width: 100%;

            height: 100%;

            padding-bottom: 60px;

            transition: all .377s ease;

            box-sizing: border-box;

            overflow: auto;

          }

          .slide-left-enter,

          .slide-right-leave-active {

            opacity: 0;

            -webkit-transform: translate(100%, 0);

            transform: translate(100%, 0);

          }



          .slide-left-leave-active,

          .slide-right-enter {

            opacity: 0;

            -webkit-transform: translate(-100%, 0);

            transform: translate(-100% 0);

          }

          .ovf {

            overflow: hidden;

          }

          .center {

            width: 95%;

            margin: 0 auto;

            overflow-y: hidden;

          }

          li {

            list-style: none;

          }

          </style>



          路由配置



              {

                path: '/playListDetail/:id',

                name: 'playListDetail',

                component: pather => require(['../components/playListDetail.vue'], pather),

                meta: {

                  title: '歌單詳情',

                  keepAlive: true,

                  isBack: false

                }

              },



          返回事件



           back () {

                this.$router.go(-1)

                this.$router.isBack = true

              }

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

          提高JS性能的12個技巧

          seo達人

          在我們開發的過程中,應該始終考慮性能。而本文列舉了有效提高系統性能的12個方法,如果朋友們有更多的技巧請在吳小迪的博客下方評論,謝謝。



          性能是創建網頁或應用程序時最重要的一個方面。沒有人想要應用程序崩潰或者網頁無法加載,或者用戶的等待時間很長。根據Kissmetrics,47%的訪問者希望網站在不到2秒的時間內加載,如果加載過程需要3秒以上,則在40%的訪問者會離開網站。



          考慮到以上這些數字,你在創建Web應用程序時應始終考慮性能。為了幫助你開始,以下提供了有效提高應用程序性能的12種方法:



          一:在瀏覽器中緩存

          要這樣做有倆種選擇。第一種是使用JavaScript Cache API,我們可以安裝service worker來使用它。第二種是使用HTTP協議緩存。



          訪問某個對象通常要用腳本。通過把重復訪問的對象存儲在用戶定義的變量中,以及在后續對該對象的引用中使用變量,可以立即實現性能的提升。



          二:定義執行的上下文

          為了有效地衡量你在程序中加入的任何改進,你必須創建一組定義良好的環境,以便測試代碼性能。



          對所有JavaScript引擎的所有版本進行性能測試和優化實際上是不可行的。但是,在單一的環境中進行測試并非一個好習慣,因為你可能會得到片面的結果。因此,建立多個定義良好的環境并測試代碼是否有效非常重要。



          三:刪除未使用的JavaScript

          此步驟不僅會縮短傳輸時間,還會縮短瀏覽器分析和編譯代碼所需的時間。為此,你必須考慮以下幾點:



          如果你檢測到一個用戶未使用的功能,最好刪除所有與之相關的JavaScript代碼,這樣網站的加載速度會更快,用戶也有更好的體驗。

          還有可能,你錯誤地加入了一個并不需要的庫,或者你有依賴項,這些依賴項提供的功能在所有瀏覽器中原本就有,那么你無需再增加多余的代碼。

          四:避免使用太多內存

          你應該始終給內存加一條限制,那就是只有絕對必須的內容才能使用內存,因為你無法知道運行應用程序的設備到底需要多少內存。只要你的代碼要求瀏覽器保留新的內存,瀏覽器的垃圾收集器就會被執行,并停止JavaScript的運行。如果經常發生這種情況,頁面將變慢。



          五:推遲不必要的JS加載

          用戶希望頁面快速加載,但并非所有函數都需要在頁面的初始加載時就可用。如果用戶必須執行某個操作才能執行某個函數(例如,通過單擊某個元素或更改選項卡),那么你可以將該函數的加載推遲到初始頁面加載之后。



          通過這種方式,你可以避免加載和編譯那些會延遲頁面初始顯示的 JavaScript 代碼。頁面完全加載后,我們可以再開始加載這些功能,以便它們在用戶開始交互時立即可用。在 RAIL 模型中,Google 建議將此延遲加載以 50 毫秒為單位進行,這樣就不會影響用戶與頁面的交互。



          六:避免內存泄漏

          如果內存正在泄漏,則加載的頁面將保留越來越多的內存,并最終占用設備的所有可用內存并嚴重影響性能。你可能見過此類故障(并且可能對此類故障感到懊惱),例如在帶有輪播或圖像滑動條的頁面上。



          在 Chrome 開發者工具中,你可以通過在“性能”標簽中記錄時間線來分析你的網站是否存在內存泄漏。通常,內存泄漏的原因是,你從頁面中刪除了 DOM,但有一些變量還在引用這些 DOM,因此,垃圾收集器無法消除它們。



          七:適當的使用Web worker

          當你執行耗時很長的代碼時,請使用 Web worker。根據 Mozilla 開發人員網絡 (MDN) 文檔:“Web Worker 可以在與 Web 應用程序的主執行線程分開的后臺線程中運行腳本操作。這樣做的好處是你可以在一個單獨的線程中執行耗時又費力的的處理,同時讓主(通常為 UI)線程運行而不被阻塞或減慢?!?br />


          Web worker 允許代碼執行處理器密集型計算,而不阻塞用戶界面線程。Web Worker 允許你生成新線程并將工作委托給這些線程以獲得的性能。這樣,通常會阻礙其他任務且需要長時間運行的任務將被傳遞給 worker,從而讓主線程可以在無阻礙的情況下運行。



          八:適當將DOM元素保存在局部變量中

          訪問 DOM 會很慢。如果要多次讀取某元素的內容,最好將其保存在局部變量中。但記住重要的是,如果稍后你會刪除 DOM 的值,則應將變量設置為“null”,不然會導致內存泄漏。



          九:優先訪問局部變量

          JavaScript 首先搜索以查看變量是否存在于本地,然后才在更高級別的作用域內逐步搜索到全局變量為止。將變量保存在本地作用域內能讓 JavaScript 更快地訪問它們。



          局部變量是基于最具體的作用域的,并且可能會穿過多個級別的作用域,因此查找這一動作可能導致出現通用的查詢。在一個它前面沒有變量聲明的局部變量中定義函數作用域時,需要在每個變量之前加上 let 或 const,以便定義當前作用域,防止查找并加速代碼執行。



          十:避免使用全局變量

          因為腳本引擎在從函數或其他作用域內引用全局變量時需要逐一查看作用域,所以當本地作用域丟失時,該變量將被銷毀。如果全局作用域中的變量無法在腳本的生命周期內持續存在,則性能將得到改善。



          十一:實施一些優化方案

          始終使用計算復雜度的算法和最佳的數據結構來解決任務。



          重寫算法以獲得相同的結果和更少的計算。



          避免遞歸調用。



          給重復的函數加入變量、計算和調用。



          分解和簡化數學公式。



          使用搜索數組:用它們來獲取基于另一個的值,而不是使用 switch/case 語句。



          使條件總是更有可能為真,以更好地利用處理器的推測執行。



          如果可以,請使用位級運算符替換某些操作,因為這些運算符的處理周期較短。



          十二:使用工具檢測問題

          Lighthouse 是一個很好的網頁性能工具,它可以幫助你審核性能、可訪問性、最佳實踐和 SEO。谷歌 PageSpeed 旨在幫助開發人員了解網站的性能優化和潛在可改進的方面。這些組件旨在識別網站是否符合 Google Web 性能最佳實踐,以及將調整過程自動化。



          在 Chrome 中,你還可以使用主菜單中的“更多工具”選項來查看每個選項卡使用的內存和 CPU。對于更高級的分析,你可以使用 Firefox 或 Chrome 中的開發人員工具“性能”視圖來分析不同的指標,例如:





          devtools 的性能分析允許你在加載頁面時模擬 CPU 消耗、網絡和其他指標,以便識別和修復問題。





          為了更深入地了解,建議你使用 JavaScript Navigation Timing API,它允許你詳細測量代碼的每個部分從編程本身中獲取的內容。



          對于基于 Node.js 構建的應用程序,NodeSource Platform 也是一種非常好、影響低的方式,它可以在非常精細的級別上探索應用程序性能。



          全面的 Node.js 指標可幫助你識別內存泄漏源或其他性能問題,并更快地解決這些問題。



          最后的說明在代碼的可讀性和優化之間保持平衡很重要。代碼由計算機解釋,但我們需要確保代碼將來可以由我們自己或其他人維護,因此它們需要易于理解。



          請記?。簯冀K考慮性能,但不應將性能凌駕于錯誤檢測和功能添加之上。

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

          日歷

          鏈接

          個人資料

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

          存檔

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