<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      【vue系列之三】從一個(gè)vue-pdf-shower,說說vue組件和npm包

      前言

      從去年年初開始,自己便下決心要寫一個(gè)vue系列的博客,但時(shí)至今日,才寫系列的第三篇博客,想來甚是慚愧。

      但是慢歸慢,每一篇都要保證質(zhì)量,以及要寫出自己的心路歷程,防止自己工作中填的坑再讓讀者走一遍。

      vue上手相對react來說是比較簡單的,對于vue的基本指令以及語法,應(yīng)該沒有什么能比官網(wǎng)更詳細(xì),更生動(dòng)的了。仔細(xì)想來,vue值得一說的,在項(xiàng)目中會(huì)讓新手感到困惑的,是vue的組件,今天就最近工作中用到的一個(gè)pdf查看組件,和大家聊聊vue的組件。最后會(huì)講如何將自己的代碼封裝成一個(gè)npm包,發(fā)布到npm官網(wǎng)。

      去年5月份的,寫了vue系列的第一篇使用vue-cli腳手架工具搭建vue-webpack項(xiàng)目,今天再次使用vue-cli初始化項(xiàng)目時(shí),發(fā)現(xiàn)vue-cli已經(jīng)升級到2.9.2。

      多說一句,因?yàn)関ue-cli的命令為vue,所以查看vue-cli的版本時(shí),需要使用vue -V,而且是大寫的V。仔細(xì)看下vue-cli 2.9的官方模板,驚喜的發(fā)現(xiàn)多了一個(gè)pwa模板。

       

      前一陣子,谷歌開發(fā)者大會(huì)在上海舉辦,會(huì)上主推pwa,在這在簡單說下PWA,大神可直接忽略。

      簡述PWA

       PWA是Progressive Web App的縮寫,字面意思理解為漸進(jìn)增強(qiáng)的網(wǎng)頁應(yīng)用。一個(gè) PWA 應(yīng)用首先是一個(gè)網(wǎng)頁, 可以通過 Web 技術(shù)編寫出一個(gè)網(wǎng)頁應(yīng)用. 隨后添加上 App Manifest 和 Service Worker 來實(shí)現(xiàn) PWA 的安裝和離線等功能。

      在一個(gè)正常的HTML中,添加一個(gè)link標(biāo)簽,href為manifest.json,即可將你的網(wǎng)頁應(yīng)用添加到主屏幕。

      manifest.json中會(huì)包含你的圖標(biāo)、名稱。背景色等信息。

      {
        "name": "你的web app名稱",
        "short_name": "簡稱",
        "display": "standalone",
        "start_url": "/",
        "theme_color": "主體色(#ffffff)",
        "background_color": "背景色(#333333)",
        "icons": [
          {
            "src": "icon.png",
            "sizes": "256x256",
            "type": "image/png"
          }
        ]
      }
      引入manifest.json
      <link rel="manifest" href="manifest.json" />

      PWA應(yīng)用能實(shí)現(xiàn)離線訪問的核心是Service Worker,Service Worker 在網(wǎng)頁已經(jīng)關(guān)閉的情況下還可以運(yùn)行, 用來實(shí)現(xiàn)頁面的緩存和離線, 后臺(tái)通知等等功能。

      為了讓應(yīng)用離線工作,需要注冊一個(gè) service worker,一段允許在后臺(tái)運(yùn)行的腳本,不需要 用戶打開 web 頁面,也不需要其他交互。在應(yīng)用根目錄放置serviceworker.js,然后在瀏覽器注冊。

      if('serviceWorker' in navigator) { 
        navigator.serviceWorker .register('/service-worker.js')
        .then(function() { console.log('Service Worker Registered');
      }); }

        在serviceworker注冊后,瀏覽器首次訪問該應(yīng)用時(shí),會(huì)執(zhí)行install方法,這個(gè)方法的callback中我們能夠緩存所有需要緩存的數(shù)據(jù)。具體過程為:
      首先定義需要緩存的文件類型,以及緩存存放路徑;然后在網(wǎng)頁相應(yīng)所有請求之前,會(huì)將請求統(tǒng)一處理,可以控制一部分請求從緩存里拿數(shù)據(jù)。緩存會(huì)通過字符串名稱,動(dòng)態(tài)的更新。篇幅有限,這里大概簡述下。具體可以移步餓了么團(tuán)隊(duì)知乎

      vue組件vue-pdf-shower

      下面言歸正傳,說說vue組件。

      最近筆者在項(xiàng)目中遇到一個(gè)pdf預(yù)覽的需求,經(jīng)過調(diào)研,最終決定用火狐的pdf.js封裝一個(gè)vue組件。

      其實(shí)需求還是比較簡單的,就是后臺(tái)給一個(gè)URL,前端將pdf加載到網(wǎng)頁中即可。chrome和Firefox是自帶pdf查看器的,簡單的做法是使用iframe嵌入,但該方案兼容性太差,而且不受我們控制,所以pass了。

      總體思路如下:

      1.通過pdf.js提供的api,我們傳入pdf的URL,在callback中會(huì)拿到所需的pdf對象。

      2.通過傳入不同的頁碼,可以拿到指定頁面的page對象。

      3.通過canvas,將page對象渲染到頁面中。

      4.遍歷所有page,循環(huán)生成多個(gè)canvas對象,插入dom。

      把思路縷清楚之后,開發(fā)就比較簡單了。

      首先,確定dom結(jié)構(gòu)。由于我們的canvas是動(dòng)態(tài)插入dom的,所以只提供一個(gè)wraper即可。

      dom結(jié)構(gòu)如下

      <template>
          <div class="pdf-wraper">
              <div id="cvsWraper">
                  <div class="loading-pdf" v-if="isloading">{{loadingTxt}}</div>
              </div>
          </div>
      </template>
      

       

      vue-pdf-viewer組件js

      該組件需要傳兩個(gè)參數(shù),一個(gè)是URL,一個(gè)是縮放值scale。

      vue組件需要顯式說明自身期望傳入哪些屬性,并且可以賦予默認(rèn)值。調(diào)用組件時(shí),傳入不同的屬性,可以實(shí)現(xiàn)父組件向子組件傳值。

      props: {
              pdfurl: {
                  default: ''
              },
              scale: {
                  default: 1
              }
          }
      

        

      子組件向父組件傳值

      子組件向父組件通信時(shí),需要使用vue.$emit事件。

      $emit事件接受兩個(gè)參數(shù),第一個(gè)為所要拋出的方法名,第二個(gè)為所拋出方法帶的參數(shù)。

      在這個(gè)組件中,只暴露出一個(gè)onErr事件,即當(dāng)pdf加載失敗時(shí)的回調(diào)函數(shù)。

      PDFJS.getDocument(me.pdfurl).then(function (pafObj) {
                  me.isloading = true;
                  me.pdfDoc = pafObj;
                  let totalNum = me.pdfDoc.numPages;
      
                  // 循環(huán)渲染所有canvas
                  for (let i = 1; i <= totalNum; i++) {
                      let id = `canvas${i}`;
                      let cvsNode = document.createElement('canvas');
                      cvsNode.setAttribute('id', id);
                      cvsNode.setAttribute('class', 'canvas-item');
                      cvsWraper.appendChild(cvsNode);
                      me.renderPage(i);
      
                      if (totalNum === i) {
                          me.isloading = false;
                      }
                  }
              }).catch(function (err) {
                  me.loadingTxt = '加載失敗,請稍后重試';
                  me.$emit('onErr', err);
              });
      

        

      調(diào)用組件

      在調(diào)用組件時(shí),需要傳入所需的屬性和方法。

      <template>
          <div>
               <pdfshower 
                  :pdfurl="pdfurls" 
                  :scale="scale" 
                  @onErr="onErr"
              ></pdfshower>
          </div>
      </template>
      

        

      非父子組件通信

      兄弟組件通信也是比較常見的,比如說在一個(gè)頁面中,導(dǎo)航是一個(gè)組件,內(nèi)容區(qū)域是一個(gè)組件;當(dāng)導(dǎo)航切換時(shí),需要通知內(nèi)容組件發(fā)生變化,并告訴他導(dǎo)航的id。

      處理兄弟組件通信的問題,一般有兩種方式:

      1.兄弟組件都引入一個(gè)公共vue組件hub,通過hub拋出事件,和監(jiān)聽事件,以達(dá)到兄弟組件通信。

      2.使用vuex。

      項(xiàng)目中比較常見的是第一種做法,我做的vue項(xiàng)目中只有一次使用到了vuex;我對vuex的理解是:

      vuex類似于一個(gè)全局的存儲(chǔ)空間,你可以把他理解為將需要傳遞的東西綁在了window下,所以在任何地方都可以拿到,并做修改。

      在項(xiàng)目中用到的hub.js

      /**
       * @file 事件總線
       * @author yangtianjiao
      /
      import Vue from 'vue';
      export default new Vue({});
      

        

      假設(shè)是上面說的那種情況,在導(dǎo)航組件切換時(shí),通過hub發(fā)射信息:

      hub.$emit('changeTableData', {
             dateKey: this.curDateTab
      });
      

        

      內(nèi)容區(qū)域監(jiān)聽hub發(fā)射的方法:

      hub.$on('changeTableData', item => {
                      this.pageNum = 1;
                      this.total = 0;
                      this.dataList = [];
                      this.orderFieldId = 1;
                      this.orderType = 1;
                      this.contenctDesc = '';
                      this.emptyText = '數(shù)據(jù)加載中...';
                      this.isLoading = false;
                  });
      

        

      在內(nèi)容組件銷毀時(shí),取消對hub事件的監(jiān)聽

      beforeDestroy() {
              hub.$off('changeTableData');
      }
      

        

      兄弟組件通信并不復(fù)雜,但要深刻理解,必須在項(xiàng)目中多運(yùn)用、實(shí)踐。這塊應(yīng)該是vue最難的部分了,這塊掌握了,vue項(xiàng)目做起來就會(huì)得心應(yīng)手。

      發(fā)布npm包

      大家平時(shí)工作中,最常用的是npm,很多包、類庫都從npm安裝。其實(shí)我們很容易就會(huì)發(fā)布屬于自己的npm包,下面我會(huì)一步步講講如何將上述的vue-pdf-viewer組件發(fā)布到npm官網(wǎng)的。

      1.執(zhí)行npm init

      執(zhí)行npm init后,根據(jù)命令行提示,依次輸入

      包名稱

      版本

      描述

      入口文件

      測試腳本

      關(guān)鍵詞

      作者

      版權(quán)信息(協(xié)議)

      等等,最后OK,生成一個(gè)package.json文件。

      2.確定包的目錄結(jié)構(gòu)

      package.json是npm幫我們生成的,根目錄下有入口文件index.js,和readme.md。

      index.js中其實(shí)就是一句話,將真正的index.vue暴露出去

      index.js

      /**
       * @file vue-pdf-shower
       * @author v_yangtianjiao(v_yangtianjiao@baidu.com)
       * @time 18/01/15
       */
      module.exports = require('./lib/index.vue');
      

        

      readme中放有對包的簡述,以及包的基本用法

      readme.md

      # vue-pdf-shower
      
      ## 介紹
      > 基于pdf.js的pdf簡易查看組件。
      > 該組件加載全部pdf頁面,不提供翻頁查看功能。
      
      ## github
      [vue-pdf-shower](https://github.com/TJ666/vue-pdf-shower)
      
      ## install
      ```
      npm i vue-pdf-shower --save
      ```
      ## example
      ```
      <template>
          <div>
               <pdfshower 
                  :pdfurl="pdfurls" 
                  :scale="scale" 
                  @onErr="onErr"
              ></pdfshower>
          </div>
      </template>
      
      <script>
      import pdfshower from 'vue-pdf-shower';
      export default {
          name: 'pdfshower',
          components: {
              pdfshower
          },
          data() {
              return {
                  // 所查看的pdf url
                  pdfurls: '//cdn.mozilla.net/pdfjs/tracemonkey.pdf',
                  // 縮放 默認(rèn)為1
                  scale: 1.2
              };
          },
          methods: {
              // 加載失敗的callback
              onErr(err) {
                  console.log('pdf加載失敗,請重試');
                  console.log('錯(cuò)誤信息:', err);
              }
          }
      };
      </script>
      ```
      

        

      至于為啥有個(gè)lib文件夾,還有目錄結(jié)構(gòu)為啥長這樣?我的回答是:

      看了一遍所有的npm包都是這樣,咱就按人家的來吧 - -

      好了,咱們的包已經(jīng)準(zhǔn)備就緒了,就差發(fā)布!!!

      3.注冊npm賬號&發(fā)包

      打開冰箱,將大象放進(jìn)冰箱,關(guān)上冰箱門。

      注冊很簡單的,只需要一個(gè)郵箱就行,連網(wǎng)站都打不開的同學(xué)就好好寫寫jquery去吧。

      4.npm login

      在命令行輸入npm login,

      然后依次輸入用戶名和密碼,以及注冊的郵箱。

      注意:輸入密碼時(shí),密碼是不會(huì)顯示出來的,不要方!

      登錄后只要沒有錯(cuò)誤提示即登錄成功。

      5.npm publish發(fā)包

      離成功只差一步。

      一切準(zhǔn)備妥當(dāng),cd 到我們的vue-pdf-shower目錄,先檢查下npm有沒有重名的包。

      可以去npm官網(wǎng)搜索,也可以直接npm install 包名,如果報(bào)錯(cuò),那么恭喜你包名沒有重復(fù)的。

      執(zhí)行npm publish

      定睛一看,報(bào)了個(gè)錯(cuò)。原來是package.json 的版本號沒有改。將版本號升一個(gè)級,在執(zhí)行publish。

      成功!

       6.去npm官網(wǎng)檢驗(yàn)發(fā)包情況

      發(fā)現(xiàn)已經(jīng)可以搜到,因?yàn)槲沂亲蛱彀l(fā)的包,一天時(shí)間內(nèi)已有116次下載。嗯,還不賴。

      最后附上本組件github地址,歡迎大家拍磚。
      https://github.com/TJ666/vue-pdf-shower

       

      參考文獻(xiàn)

      PWA 入門: 寫個(gè)非常簡單的 PWA 頁面

      手把手教你用npm發(fā)布一個(gè)包

       

      posted @ 2018-01-16 14:04  TJYoung  閱讀(4715)  評論(2)    收藏  舉報(bào)
      主站蜘蛛池模板: 红杏av在线dvd综合| 欧美交a欧美精品喷水| 国产在线精品欧美日韩电影 | 中文字幕有码高清日韩| 无码伊人66久久大杳蕉网站谷歌| 东京热一精品无码av| 日韩亚av无码一区二区三区| 亚洲三区在线观看内射后入| 日韩有码国产精品一区| 亚洲区日韩精品中文字幕| 免费国产黄线在线观看| 亚洲精品成人福利网站| 人人做人人妻人人精| 久久综合亚洲色一区二区三区| 啪啪av一区二区三区| 日本东京热不卡一区二区| 国产美女69视频免费观看| 在线 欧美 中文 亚洲 精品| 国产一区二区三区的视频| 国产精品人成视频免费播放| 国产精品日本一区二区不卡视频| 久青草视频在线观看免费| 国产综合视频一区二区三区| 亚洲一区二区三区久久受| 色狠狠色婷婷丁香五月| 亚洲欧洲美洲在线观看| √新版天堂资源在线资源 | 国产麻豆精品一区一区三区| 自拍偷拍一区二区三区四| 免费专区丝袜调教视频| 亚洲第一香蕉视频啪啪爽| 国产蜜臀一区二区三区四区| 精品国产欧美一区二区三区在线| 亚洲精品国产精品不乱码| 九九热视频免费在线播放| 看黄a大片日本真人视频直播| 亚洲天堂男人影院| 国产欧美日韩亚洲一区二区三区 | 国产一级区二级区三级区| 婷婷久久综合九色综合88| 国产精品国产高清国产av|