Rumah  >  Artikel  >  hujung hadapan web  >  Apakah maksud pembangunan komponen vue?

Apakah maksud pembangunan komponen vue?

青灯夜游
青灯夜游asal
2021-12-27 16:15:147561semak imbas

Dalam Vue, pembangunan komponen merujuk kepada pembahagian perniagaan yang kompleks kepada berbilang komponen, dan CSS, JS, templat, gambar dan sumber lain yang setiap komponen bergantung kepada dibangunkan dan diselenggara bersama. Oleh kerana komponen bebas daripada sumber, ia boleh digunakan semula dalam sistem, sangat memudahkan jumlah kod, dan lebih mesra untuk meminta perubahan dan penyelenggaraan kemudian.

Apakah maksud pembangunan komponen vue?

Persekitaran pengendalian tutorial ini: sistem Windows 7, vue versi 2.9.6, komputer DELL G3.

Pembangunan komponen Vue

Apakah komponenisasi

vue.js mempunyai dua keajaiban Satu utama senjata adalah didorong oleh data dan yang lain adalah komponenisasi Jadi persoalannya, apakah komponenisasi dan mengapa ia perlu? Seterusnya, saya akan menjawab dua soalan ini satu demi satu Apa yang dipanggil komponenisasi adalah untuk membahagikan halaman kepada berbilang komponen, dan CSS, JS, templat, gambar dan sumber lain yang bergantung pada setiap komponen dibangunkan dan diselenggara. bersama. Oleh kerana komponen tidak bergantung pada sumber, ia boleh digunakan semula dalam sistem, dan komponen boleh disarangkan jika projek itu rumit, jumlah kod boleh dipermudahkan, dan perubahan permintaan dan penyelenggaraan akan menjadi lebih mudah .

1. Pembangunan komponen merujuk kepada pembahagian perniagaan yang kompleks kepada komponen satu demi satu

2 Komponen pembangunan komponen secara amnya perlu fleksibel

3. Pembangunan komponen melibatkan js Vue. enkapsulasi komponen, dan anda perlu menguasai asas Vue, kaedah dan sifat contoh Vue, Vue.extend, pemalam Vue, dll.

Apakah maksud pembangunan komponen vue?

Bagaimana untuk menjalankan pembangunan komponen

Lihat gambar di bawah:

Apakah maksud pembangunan komponen vue?

Ini adalah ralat dalam vue.js bahawa komponen tidak berdaftar lx-xxx digunakan. Ralat ini memberitahu kami kebenaran: mesti mendaftar sebelum menggunakan komponen tersuai.
Jadi bagaimana untuk mendaftar komponen? Vue.js menyediakan dua cara untuk mendaftar komponen, pendaftaran global dan pendaftaran tempatan.

1. Pendaftaran global

Dalam vue.js kita boleh menggunakan Vue.component(tagName, options) untuk pendaftaran global, seperti

Vue.component('my-component', {
  // 选项
})

2. Pendaftaran separa

Vue.js juga menyokong pendaftaran separa Kami boleh menggunakan pilihan komponen di dalam komponen untuk melakukan pendaftaran separa komponen, contohnya:

import HelloWorld from './components/HelloWorld'

export default {
  components: {
    HelloWorld
  }
}

Perbezaan: Komponen global dipasang di bawah Vue.options.components, manakala komponen tempatan dipasang di bawah vm.$options.components Inilah sebabnya mengapa komponen yang didaftarkan secara global boleh digunakan sewenang-wenangnya.

Pengetahuan penting untuk pembangunan komponen

Bak kata pepatah, jika anda ingin melakukan kerja anda dengan baik, anda mesti mengasah alat anda terlebih dahulu komponen, kita mesti terlebih dahulu Untuk menguasai beberapa pengetahuan yang diperlukan, saya hanya akan memperkenalkannya secara ringkas di sini Sila rujuk laman web rasmi untuk butiran.

nama

Nama komponen, diperlukan

<lx-niu/>
<lx-niu></lx-niu/>

name: &#39;lxNiu&#39;

Gunakan perintah kes unta dalam js, gunakan kebab untuk penamaan kes HTML.

props

Sifat komponen, digunakan untuk komunikasi komponen ibu bapa-anak, boleh diakses melalui ini.msg

<div>{{msg}}</div>

props: {
  msg: {
    type: String,
    default: &#39;&#39;
  }
}

show: Boolean // 默认false

msg: [String, Boolean]  // 多种类型

dikira

Memproses atribut dalam data atau prop dan mengembalikan atribut baharu

<div>{{newMsg}}</div>

computed: {
  newMsg() {
    return &#39;hello &#39; + this.msg
  }
},

Nota: Kerana prop, data dan dikira disusun Peringkat akan digabungkan sebagai atribut vm, jadi ia tidak boleh dinamakan semula

memberi

Gunakan fungsi render untuk menerangkan templat

<lx-niu tag=&#39;button&#39;>hello world</lx-niu>

<script type="text/javascript">
  export default {
    name: &#39;lxNiu&#39;,
    props: {
      tag: {
        type: String,
        default: &#39;div&#39;
      },
    },
    // h: createElement
    render(h) {
      return h(this.tag,
        {class: &#39;demo&#39;}, 
        this.$slots.default)
    }
  }
</script>

h dalam render sebenarnya createElement, yang menerima tiga parameter dan mengembalikan vnode
h penjelasan parameter:
args1: {string | Function | Object} digunakan untuk menyediakan kandungan html DOM
args2: { Objek} Tetapkan gaya DOM, sifat, peristiwa mengikat, dsb.
args3: {array} Digunakan untuk menetapkan kandungan yang diedarkan

Nota: Urutan kompilasi Vue: templat–> render - -> vnode --> tampalan -->

kelas

Tentukan nama kelas subkomponen

Apakah maksud pembangunan komponen vue?

<lx-niu>
  <div slot=&#39;header&#39;>header</div>
  <div class="body" slot=&#39;body&#39;>
    <input type="text">
  </div>
  <div slot=&#39;footer&#39;>footer</div>

  <button class=&#39;btn&#39;>button</button>
</lx-niu>

<template>
  <div>
    <slot name=&#39;header&#39;></slot>
    <slot name=&#39;body&#39;></slot>
    <slot name=&#39;footer&#39;></slot>
    <slot></slot>
  </div>
</template>

<script>
  export default {
    name: &#39;lxNiu&#39;,
    mounted() {
      this.$slots.header // 包含了slot="foo"的内容
      this.$slots.default // 得到一个vnode,没有被包含在具名插槽中的节点,这里是button
    }
  }
</script>

gayaTeruskan gaya kepada komponen kanak-kanak

// 父组件
<lx-niu round type=&#39;big&#39;/>

// 子组件
<div :class="[
  type ? &#39;lx-niu__&#39; + type : &#39;&#39;,
  {&#39;is-round&#39;: round},
]">控制</div>

//真实DOM
<div class=&#39;lx-niu__big is-round&#39;>hello</div>

Atribut lain

$attrs

// 父组件
<lx-niu :bodyStyle=&#39;{color: "red"}&#39;/>


// 子组件
<template>
  <div :style=&#39;bodyStyle&#39;>hello world</div>
</template>

<script>
  export default {
    name: &#39;lxNiu&#39;,
    props: {
      bodyStyle: {},
    },
  }
</script>
v-bind="$attrs" Tambahkan atribut selain kelas dan gaya kepada komponen induk, seperti mentakrifkan input:

v-sekali

Komponen hanya dipaparkan sekali, dan tidak akan dipaparkan semula walaupun data berubah kemudian. Contohnya, dalam contoh, val tidak akan menjadi 456

campuran.

<input v-bind="$attrs">
// mixin.js
export default {
  data() {
    return{
       msg: &#39;hello world&#39;
    }
  },
  methods: {
    clickBtn() {
      console.log(this.msg)
    }
  },
}

// index.vue
<button @click="clickBtn">button</button>

import actionMixin from "./mixin.js";
export default {
  methods: {},
  mixins: [actionMixin]
}

实例演示

比如我们要注册一个 lx-button 这样一个组件,那么目录和伪代码如下:

Apakah maksud pembangunan komponen vue?

index.vue

<template>
  <button>lxButton</button>
</template>

<script>
export default {
  name: &#39;lxButton&#39;
}
</script>

index.js

import lxButton from &#39;./src/index&#39;

lxButton.install = (Vue) => {
  Vue.component(lxButton.name, lxButton)
}

export default lxButton

其中 install 是 Vue.js 提供了一个公开方法,这个方法的第一个参数是 Vue 构造器,第二个参数是一个可选的选项对象。
MyPlugin.install = function (Vue, options){}

参考: 开发插件

https://cn.vuejs.org/v2/guide/plugins.html#%E5%BC%80%E5%8F%91%E6%8F%92%E4%BB%B6

watch-弹窗实现原理

<button @click="dialogVisible = true">显示</button>
<lx-niu :visible.sync="dialogVisible"></lx-niu>

<script>
  export default {
    data() {
      return {
        dialogVisible: false
      }
    },
    watch: {
      dialogVisible(val) {
        console.log(&#39;father change&#39;, val)
      }
    }
  }
</script>

定义组件

<template>
  <div v-show="visible">
    <button @click="hide">关闭</button>
  </div>
</template>

<script>
  export default {
    name: &#39;lxNiu&#39;,
    props: {
      visible: Boolean
    },
    watch: {
      visible(val) {
        console.log(&#39;child change:&#39;, val)
      }
    },
    methods: {
      hide() {
        this.$emit(&#39;update:visible&#39;, false);
      }
    },
  }
</script>

点击父组件中的显示按钮,改变传入子组件中的值,点击子组件中的关闭,改变父组件中值。

注:@click=“dialogVisible = true” 点击时将dialogVisible的值改为true  
注::visible.sync: 双向数据绑定,配合update:visible使用,实现子组件修改父组件中的值

官网解释: sync

col组件实例

export default {
  name: &#39;ElCol&#39;,

  props: {
    span: {
      type: Number,
      default: 24
    },
    tag: {
      type: String,
      default: &#39;div&#39;
    },
    offset: Number,
    pull: Number,
    push: Number,
    xs: [Number, Object],
    sm: [Number, Object],
    md: [Number, Object],
    lg: [Number, Object],
    xl: [Number, Object]
  },

  computed: {
    gutter() {
      let parent = this.$parent;
      while (parent && parent.$options.componentName !== &#39;ElRow&#39;) {
        parent = parent.$parent;
      }
      return parent ? parent.gutter : 0;
    }
  },
  render(h) {
    let classList = [];
    let style = {};

    if (this.gutter) {
      style.paddingLeft = this.gutter / 2 + &#39;px&#39;;
      style.paddingRight = style.paddingLeft;
    }

    [&#39;span&#39;, &#39;offset&#39;, &#39;pull&#39;, &#39;push&#39;].forEach(prop => {
      if (this[prop] || this[prop] === 0) {
        classList.push(
          prop !== &#39;span&#39;
            ? `el-col-${prop}-${this[prop]}`
            : `el-col-${this[prop]}`
        );
      }
    });

    [&#39;xs&#39;, &#39;sm&#39;, &#39;md&#39;, &#39;lg&#39;, &#39;xl&#39;].forEach(size => {
      if (typeof this[size] === &#39;number&#39;) {
        classList.push(`el-col-${size}-${this[size]}`);
      } else if (typeof this[size] === &#39;object&#39;) {
        let props = this[size];
        Object.keys(props).forEach(prop => {
          classList.push(
            prop !== &#39;span&#39;
              ? `el-col-${size}-${prop}-${props[prop]}`
              : `el-col-${size}-${props[prop]}`
          );
        });
      }
    });

    return h(this.tag, {
      class: [&#39;el-col&#39;, classList],
      style
    }, this.$slots.default);
  }
};

col组件使用render函数,而不是template来实现组件,原因有两个:

  • 该组件有大量的类判断,如果采用template代码比较冗余,使用js代码更加简洁

  • 直接render描述性能更好

官网解释: render-function

button组件实例

<template>
  <button
    class="el-button"
    @click="handleClick"
    :disabled="buttonDisabled || loading"
    :autofocus="autofocus"
    :type="nativeType"
    :class="[
      type ? &#39;el-button--&#39; + type : &#39;&#39;,
      buttonSize ? &#39;el-button--&#39; + buttonSize : &#39;&#39;,
      {
        &#39;is-disabled&#39;: buttonDisabled,
        &#39;is-loading&#39;: loading,
        &#39;is-plain&#39;: plain,
        &#39;is-round&#39;: round,
        &#39;is-circle&#39;: circle
      }
    ]"
  >
    <i class="el-icon-loading" v-if="loading"></i>
    <i :class="icon" v-if="icon && !loading"></i>
    <span v-if="$slots.default"><slot></slot></span>
  </button>
</template>
<script>
  export default {
    name: &#39;ElButton&#39;,

    inject: {
      elForm: {
        default: &#39;&#39;
      },
      elFormItem: {
        default: &#39;&#39;
      }
    },

    props: {
      type: {
        type: String,
        default: &#39;default&#39;
      },
      size: String,
      icon: {
        type: String,
        default: &#39;&#39;
      },
      nativeType: {
        type: String,
        default: &#39;button&#39;
      },
      loading: Boolean,
      disabled: Boolean,
      plain: Boolean,
      autofocus: Boolean,
      round: Boolean,
      circle: Boolean
    },

    computed: {
      _elFormItemSize() {
        return (this.elFormItem || {}).elFormItemSize;
      },
      buttonSize() {
        return this.size || this._elFormItemSize || (this.$ELEMENT || {}).size;
      },
      buttonDisabled() {
        return this.disabled || (this.elForm || {}).disabled;
      }
    },

    methods: {
      handleClick(evt) {
        this.$emit(&#39;click&#39;, evt);
      }
    }
  };
</script>

局部组件实例

<template>
  <div class="login">
    <login-header />
    <login-request />
    <login-footer />
  </div>
</template>

<script>
import loginHeader from &#39;./login-header&#39;;
import loginRequest from &#39;./login-request&#39;;
import loginFooter from &#39;./login-footer&#39;;

export default {
  components: {
    [loginHeader.name]: loginHeader,
    [loginRequest.name]: loginRequest,
    [loginFooter.name]: loginFooter
  }
};
</script>

8. 分享总结

  • 首先介绍了什么是组件化开发,以及为什么要进行组件化
  • 其次介绍了组件开发的两种方式和适用场景,以及进行组件化开发的必备知识
  • 最后实例演示了全局组件和局部组件的开发

【相关推荐:《vue.js教程》】

Atas ialah kandungan terperinci Apakah maksud pembangunan komponen vue?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn