Vue 組件開發中的(de)小技巧 - 新聞資訊 - 雲南小程序開發|雲南軟件開發|雲南網站建設-昆明融晨信息技術有限公司

159-8711-8523

雲南網建設/小程序開發/軟件開發

知識

不(bù)管是(shì)網站,軟件還是(shì)小程序,都要(yào / yāo)直接或間接能爲(wéi / wèi)您産生價值,我們在(zài)追求其視覺表現的(de)同時(shí),更側重于(yú)功能的(de)便捷,營銷的(de)便利,運營的(de)高效,讓網站成爲(wéi / wèi)營銷工具,讓軟件能切實提升企業内部管理水平和(hé / huò)效率。優秀的(de)程序爲(wéi / wèi)後期升級提供便捷的(de)支持!

您當前位置>首頁 » 新聞資訊 » 小程序相關 >

Vue 組件開發中的(de)小技巧

發表時(shí)間:2021-1-5

發布人(rén):融晨科技

浏覽次數:46

日常開發中,我們會用到(dào)很多第三方組件庫,學習組件開發最好的(de)方法就(jiù)是(shì)看這(zhè)些組件庫的(de)源碼,并從中學到(dào)一些小技巧

element-ui 大(dà)家基本都用過,總結一下組件庫中 Tree 和(hé / huò) Collapse 用到(dào)的(de)小技巧,下圖爲(wéi / wèi)簡易版實現演示效果

Collapse

先來(lái)看下使用到(dào)的(de) API:

  • provide/inject
  • $emit
  • $on
  1. 使用 provide/inject祖先組件實例 作爲(wéi / wèi)依賴,注入到(dào)子(zǐ)孫組件中
  2. 因爲(wéi / wèi)子(zǐ)組件是(shì)采用 slot 方式插入,所以(yǐ)要(yào / yāo)使用 祖先組件實例 發起自定義事件
<mx-collapse v-model="activeNames" @change="handleChange" accordion>
  <mx-collapse-item title="一緻性 Consistency" name="1">
    <div>
      與現實生活一緻:與現實生活的(de)流程、邏輯保持一緻,遵循用戶習慣的(de)語言和(hé / huò)概念;
    div>
    <div>
      在(zài)界面中一緻:所有的(de)元素和(hé / huò)結構需保持一緻,比如:設計樣式、圖标和(hé / huò)文本、元素的(de)位置等。
    div>
  mx-collapse-item>
  ......
mx-collapse>
複制代碼

  • 父組件 實例作爲(wéi / wèi)依賴,注入到(dào)子(zǐ)組件中, 在(zài)子(zǐ)組件中使用父組件實例 發起自定義事件
  • 父組件中使用 $on 監聽 item-click 事件,并接收子(zǐ)組件傳回來(lái)的(de)數據做進一步處理
provide() {
  return {
    collapse: this,
  };
},
created() {
  // 自定義事件監聽
  this.$on('item-click', this.handleItemClick);
},
//...
複制代碼

  • 在(zài)子(zǐ)組件 collapse-item 中使用 父組件實例 觸發點擊事件,發送當前組件數據
inject: ['collapse'],
methods: {
  // 使用父組件實例觸發自定義事件
  handleHeaderClick() {
    this.collapse.$emit('item-click', this);
  },
},
//...
複制代碼

  • collapse.vue 完整代碼

<script>
export default {
  name: 'MxCollapse',
  componentName: 'MxCollapse',
  props: {
    accordion: Boolean,
    value: {
      type: [Array, String, Number],
      default() {
        return [];
      },
    },
  },
  data() {
    return {
      activeNames: [].concat(this.value),
    };
  },
  // 将當前組件實例作爲(wéi / wèi)依賴,用于(yú)注入到(dào)子(zǐ)組件中,
  // 在(zài)子(zǐ)孫後代中可以(yǐ)使用祖先組件實例 發起自定義事件
  provide() {
    return {
      collapse: this,
    };
  },
  watch: {
    value(value) {
      this.activeNames = [].concat(value);
    },
  },
  created() {
    // 自定義事件監聽
    this.$on('item-click', this.handleItemClick);
  },
  methods: {
    /**
     * item-click 自定義事件處理
     * 1. 手風琴模式下,展開的(de)元素隻有一個(gè)
     * 2. 普通模式可以(yǐ)多個(gè)展開
     */
    handleItemClick(item) {
      const { name } = item;

      // 手風琴模式
      if (this.accordion) {
        this.setActiveNames(
          (this.activeNames[0] || this.activeNames[0] === 0) &&
          this.activeNames[0] === name
          ? ''
          : name
        );
      }
      // 普通模式
      else {
        const activeNames = this.activeNames.slice(0);
        const index = activeNames.indexOf(name);
        if (index > -1) {
          activeNames.splice(index, 1);
        } else {
          activeNames.push(name);
        }
        this.setActiveNames(activeNames);
      }
    },

    /**
     * 實時(shí)修改 activeNames 值
     * 當 activeNames 數據變化時(shí),觸發組件自定義 change 事件
     */
    setActiveNames(activeNames) {
      activeNames = [].concat(activeNames);
      this.activeNames = activeNames;
      const value = http://www.wxapp-union.com/this.accordion ? activeNames[0] : activeNames;
      this.$emit('change', value);
    },
  },
};
script>
<style lang="less" scoped>
.mx-collapse {
  border-top: 1px solid #ebeef5;
  border-bottom: 1px solid #ebeef5;
}
style>
複制代碼

  • collapse-item.vue 完整代碼

<script>
export default {
  name: 'MxCollapseItem',
  componentName: 'MxCollapseItem',
  data() {
    return {};
  },
  inject: ['collapse'],
  props: {
    disabled: Boolean,
    title: String,
    name: {
      type: [String, Number],
    },
  },
  computed: {
    isActive() {
      return this.collapse.activeNames.indexOf(this.name) > -1;
    },
  },
  methods: {
    // 使用父組件實例觸發自定義事件,并将本組件數據回傳
    handleHeaderClick() {
      this.collapse.$emit('item-click', this);
    },
  },
};
script>
<style lang="less" scoped>
.mx-collapse-item {
  font-size: 13px;
  user-select: none;
  &:last-child {
    margin-bottom: -1px;
  }
  .mx-collapse-item__header {
    height: 48px;
    line-height: 48px;
    color: #303133;
    cursor: pointer;
    border-bottom: 1px solid #ebeef5;
    font-weight: bold;
    outline: 0;
  }
  .mx-collapse-item__content {
    padding: 25px 0;
    color: #303133;
    line-height: 1.769230769230769;
  }
}
style>
複制代碼

Tree

組件循環引用,遞歸組件

  1. 使用遞歸組件,調用組件自身完成樹結構渲染
  2. 必須指定組件 name 屬性,并将子(zǐ)數據元素作爲(wéi / wèi)遞歸的(de)數據源傳入
  • tree.vue 完整代碼
<script>
export default {
  // 遞歸組件必須指定name
  name: 'MxTree',
  componentName: 'MxTree',
  props: {
    treeData: {
      type: Object,
      required: true,
    },
  },
  data() {
    return {
      open: true,
    };
  },
  computed: {
    // 計算是(shì)否可以(yǐ)展開 or 收起
    isFolder() {
      return this.treeData.children && this.treeData.children.length;
    },
  },
  methods: {
    // 展開 or 收起
    toggle() {
      if (this.isFolder) {
        this.open = !this.open;
      }
    },
  },
};
script>

<style lang="less" scoped>
.mx-tree-label {
  text-align: left;
  font-size: 13px;
}
style>

複制代碼

Install

安裝 Vue.js 插件

  1. 如果插件是(shì)一個(gè)對象,必須提供 install 方法
  2. 如果插件是(shì)一個(gè)函數,它會被作爲(wéi / wèi) install 方法
  3. install 方法調用時(shí),會将 Vue 作爲(wéi / wèi)參數傳入
  4. 該方法需要(yào / yāo)在(zài)調用 new Vue() 之(zhī)前被調用
  5. install 方法被同一個(gè)插件多次調用,插件将隻會被安裝一次
  • 每個(gè)組件都是(shì)獨立的(de)模塊,目錄結構如下
mx
├── collapse
│   ├── index.js
│   └── src
│       └── collapse.vue
├── collapse-item
│   ├── index.js
│   └── src
│       └── collapse-item.vue
├── index.js
└── tree
    ├── index.js
    └── src
        └── tree.vue
複制代碼

  • 組件文件夾中 index.js 爲(wéi / wèi)入口文件,在(zài)其中定義 install 方法并将模塊暴露
import MxTree from './src/tree';

MxTree.install = function(Vue) {
  Vue.component(MxTree.name);
};

export default MxTree;
複制代碼

  • 根目錄下的(de) index.js 爲(wéi / wèi)總入口文件,在(zài)其中将所有組件集中,定義 install 方法并将模塊暴露
import Collapse from './collapse/index';
import CollapseItem from './collapse-item/index';
import Tree from './tree/index';

const components = [Collapse, CollapseItem, Tree];

const install = function(Vue, options = {}) {
  components.forEach(component => {
    Vue.component(component.name, component);
  });
};

export default {
  install,
};
複制代碼

  • 最後一步,像使用 element-ui 一樣的(de)方式,來(lái)使用自己的(de)組件庫
import Vue from 'vue';
import App from './App.vue';
import MxUI from './mx/index';

Vue.config.productionTip = false;
Vue.use(MxUI)

new Vue({
  render: h => h(App),
}).$mount('#app');
複制代碼

  • 入口頁面完整代碼


<script>
export default {
  name: 'App',
  data() {
    return {
      activeNames: ['1'],
      treeData: {
        label: 'JavaScript',
        children: [
          {
            label: '數據類型',
            children: [
              {
                label: 'string',
              },
              {
                label: 'number',
              },
              {
                label: 'boolean',
              },
              {
                label: 'null',
              },
              {
                label: 'undefined',
              },
              {
                label: 'symbol',
              },
              {
                label: 'object',
              },
            ],
          },
          {
            label: '變量聲明',
            children: [
              {
                label: 'var',
              },
              {
                label: 'let',
              },
              {
                label: 'const',
              },
            ],
          },
        ],
      },
    };
  },
  methods: {
    handleChange(val) {
      console.log(`activeNames: ${val}`);
    },
  },
};
script>

<style lang="less">
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin: 40px;
  .logo {
    width: 40px;
    margin-bottom: 30px;
  }
  .mx-collapse {
    float: right;
    width: 70%;
    height: 600px;
  }
  .mx-tree:first {
    float: left;
    width: 30%;
    height: 600px;
  }
  .fade-enter-active {
    transition: opacity 0.3s;
  }
  .fade-leave-active {
    transition: opacity 0.1s;
  }
  .fade-enter,
  .fade-leave-to {
    opacity: 0;
  }
}
style>
複制代碼

總結

  1. provide/inject 依賴注入,祖先與子(zǐ)孫之(zhī)間的(de)配合
  2. $emit $on 自定義事件,需注意 slot 方式子(zǐ)組件與父組件通訊的(de)方式
  3. 遞歸組件 必須指定 name 選項
  4. Vue.use 配合 install 将自己的(de)組件添加到(dào) Vue

作者:__mxin
來(lái)源:掘金
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出(chū)處。

相關案例查看更多