Basic knowledge of
Component communication method
Props — Parent $emit/$ON — Parent custom event dispatch/listening event evuent bus — VuEX
$parent $child — Strong coupling reduces use of $root $ref provide/inject non-prop features: $attrs $Listeners
$emit(‘foo’) // Brother1 this.$parent.$emit(‘foo’) // Brother2 this.$parent.
$attrs $Listeners are transparently uploaded
//v-bind v-on can expand the object directly
<grandson v-bind="$attrs" v-on="$listeners" />
Copy the code
Provide/provide core
//grandpa
export default{
provide(){
return {
foo:'this is foo'.grandpa:this}}}//grandson
export default{
inject: ['foo'.'grandpa'].inject: {'alias': {}}}Copy the code
Slot content distribution
Anonymous slot
//comp1 child component placeholder
<div>
<slot></slot>
</div>
//parent
<comp>helllo</comp>
Copy the code
A named slot
//comp1 child component placeholder
<div>
<slot></slot>
<slot name='content'></slot>
</div>
//parent
<comp>
<template v-slot:default>No name by default</template>
<template v-slot:content>content</template>
</comp>
Copy the code
Scope slot
//comp1 child component placeholder
<div>
<slot :foo="foo "></slot> // The object being replaced
</div>
//parent
// Some of the data comes from the child component v-slot as a scoped context object
<comp>
<template v-slot:default="SlotProps">// Function (parameter) subcomponent data {{slotProps. Foo}}</template>
</comp>
Copy the code
Generic form component
Implementation content: collect and verify data
The index page
<template>
<MForm :model="model" :rules="rules" ref="loginForm">
<MFormItem label="Username:" prop="username">
<MInput v-model="model.username" placeholder="Please enter"</MInput>
</MFormItem>
<MFormItem>
<button @click="onLogin">The login</button>
</MFormItem>
</MForm>
</template>
<script>
import MInput from './MInput'
import MFormItem from './MFormItem'
import MForm from './MForm'
export default{
components:{
MForm,
MFormItem,
MInput
},
data(){
return {
model: {username:' '.rules: {username: [{required:true.message:"Username Required"}]}}}},methods: {onLogin(){
this.$refs.loginForm.validate(isValid= >{
if(isValid){
//login
}else{
console.log('failure! ')}})}}}</script>
Copy the code
[Input component] Bidirectional binding component <template><div>
<input type="text" :value="value" @input="onInput"
v-bind="$attrs"
/>
</div>
</template>
<script>
inheritAttrs:false.// Do not assign attributes to the root component
export default{
props: {value: {type:String.default:' '}},methods: {onInput(e){
this.$emit('input',e.target.value)
// Notify validation
// this. Dispatch ('el-form-item','validate') // this. Dispatch ('el-form-item','validate'
this.$parent.$emit('validate')}}}</script>
<style></style>
Copy the code
[my-form-item] <template><div>
<label v-if="label">{{label}}</label>
<slot></slot>
<p v-if="error">{{error}}</p>
<p>{{form.rules[prop]}}</p>
</div>
</template>
<script>import Validator from 'async-validator' export default{ inject:['form'], props:{ label:{ type:String, default:'' }, prop:String }, data(){ return { error:' } }, mounted(){ this.$on('validate',()=>{ this.validate() }) }, Methods :{validate(){const rules = this.form.rules[this.prop] const value = This.form. model[this.prop] const validator = new validator ({[this.prop]:rules}) // Return Promise return validator.validate({[this.prop]:value},(errors)=>{ if(errors){ this.error = errors[0].message }else{ this.error='' } }) } } }</script>
Copy the code
[my-form] model, rules <template><div>
<slot></slot>
</div>
</template>
<script>
export default{
components:{
},
props: {model: {type:Object.required:true
},
rules:Object
},
// Pass to form item next generation
provide(){
return{
form:this}},data(){
return{}},methods: {validate(cb){
// Iterate over all item validation methods with prop attributes
const promises=this.$children.filter(item= >item.prop)
.map(item= >item.validate())
// All passes pass
Promise.all(promises).then(() = >cb(true)).catch(() = >cb(false))}}}</script>
Copy the code