手把手教你開發 Vue 元件 ( 一)

ericjj發表於2017-01-06

好久沒寫文章啦~
新公司有點忙, 再加上最近在寫 node.js, 抽空寫一篇吧!

隨著 Vue 越來越火熱, 相關元件庫也非常多啦, 只用輪子怎麼夠, 還是要造起來!!!
滴滴公共前端團隊已經有了一篇文章 [Vue] 外掛開發入門
但是可能具體細節還不夠清楚; 在本文中; 將帶領大家開發一個簡單的分頁元件~

1 環境配置

首先使用 vue-cli 腳手架, 生成基本專案;

npm install vue-cli -g
# mvue 是本次專案名稱
vue init webpack mvue複製程式碼

如果要開發一個 npm 安裝包, 還修改 package.jsonmain 選項

"main": "dist/mvue.js"複製程式碼

意思是我們將提供編譯壓縮後 mvue.js 檔案給其他開發者使用;

2. webpack

在前端領域內, 可謂是沒 webpack 不成活; 手寫太麻煩, 就直接給大家檔案了, 以下是我們的 webpack.config.js 檔案:

var path = require('path');
var webpack = require('webpack');

module.exports = {
    entry: {
        main: './src/mvue.js'
    },
    output: {
        path: path.resolve(__dirname, '../dist'),
        publicPath: '/dist/',
        filename: 'mvue.js',
        library: 'mvue',
        libraryTarget: 'umd',
        umdNamedDefine: true
    },
    externals: {
        vue: {
            root: 'Vue',
            commonjs: 'vue',
            commonjs2: 'vue',
            amd: 'vue'
        }
    },
    resolve: {
        extensions: ['', '.js', '.vue']
    },
    module: {
        loaders: [{
            test: /\.vue$/,
            loader: 'vue'
        }, {
            test: /\.js$/,
            loader: 'babel',
            exclude: /node_modules/
        }, {
            test: /\.css$/,
            loader: 'style!css!autoprefixer'
        }, {
            test: /\.less$/,
            loader: 'style!css!less'
        }, {
            test: /\.(gif|jpg|png|woff|svg|eot|ttf)\??.*$/,
            loader: 'url?limit=8192'
        }, {
            test: /\.(html|tpl)$/,
            loader: 'vue-html'
        }]
    },
    plugins: [
        new webpack.DefinePlugin({
            'process.env': {
                NODE_ENV: '"production"'
            }
        }),
        new webpack.optimize.UglifyJsPlugin({
            compress: {
                warnings: false
            }
        }),
        new webpack.optimize.OccurenceOrderPlugin()
    ]
}複製程式碼

重點是 entry 和 output, 指定入口檔案和輸出檔案;
因為我們要寫的是分頁元件, 所以已經在 components 目錄下建立了 page.vue;
接下來 我們編寫 webpack 入口檔案:

import Page from './components/page';

const mvue = {
  Page
};

// 匯出 install 函式
// Vue.use() 會呼叫這個函式
const install = function(Vue, opts = {}) {
  // 如果安裝過就忽略
  if (install.installed) return;

  // 指定元件 name
  Vue.component(Page.name, Page);
}

// 自動安裝 方便打包成壓縮檔案, 用<script scr=''></script>的方式引用
if (typeof window !== 'undefined' && window.Vue) {
  install(window.Vue);
}

// 把模組匯出
module.exports = {
  install,
  Page
}複製程式碼

在入口檔案中, 我們提供了對外公開的元件, install 函式, install 在 vue 元件開發中至關重要, vue 元件的呼叫方式是 Vue.use(***), 這個函式就會呼叫元件的 install 函式;
接下來就是各種元件的編寫了!
以分頁元件為例子, 首先我們要指定 props, 並對其型別進行驗證,

  props: {
    current: {
      type: Number,
      default: 1
    },
    total: {
      type: Number,
      default: 1
    }, 
    currentChange: {
      type: Function
    }
  }複製程式碼

一共接受三個引數 分別是:

當前索引, 總條目, 回撥函式

export default {
  name: 'mvue-page',
  props: {
    current: {
      type: Number,
      default: 1
    },
    total: {
      type: Number,
      default: 1
    }, 
    currentChange: {
      type: Function
    }
  },
  mounted () {
    this.insertPage()
  },

  data () {
    return {
      currentIndex: this.current,
      pageShowArray: [],
      displayCount: 7
    }
  },

  methods: {
// 翻頁
    insertPage () {
      let self = this
      self.pageShowArray = []

      for (var i = 1; i <= self.total; i++) {
        this.pageShowArray.push(i)
      }
      // 小型分頁
      if (this.total <= this.displayCount) { return; }
      let begin = this.currentIndex - 3 
      let end = this.currentIndex + 3

      begin = begin <= 1 ? 1 : begin
      end = end <= this.displayCount ? this.displayCount : end
      begin = begin >= this.total - this.displayCount ? this.total - this.displayCount : begin
      end = end >= this.total ? this.total : end

      let arr = this.pageShowArray.slice(begin - 1, end)
      this.$set(this, 'pageShowArray', arr)
    },

// 上一頁
   pre () {
      if (this.currentIndex <= this.displayCount) {return;}
      this.setIndex(this.currentIndex - this.displayCount)
      this.insertPage()
    },
// 下一頁
    next () {
      if (this.currentIndex >= this.total) {return;}
      this.setIndex(this.currentIndex + this.displayCount)
      this.insertPage()
    },
// item 點選
    itemClick (current) {
      this.setIndex(current)
      this.insertPage()
// 觸發回撥
      this.currentChange(current)
    },
    setIndex (current) {
      let temp = current
      if (temp <= 1) { temp = 1}
      if (temp >= this.total) { temp = this.total}
      this.$set(this, 'currentIndex', temp)
    }
  }
}複製程式碼

呼叫方式

...  html code
<mvue-page :current="2" :total="40" :currentChange='currentChange'></mvue-page>

... js code
// 兩種方式選一個即可
// 按需載入
import {Page} from 'mvue'
Vue.use(Page)
// 全部載入
import mvue from '../dist/mvue.js'
Vue.use(mvue);複製程式碼

如上, 一個簡單的分頁元件已經有些模樣, 接下來使用 webpack 打包;

// 對應 config 檔案
webpack webpack.config.js複製程式碼

釋出

npm publish複製程式碼

如果有問題, 請在文字下面評論留言, O(∩_∩)O謝謝

相關程式碼 : github.com/ericjjj/mvu…
歡迎 Star

相關文章