Dans Vue, le développement de composants fait référence à la division d'une entreprise complexe en plusieurs composants, et les CSS, JS, modèles, images et autres ressources dont dépend chaque composant sont développés et maintenus ensemble. Étant donné que les composants sont indépendants des ressources, ils peuvent être réutilisés au sein du système, ce qui simplifie considérablement la quantité de code et sont plus adaptés aux modifications ultérieures des demandes et à la maintenance.
L'environnement d'exploitation de ce tutoriel : système Windows 7, vue version 2.9.6, ordinateur DELL G3. "Développement de composants Vue" ? Ensuite, je répondrai à ces deux questions une par une. La soi-disant composantisation signifie diviser la page en plusieurs composants, et les CSS, JS, modèles, images et autres ressources dont dépend chaque composant sont développés et maintenus ensemble.
Étant donné que les composants sont indépendants des ressources, ils peuvent être réutilisés dans le système et les composants peuvent être imbriqués. Si le projet est complexe, la quantité de code peut être considérablement simplifiée et il est également plus convivial pour exiger des modifications et une maintenance ultérieures.3 Le développement de composants implique l'encapsulation des composants js de Vue, vous devez maîtriser les bases de Vue, Méthodes et propriétés des instances Vue, Vue.extend, plug-ins Vue, etc.
Comment réaliser le développement de composants
Premier coup d'oeil à l'image ci-dessous :
C'est vue. Une erreur dans js est due à l'utilisation d'un composant non enregistré lx-xxx
. Cette erreur nous dit une vérité :
. Alors comment enregistrer un composant ? Vue.js propose deux façons d'enregistrer des composants, enregistrement global et enregistrement local
.Dans vue.js, nous pouvons utiliser Vue.component(tagName, options) pour un enregistrement global, tel que
Vue.component('my-component', { // 选项 })
2. >lx-xxx
,这个报错告诉我们一个道理:使用自定义组件之前必须注册。
那么如何注册一个组件呢? Vue.js 提供了 2 种组件的注册方式,全局注册和局部注册。
在 vue.js 中我们可以使用 Vue.component(tagName, options) 进行全局注册,例如
import HelloWorld from './components/HelloWorld' export default { components: { HelloWorld } }
Vue.js 也同样支持局部注册,我们可以在一个组件内部使用 components 选项做组件的局部注册,例如:
<lx-niu/> <lx-niu></lx-niu/> name: 'lxNiu'
区别:全局组件是挂载在 Vue.options.components
下,而局部组件是挂载在 vm.$options.components
Vue.js prend également en charge l'enregistrement local. Nous pouvons utiliser l'option composants à l'intérieur d'un composant pour effectuer l'enregistrement local du composant, par exemple :
<div>{{msg}}</div> props: { msg: { type: String, default: '' } } show: Boolean // 默认false msg: [String, Boolean] // 多种类型
Vue.options.components<. / code>, tandis que les composants locaux sont montés sous <code>vm.$options.components
, c'est pourquoi les composants enregistrés globalement peuvent être utilisés arbitrairement. Connaissances essentielles pour le développement de composants
On dit que si vous voulez bien faire votre travail, vous devez d'abord aiguiser vos outils Avant de développer officiellement un composant, nous devons d'abord maîtriser certaines connaissances nécessaires. Je ne vais que brièvement. présentez-le ici, veuillez vous référer au site officiel pour plus de détails.
nameLe nom du composant, obligatoire<div>{{newMsg}}</div> computed: { newMsg() { return 'hello ' + this.msg } },
Les propriétés des composants, utilisées pour la communication des composants parent-enfant, sont accessibles via this.msg<lx-niu tag='button'>hello world</lx-niu>
<script type="text/javascript">
export default {
name: 'lxNiu',
props: {
tag: {
type: String,
default: 'div'
},
},
// h: createElement
render(h) {
return h(this.tag,
{class: 'demo'},
this.$slots.default)
}
}
</script>
<lx-niu> <div slot='header'>header</div> <div class="body" slot='body'> <input type="text"> </div> <div slot='footer'>footer</div> <button class='btn'>button</button> </lx-niu> <template> <div> <slot name='header'></slot> <slot name='body'></slot> <slot name='footer'></slot> <slot></slot> </div> </template> <script> export default { name: 'lxNiu', mounted() { this.$slots.header // 包含了slot="foo"的内容 this.$slots.default // 得到一个vnode,没有被包含在具名插槽中的节点,这里是button } } </script>
Utilisez la fonction render pour décrire le modèle
// 父组件 <lx-niu round type='big'/> // 子组件 <div :class="[ type ? 'lx-niu__' + type : '', {'is-round': round}, ]">控制</div> //真实DOM <div class='lx-niu__big is-round'>hello</div>
args2 : {Object} Définir les styles, les attributs et les événements de liaison du DOM , etc.
args3 : {array } Utilisé pour définir le contenu à distribuerRemarque : ordre de compilation de vue : template–> compile render --> slot
// 父组件
<lx-niu :bodyStyle='{color: "red"}'/>
// 子组件
<template>
<div :style='bodyStyle'>hello world</div>
</template>
<script>
export default {
name: 'lxNiu',
props: {
bodyStyle: {},
},
}
</script>
Définir le nom de classe du sous-composant <input v-bind="$attrs">
Pa style ss au sous-composant <template>
<div>
<button @click="show = !show">button</button>
<button @click="val = '456'">button</button>
<div v-once v-if="show">
<span>{{val}}</span>
</div>
</div>
</template>
<script>
export default {
data() {
return{
show: false,
val: '123'
}
},
};
</script>
$attrs
v- bind="$attrs" ajoute des attributs autres que la classe et le style au composant parent, comme la définition de l'entrée : // mixin.js
export default {
data() {
return{
msg: 'hello world'
}
},
methods: {
clickBtn() {
console.log(this.msg)
}
},
}
// index.vue
<button @click="clickBtn">button</button>
import actionMixin from "./mixin.js";
export default {
methods: {},
mixins: [actionMixin]
}
Le composant n'est rendu qu'une seule fois, et ne sera pas restitué même si les données changent ultérieurement. Par exemple, dans l'exemple, val ne deviendra pas 456<template>
<button>lxButton</button>
</template>
<script>
export default {
name: 'lxButton'
}
</script>
// mixin.js export default { data() { return{ msg: 'hello world' } }, 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 这样一个组件,那么目录和伪代码如下:
index.vue
<template> <button>lxButton</button> </template> <script> export default { name: 'lxButton' } </script>
index.js
import lxButton from './src/index' 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('father change', val) } } } </script>
定义组件
<template> <div v-show="visible"> <button @click="hide">关闭</button> </div> </template> <script> export default { name: 'lxNiu', props: { visible: Boolean }, watch: { visible(val) { console.log('child change:', val) } }, methods: { hide() { this.$emit('update:visible', false); } }, } </script>
点击父组件中的显示
按钮,改变传入子组件中的值,点击子组件中的关闭
,改变父组件中值。
注:@click=“dialogVisible = true” 点击时将dialogVisible的值改为true
注::visible.sync: 双向数据绑定,配合update:visible使用,实现子组件修改父组件中的值
官网解释: sync
col组件实例
export default { name: 'ElCol', props: { span: { type: Number, default: 24 }, tag: { type: String, default: 'div' }, 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 !== 'ElRow') { parent = parent.$parent; } return parent ? parent.gutter : 0; } }, render(h) { let classList = []; let style = {}; if (this.gutter) { style.paddingLeft = this.gutter / 2 + 'px'; style.paddingRight = style.paddingLeft; } ['span', 'offset', 'pull', 'push'].forEach(prop => { if (this[prop] || this[prop] === 0) { classList.push( prop !== 'span' ? `el-col-${prop}-${this[prop]}` : `el-col-${this[prop]}` ); } }); ['xs', 'sm', 'md', 'lg', 'xl'].forEach(size => { if (typeof this[size] === 'number') { classList.push(`el-col-${size}-${this[size]}`); } else if (typeof this[size] === 'object') { let props = this[size]; Object.keys(props).forEach(prop => { classList.push( prop !== 'span' ? `el-col-${size}-${prop}-${props[prop]}` : `el-col-${size}-${props[prop]}` ); }); } }); return h(this.tag, { class: ['el-col', 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 ? 'el-button--' + type : '', buttonSize ? 'el-button--' + buttonSize : '', { 'is-disabled': buttonDisabled, 'is-loading': loading, 'is-plain': plain, 'is-round': round, 'is-circle': 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: 'ElButton', inject: { elForm: { default: '' }, elFormItem: { default: '' } }, props: { type: { type: String, default: 'default' }, size: String, icon: { type: String, default: '' }, nativeType: { type: String, default: 'button' }, 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('click', evt); } } }; </script>
局部组件实例
<template> <div class="login"> <login-header /> <login-request /> <login-footer /> </div> </template> <script> import loginHeader from './login-header'; import loginRequest from './login-request'; import loginFooter from './login-footer'; export default { components: { [loginHeader.name]: loginHeader, [loginRequest.name]: loginRequest, [loginFooter.name]: loginFooter } }; </script>
8. 分享总结
【相关推荐:《vue.js教程》】
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!