Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 精品欧美在线观看视频,亚洲高清在线观看看片,国产人妖chinats

          整合營(yíng)銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          一個(gè)vue頁(yè)面復(fù)用方案

          問(wèn)大家一個(gè)問(wèn)題,曾經(jīng)的你是否也遇到過(guò),一個(gè)項(xiàng)目中有好幾個(gè)頁(yè)面長(zhǎng)得基本相同,但又差那么一點(diǎn),想用 vue extends 繼承它又不能按需繼承html模板部分,恰好 B 頁(yè)面需要用的 A 頁(yè)面 80% 的模板,剩下的 20% 由 B 頁(yè)面自定義,舉個(gè)栗子:

          我們假設(shè)這是兩個(gè)頁(yè)面,B頁(yè)面比A頁(yè)面多了個(gè)p標(biāo)簽,剩余的東西都一樣,難道僅僅是因?yàn)檫@一個(gè) p標(biāo)簽就要重新寫(xiě)一份模板嗎?相信大部分伙伴解決方式是把公共部分抽成一個(gè)組件來(lái)用,這是一個(gè)好的做法。沒(méi)錯(cuò),但是來(lái)了,老板讓你在 標(biāo)題1、標(biāo)題2下面分別插入一段內(nèi)容,這會(huì)兒你是不是頭大了?難道只能重寫(xiě)一份了嗎?當(dāng)然不是,來(lái)開(kāi)始我們的填坑之路~(當(dāng)你的業(yè)務(wù)能用插槽或者組件抽離的方式固然更好,以下內(nèi)容僅針對(duì)當(dāng)你項(xiàng)目達(dá)到一定體量,vue老三套難以處理的情況下采用)

          準(zhǔn)備工作

          準(zhǔn)備以下工具包:

          • node-html-parser: 將html生成dom樹(shù) 官網(wǎng)
          npm install --save node-html-parser
          


          思路

          1. 子頁(yè)面提供繼承的父頁(yè)面的路徑,如下:
          <template extend="./xxx.vue">
          </template>
          


          1. 子頁(yè)面需要通過(guò)一個(gè)自定義標(biāo)簽(假設(shè)是 extend)的方式,來(lái)決定如何拓展父頁(yè)面,如下就應(yīng)該是一個(gè)替換的操作,它最少應(yīng)該具備拓展類型 type 與目標(biāo)節(jié)點(diǎn) target 屬性。
          <template extend="./xxx.vue">
            <div>
              <extend type="replace" target="#div_1">
                <a>通過(guò)replace替換掉父頁(yè)面下id為div_1的元素 </a>
              </extend>
            </div>
          </template>
          


          最終它生成的應(yīng)該是除了 id 為 div_1元素被<a>通過(guò)replace替換掉父頁(yè)面下id為div_1的元素 </a>替換掉之外,剩下的全部和xxx.vue一樣的頁(yè)面。

          梳理需求點(diǎn)

          子頁(yè)面繼承父頁(yè)面既可以完全繼承,也可以通過(guò)某種方式以父頁(yè)面為基板,對(duì)其進(jìn)行增、刪、改。方便理解,我們先定義一個(gè)自定義標(biāo)簽 extend,子頁(yè)面通過(guò)該標(biāo)簽對(duì)其繼承的頁(yè)面操刀動(dòng)手術(shù),為了實(shí)現(xiàn)一個(gè)比較完善的繼承拓展,extend 標(biāo)簽需要具備以下屬性:

          Extend Attributes

          參數(shù)

          說(shuō)明

          類型

          可選值

          type

          指定擴(kuò)展類型

          string

          insert(插入)、replace(替換)、remove(移除)、append(向子集追加)

          position

          指定插入的位置(僅在 type 取值 insert 時(shí)生效)

          string

          before(目標(biāo)前)、after(目標(biāo)后)

          指定插入的位置(僅在 type 取值 append 時(shí)生效,用于指定插入成為第幾個(gè)子節(jié)點(diǎn))

          number

          -

          target

          指定擴(kuò)展的目標(biāo)

          string


          實(shí)現(xiàn)需求

          新建一個(gè)vue2的項(xiàng)目,項(xiàng)目結(jié)構(gòu)如下:

          我們的繼承拓展通過(guò)自定義loader在編譯的時(shí)候?qū)崿F(xiàn),進(jìn)入到src/loader/index.js

          const extend = require('./extend');
          module.exports = function (source) {
               // 當(dāng)前模塊目錄
               const resourcePath = this.resourcePath;
               // 合并
               const result = new extend(source, resourcePath).mergePage();
               // console.log('result :>> ', result);
               // 返回合并后的內(nèi)容
               this.callback(null, result);
          };
          


          實(shí)現(xiàn)繼承拓展主要邏輯代碼:src/loader/extend.js

          const parser = require('node-html-parser');
          const fs = require('fs');
          const pathFile = require('path');
          /**
           * 通過(guò)node-html-parser解析頁(yè)面文件重組模板
           * @param {String} source 頁(yè)面內(nèi)容
           * @param {String} resourcePath 頁(yè)面目錄
           * @returns {String} 重組后的文件內(nèi)容
           */
          class Extend {
              constructor(source, resourcePath) {
                  this.source = source;
                  this.resourcePath = resourcePath;
              }
              // 合并頁(yè)面
              mergePage() {
                  // 通過(guò)node-html-parser解析模板文件
                  const pageAst = parser.parse(this.source).removeWhitespace();
                  // 獲取template標(biāo)簽extend屬性值
                  const extendPath = pageAst.querySelector('template').getAttribute('extend');
                  if (!extendPath) {
                      return pageAst.toString();
                  }
                  // extendPath文件內(nèi)容
                  const extendContent = fs.readFileSync(pathFile.resolve(pathFile.dirname(this.resourcePath), extendPath), 'utf-8');
                  // extendContent文件解析
                  const extendAst = parser.parse(extendContent).removeWhitespace();
                  // 獲取頁(yè)面文件標(biāo)簽為extend的元素
                  const extendElements = pageAst.querySelectorAll('extend');
          
                  extendElements.forEach((el) => {
                      // 獲取對(duì)應(yīng)屬性值
                      const type = el.getAttribute('type');
                      const target = el.getAttribute('target');
                      const position = parseInt(el.getAttribute('position'));
          
                      // 匹配模板符合target的元素
                      let templateElements = extendAst.querySelectorAll(target);
          
                      // type屬性為insert
                      if (type === 'insert') {
                          templateElements.forEach((tel) => {
                              // 通過(guò)position屬性判斷插入位置 默認(rèn)為after
                              if (position === 'before') {
                                  el.childNodes.forEach((child) => {
                                      tel.insertAdjacentHTML('beforebegin', child.toString());
                                  });
                              } else {
                                  el.childNodes.forEach((child) => {
                                      tel.insertAdjacentHTML('afterend', child.toString());
                                  });
                              }
                          });
                      }
                      // type屬性為append
                      if (type === 'append') {
                          templateElements.forEach((tel) => {
                             const elNodes = el.childNodes;
                             let tlNodes = tel.childNodes;
                             const len = tlNodes.filter((node) => node.nodeType === 1 || node.nodeType === 3).length;
                              // 未傳position屬性或不為數(shù)字、大于len、小于0時(shí)默認(rèn)插入到最后
                              if(isNaN(position) || position > len || position <= 0){
                                  elNodes.forEach((child) => {
                                      tel.insertAdjacentHTML('beforeend', child.toString());
                                  });
                              }else {
                                  tlNodes =  [...tlNodes.slice(0, position-1), ...elNodes, ...tlNodes.slice(position-1)]
                                  tel.set_content(tlNodes);
                              }
                          });
                      }
                      // type屬性為replace
                      if (type === 'replace') {
                          templateElements.forEach((tel) => {
                              tel.replaceWith(...el.childNodes);
                          });
                      }
                      // type屬性為remove
                      if (type === 'remove') {
                          templateElements.forEach((tel) => {
                              tel.remove();
                          });
                      }
                  });
                  // 重組文件內(nèi)容
                  const template = extendAst.querySelector('template').toString();
                  const script = pageAst.querySelector('script').toString();
                  const style = extendAst.querySelector('style').toString() + pageAst.querySelector('style').toString() 
                  return`${template}${script}${style}`
              }
          
          }
          module.exports = Extend;
          


          好的,自定義loader已經(jīng)編寫(xiě)完成,在vue.config.js里面配置好我們的loader

          const { defineConfig } = require('@vue/cli-service')
          module.exports = defineConfig({
            configureWebpack: {
              module: {
                rules: [
                  {
                    test: /\.vue$/,
                    use: [
                      {
                        loader: require.resolve('./src/loader'),
                      },
                    ],
                  },
                ],
              },
            },
          })
          
          


          接下來(lái)我們嘗試編寫(xiě)A頁(yè)面和B頁(yè)面:

          A.vue:

          <template>
            <div class="template">
                <div id="div_1" class="div">父頁(yè)面的div_1</div>
                <div id="div_2" class="div">父頁(yè)面的div_2</div>
                <div id="div_3" class="div">父頁(yè)面的div_3</div>
                <div id="div_4" class="div">父頁(yè)面的div_4</div>
                <div id="div_5" class="div">父頁(yè)面的div_5</div>
                <div id="div_6" class="div">父頁(yè)面的div_6</div>
                <div id="div_7" class="div">父頁(yè)面的div_7</div>
                <div id="div_8" class="div">父頁(yè)面的div_8</div>
            </div>
          </template>
          <script>
          export default {
            name: 'COM_A',
            props: {
              msg: String
            }
          }
          </script>
          <style scoped>
          .div {
            color: #42b983;
            font-size: 1.5em;
            margin: 0.5em;
            padding: 0.5em;
            border: 2px solid #42b983; 
            border-radius:  0.2em;
          }
          </style>
          


          B.vue:

          <template extend="./A.vue">
            <div>
              <extend type="insert" target="#div_1" position="after">
                <div id="div_child" class="div">子頁(yè)面的div_5</div>
              </extend>
              <extend type="append" target="#div_3" position="2">
                <a> 子頁(yè)面通過(guò)append插入的超鏈接 </a>
              </extend>
            </div>
          </template>
          <script>
          import A from './A.vue'
          export default {
            name: 'COM_B',
            extends: A,//繼承業(yè)務(wù)邏輯代碼
            props: {
              msg: String
            }
          }
          </script>
          <style scoped>
          #div_child {
            color: #d68924;
            font-size: 1.5em;
            margin: 0.5em;
            padding: 0.5em;
            border: 2px solid #d68924;
          }
          a {
            color: blue;
            font-size: 0.7em;
          }
          </style>
          


          我們?cè)贏pp.vue下引入B.vue

          <template>
            <div id="app">
              <B/>
            </div>
          </template>
          <script>
          import B from './components/B.vue'
          export default {
            name: 'App',
            components: {
              B
            }
          }
          </script>
          <style>
          #app {
            font-family: Avenir, Helvetica, Arial, sans-serif;
            -webkit-font-smoothing: antialiased;
            -moz-osx-font-smoothing: grayscale;
            text-align: center;
            color: #2c3e50;
            margin-top: 60px;
          }
          </style>
          


          當(dāng)我們執(zhí)行編譯的時(shí)候,實(shí)際上B.vue的編譯結(jié)果如下:

          <template>
            <div class="template">
              <div id="div_1" class="div">父頁(yè)面的div_1</div>
              <div id="div_child" class="div">子頁(yè)面的div_5</div>
              <div id="div_2" class="div">父頁(yè)面的div_2</div>
              <div id="div_3" class="div">
                父頁(yè)面的div_3
                <a> 子頁(yè)面通過(guò)append插入的超鏈接 </a>
              </div>
              <div id="div_4" class="div">父頁(yè)面的div_4</div>
              <div id="div_5" class="div">父頁(yè)面的div_5</div>
              <div id="div_6" class="div">父頁(yè)面的div_6</div>
              <div id="div_7" class="div">父頁(yè)面的div_7</div>
              <div id="div_8" class="div">父頁(yè)面的div_8</div>
            </div>
          </template>
          <script>
          import A from './A.vue'
          export default {
            name: 'COM_B',
            extends: A,//繼承業(yè)務(wù)邏輯代碼
            props: {
              msg: String
            }
          }
          </script>
          <style scoped>
          .div {
            color: #42b983;
            font-size: 1.5em;
            margin: 0.5em;
            padding: 0.5em;
            border: 2px solid #42b983;
            border-radius: 0.2em;
          }
          </style>
          <style scoped>
          #div_child {
            color: #d68924;
            font-size: 1.5em;
            margin: 0.5em;
            padding: 0.5em;
            border: 2px solid #d68924;
          }
          
          a {
            color: blue;
            font-size: 0.7em;
          }
          </style>
          


          注意我們?cè)贐.vue使用了extends繼承了組件A,這里是為了能復(fù)用業(yè)務(wù)邏輯代碼,最后我們運(yùn)行代碼,頁(yè)面輸出為:

          結(jié)語(yǔ)

          在真實(shí)的項(xiàng)目當(dāng)中,我們遇到大量重復(fù)的頁(yè)面但是又有小區(qū)別的頁(yè)面,是可以通過(guò)這種方式減少我們的代碼量,當(dāng)然也許有更好的辦法,也希望大伙能提出寶貴的建議。

          最后引用一下 @XivLaw 老哥的評(píng)論:有很多人說(shuō)通過(guò)cv就能解決,但是當(dāng)你的業(yè)務(wù)有成千上萬(wàn)個(gè)頁(yè)面是趨同,并且具有相同的基本功能,當(dāng)界面需要統(tǒng)一調(diào)整或者需要進(jìn)行ui統(tǒng)一管控的時(shí)候,cv就成了你的累贅了。 也有朋友說(shuō)通過(guò)組件化和插槽解決,組件化是一個(gè)不錯(cuò)的方案,但是當(dāng)成千上萬(wàn)個(gè)趨同的界面存在時(shí),插槽并一定能覆蓋所有的業(yè)務(wù)定制化。 使不使用這種方式,主要看你的業(yè)務(wù)。

          直白一點(diǎn)說(shuō)就是:我現(xiàn)在有一千個(gè)頁(yè)面幾乎一樣,有的頁(yè)面是頭部多一點(diǎn)東西,有的是底部,有的是某個(gè)按鈕旁邊多一個(gè)按鈕,有的是輸入框之間多個(gè)輸入框,ui或者界面或者同時(shí)需要添加固定功能,需要調(diào)整的時(shí)候,這一千個(gè)頁(yè)面要怎么調(diào)?


          作者:小小小小_柏
          鏈接:https://juejin.cn/post/7347973138787467274

          于經(jīng)常需要處理PDF文件的用戶來(lái)說(shuō),合并多個(gè)PDF文件是一項(xiàng)重要且經(jīng)常使用的操作技能。為了更好地保存、管理和使用這些文件,他們希望能夠很容易地將多個(gè)PDF文件合并成一個(gè)。同時(shí),他們也希望合并后的PDF文件能夠方便地發(fā)送給他人,從而提高工作效率。本期我們將分享幾種合并PDF的方法。讓我們來(lái)看看。

          方法1、另存功能

          PDF文件是我們工作和生活中常見(jiàn)的文件格式。有時(shí),為了便于管理和共享,我們需要將多個(gè)PDF文件合并成一個(gè)文件。如果目前需要合并的PDF文件數(shù)量很大,比如只有5個(gè)以內(nèi),那么此時(shí)可以使用辦公內(nèi)置的另存功能來(lái)完成。也就是說(shuō),使用Word文檔依次打開(kāi)需要合并的PDF文件,在頂部的“文件”菜單中找到“另存為”的選項(xiàng),另存為“.pdf“格式就可以了。

          方法2、手工編輯

          如果需要同時(shí)引用或處理多個(gè)PDF文件,可以節(jié)省重復(fù)操作步驟。無(wú)需多次打開(kāi)、關(guān)閉或復(fù)制粘貼文件,可以提高工作效率,降低操作失誤的可能性。通過(guò)將多個(gè)PDF文件合并成一個(gè)文件,可以減少文件的數(shù)量,從而減少存儲(chǔ)空間的占用。特別是對(duì)于大量的小文件,合并后可以節(jié)省寶貴的磁盤空間。同樣,如果需要合并的PDF文件數(shù)量較少,可以選擇專門的編輯器,將所需內(nèi)容復(fù)制到一個(gè)文件中,以滿足合并要求。

          方法3、高效率軟件合并文件

          假如目前你需要合并大量的PDF文件,并且對(duì)合并文件有很高的要求,那么在這個(gè)時(shí)候選擇一個(gè)高效率的軟件進(jìn)行操作,這是目前最好的方法。舉例來(lái)說(shuō),啟源PDF轉(zhuǎn)換器軟件,它是一個(gè)專業(yè)的PDF處理軟件,提供了一個(gè)簡(jiǎn)單快捷的PDF合并功能。在合并PDF文件時(shí),您可以很容易地將多個(gè)PDF文件合并為一個(gè)整體,從而解決您的煩惱。

          軟件的操作方法比較簡(jiǎn)單,只需直接在計(jì)算機(jī)上啟動(dòng)“啟源PDF轉(zhuǎn)換”軟件,在界面上選擇“PDF合并”功能,然后添加需要合并的PDF文件。您可以通過(guò)拖動(dòng)或點(diǎn)擊按鈕上傳文件,并調(diào)整文件的順序和頁(yè)面設(shè)置。所有設(shè)置完成后,只需點(diǎn)擊“開(kāi)始合并”按鈕,這些PDF文件就會(huì)很快合并成一個(gè)整體。

          方法4、在線平臺(tái)合并文件

          除了上面分享的三種方法外,如果您想在計(jì)算機(jī)上合并PDF文件,還可以選擇一些在線平臺(tái)進(jìn)行操作,例如iLovePDF工具。這是一個(gè)國(guó)外的PDF在線解決方案,其合并文件的效果也挺不錯(cuò)。您可以在計(jì)算機(jī)上打開(kāi)平臺(tái)網(wǎng)頁(yè),選擇對(duì)應(yīng)的功能,并批量添加需要合并的PDF文件。點(diǎn)擊“開(kāi)始合并”解決問(wèn)題。

          關(guān)于如何將PDF文件合并的方法,小編就與大家分享到這里了,希望對(duì)大家有所幫助。

          備好獎(jiǎng)狀的獲獎(jiǎng)名作為:Word獎(jiǎng)狀模板的數(shù)據(jù)源(含表頭-表格模板對(duì)應(yīng)的信息)哦!如:

          打開(kāi)word制作好需要制作的獎(jiǎng)狀模板-郵件選項(xiàng)卡-選擇收件人-選擇使用現(xiàn)有列表-插入合并域(表頭中對(duì)應(yīng)的內(nèi)容)-預(yù)覽結(jié)果-完全并合并-保存-打印就可以批量制作啦 !!!

          該功能還可以和郵箱聯(lián)合使用用于批量相同格式不同填充內(nèi)容的信息發(fā)放哦——比如offer發(fā)放等:大致步驟如下(暫時(shí)沒(méi)有示例。下次有了更新上)

          還是先將word中的offer格式調(diào)整好(注意offer發(fā)放中不同人的姓名,薪資待遇等方面要做到帶表頭的數(shù)據(jù)表格中)-郵件-選擇收件人使用現(xiàn)有列表-編輯域-預(yù)覽-完成并合并中郵件-郵件(郵箱配合outlook使用,html格式就是word中看見(jiàn)的,附件是作為郵件附件發(fā)送)-需要在outlook郵箱顯示-outlook設(shè)為默認(rèn)的郵箱發(fā)送


          主站蜘蛛池模板: 精品无码人妻一区二区三区18| 久久人妻av一区二区软件| 91在线一区二区| 一区二区三区免费在线视频| 亚洲日韩AV无码一区二区三区人| 国产成人精品无码一区二区三区| 精品国产福利在线观看一区 | 国产精品亚洲一区二区三区在线观看 | 国产精品无码一区二区三级| 国产精品免费视频一区| 无码丰满熟妇浪潮一区二区AV| 蜜桃无码AV一区二区| 亚洲AV午夜福利精品一区二区| 99精品高清视频一区二区| 日韩av片无码一区二区三区不卡| 国产精品一区二区毛卡片| 91视频一区二区三区| 亚洲国产成人久久一区二区三区| 亚洲av无码一区二区三区观看 | 国产精品乱码一区二区三区| 国产福利无码一区在线| 在线观看一区二区精品视频| 国内精自品线一区91| 精品国产一区二区三区久久影院 | 亚洲线精品一区二区三区影音先锋| 日本一区二区三区在线网| 一区二区不卡视频在线观看 | eeuss鲁片一区二区三区| 日韩一区二区a片免费观看| 丝袜美腿一区二区三区| 精品国产日韩亚洲一区在线| 国产精品亚洲一区二区无码 | 大屁股熟女一区二区三区| 亚洲夜夜欢A∨一区二区三区| 久久国产精品视频一区| 无码人妻精品一区二区三区99性 | 亚洲视频一区调教| 国产福利一区二区三区视频在线| 国产精品一区在线麻豆| 国产精品日韩一区二区三区| 日韩精品一区二区三区不卡|