Home > Article > Web Front-end > What does vue component development mean?
In Vue, component development refers to splitting complex business into multiple components, and the CSS, JS, templates, pictures and other resources that each component depends on are developed and maintained together. Because components are independent of resources, they can be reused within the system, greatly simplifying the amount of code, and are more friendly to later demand changes and maintenance.
The operating environment of this tutorial: windows7 system, vue2.9.6 version, DELL G3 computer.
What is componentization
vue.js has two major One magic weapon is data-driven and the other is componentization. So the question is, what is componentization and why is it necessary? Next, I will answer these two questions one by one. The so-called componentization is to split the page into multiple components, and the CSS, JS, templates, pictures and other resources that each component depends on are developed and maintained together. . Because components are independent of resources, they can be reused within the system, and components can be nested. If the project is complex, the amount of code can be greatly simplified, and later demand changes and maintenance will be easier. friendly.
1. Component-based development refers to splitting complex business into components one after another
2. Components developed through component-based development generally need to be flexible
3. Component development involves Vue’s js component encapsulation, and you need to master the basics of Vue, Vue instance methods and properties, Vue.extend, Vue plug-ins, etc.
How to carry out component development
First look at the picture below:
This is an error in vue.js. The reason is that an unregistered component lx-xxx
is used. This error tells us a truth: You must register before using a custom component.
So how to register a component? Vue.js provides two ways to register components, global registration and local registration.
In vue.js we can use Vue.component(tagName, options) for global registration, such as
Vue.component('my-component', { // 选项 })
Vue.js also supports partial registration. We can use the components option inside a component to do partial registration of the component, for example:
import HelloWorld from './components/HelloWorld' export default { components: { HelloWorld } }
Difference : Global components are mounted under Vue.options.components
, while local components are mounted under vm.$options.components
, which are also globally registered components. can be used arbitrarily.
It is said that if you want to do your job well, you must first sharpen your tools. Before formally developing a component, we must first To master some necessary knowledge, I will only briefly introduce it here. Please refer to the official website for details.
name
The name of the component, required
<lx-niu/> <lx-niu></lx-niu/> name: 'lxNiu'
Use camel case commands in js, kebab-case for HTML name.
props
Component properties, used for parent-child component communication, can be accessed through this.msg
<div>{{msg}}</div> props: { msg: { type: String, default: '' } } show: Boolean // 默认false msg: [String, Boolean] // 多种类型
computed
Process the attributes in data or props and return a new attribute
<div>{{newMsg}}</div> computed: { newMsg() { return 'hello ' + this.msg } },
Note: Because props, data and computed will be used as vm during the compilation phase The attributes are merged, so the name cannot be repeated
render
Use the render function to describe the h in template
<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>
render In fact It is createElement, which accepts three parameters and returns a vnode
h Parameter explanation:
args1: {string | Function | Object} is used to provide the html content of the DOM
args2: {Object} sets the DOM style, Properties, binding events, etc.
args3: {array} is used to set the distributed content
Note: vue compilation sequence: template–> compile --> render --> vnode -- > patch --> DOM
slot
##
<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>
class
Define the class name of the subcomponent// 父组件 <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>
style
Transfer style to the subcomponent// 父组件 <lx-niu :bodyStyle='{color: "red"}'/> // 子组件 <template> <div :style='bodyStyle'>hello world</div> </template> <script> export default { name: 'lxNiu', props: { bodyStyle: {}, }, } </script>
Other attributes
$attrs
v-bind="$attrs" will be removed Attributes outside class and style are added to the parent component, such as defining input:<input v-bind="$attrs">
v-once
The component is only rendered once, even if the data changes later. It will be re-rendered. For example, in the example, val will not become 456<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>
mixins
// 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教程》】
The above is the detailed content of What does vue component development mean?. For more information, please follow other related articles on the PHP Chinese website!