Vue组件基础定义
import Vue from 'vue'
const compoent = {
props: {
active: {
// type: Boolean,
// required: true,
validator (value) {
return typeof value === 'boolean'
}
},
propOne: String
},
template: `
<div>
<input type="text" v-model="text">
<span @click="handleChange">{{propOne}}</span>
<span v-show="active">see me if active</span>
</div>
`,
data () {
return {
text: 0
}
},
methods: {
handleChange () {
this.$emit('changeY')
}
}
}
// Vue.component('CompOne', compoent)
new Vue({
components: {
CompOne: compoent
},
data: {
prop1: 'test'
},
methods: {
handleChange () {
this.prop1 = this.prop1 + ' test'
}
},
mounted () {
console.log(this.$refs.comp1)
},
el: '#root',
template: `
<div>
<p>{{prop1}}</p>
<!--建议传递参用下划线命名,接收参数用驼峰-->
<!--若传参是非string,需用:-->
<!--@changeY="handleChange"接收子组件派发的change事件,这里不能@change-y="handleChange"这么写-->
<comp-one ref="comp1" :active="true" :prop-one="prop1" @changeY="handleChange"></comp-one>
<comp-one :active="true" propOne="text2"></comp-one>
</div>
`
})
Vue组件继承
import Vue from 'vue'
const compoent = {
props: {
active: Boolean,
propOne: String
},
template: `
<div>
<input type="text" v-model="text">
<p @click="handleChange">propOne参数:{{propOne}}</p>
<p v-show="active">see me if active</p>
</div>
`,
data () {
return {
text: 0
}
},
mounted () {
console.log('compoent1 comp mounted')
},
methods: {
handleChange () {
this.$emit('change')
}
}
}
const componet2 = {
extends: compoent, // 继承compoent
data () {
return {
text: 1
}
},
mounted () {
console.log('componet2', this.$parent.$options.name)
}
}
// const CompVue = Vue.extend(compoent)
// new CompVue({
// el: '#root',
// propsData: {
// propOne: 'xxx'
// },
// data: {
// text: '123'
// },
// mounted () {
// console.log('instance mounted')
// }
// })
const parent = new Vue({
name: 'parent'
})
new Vue({
parent: parent, // 设置父组件
name: 'Root',
el: '#root',
mounted () {
console.log('Root', this.$parent.$options.name)
},
components: {
Comp: componet2
},
data: {
text: '组件1'
},
methods: {
change () {
console.log('kkkkk')
}
},
template: `
<div>
<span>{{text}}</span>
<comp propOne="propOne" @change="change"></comp>
</div>
`
})
组件继承的执行顺序
Vue自定义组件双向绑定
import Vue from 'vue'
const component = {
// 使用model
model: {
// prop,子组件接收父组件通过v-model传递过来的值,可重命名为value22
prop: 'value22',
// event,该组件在派发emit 'change' 事件的时候,传递参数的值就是父组件v-model能够收到的值。
event: 'change'
},
props: ['value22'], // model中得到的prop值
template: `
<div>
<!--:value为props的值-->
<input type="text" @input="handleInput" :value="value22">
</div>
`,
methods: {
handleInput (e) {
// change为model中的event
this.$emit('change', e.target.value)
}
}
// 若不使用model接收父组件传参
// props: ['value'], // 必须要使用value
// template: `
// <div>
// <!--:value为props的值-->
// <input type="text" @input="handleInput" :value="value">
// </div>
// `,
// methods: {
// handleInput (e) {
// // 这儿必须用input发送数据,发送的数据会被父级v-model接收
// this.$emit('input', e.target.value)
// }
// }
}
new Vue({
components: {
CompOne: component
},
el: '#root',
data () {
return {
value11: '123'
}
},
template: `
<div>
<!--将父组件数据通过v-model传递给子组件-->
<comp-one v-model="value11"></comp-one>
</div>
`
})
Vue组件高级属性
import Vue from 'vue'
const ChildComponent = {
template: '<div>child component: {{data.value}}</div>',
inject: ['yeye', 'data'], // 跨级组件沟通
mounted () {
// console.log(this.yeye, this.value)
}
}
const component = {
name: 'comp',
components: {
ChildComponent
},
// template: `
// <div :style="style">
// <div class="header">
// <slot name="header"></slot>
// </div>
// <div class="body">
// <slot name="body"></slot>
// </div>
// </div>
// `,
template: `
<div :style="style">
<slot :value="value" aaa="111"></slot>
<child-component></child-component>
</div>
`,
data () {
return {
style: {
width: '200px',
height: '200px',
border: '1px solid #aaa'
},
value: 'component value'
}
}
}
new Vue({
components: {
CompOne: component
},
provide () {
const data = {}
Object.defineProperty(data, 'value', {
get: () => this.value,
enumerable: true
})
return {
yeye: this,
data
}
},
el: '#root',
data () {
return {
value: '123'
}
},
mounted () {
console.log(this.$refs.comp.value, this.$refs.span)
// 打印vue实例,dom节点,ref用在组件和原生HTML上的区别
},
template: `
<div>
<comp-one ref="comp">
<div slot-scope="props" ref="span">
<P>子组件组件内部变量:{{props.value}} {{props.aaa}}</P>
<P>当前组件变量:{{value}}</P>
</div>
</comp-one>
<input type="text" v-model="value" />
</div>
`
})
// 匿名插槽
// 具名插槽
// 作用域插槽,父组件可使用子组件中的数据slot-scope
与君共勉:再牛逼的梦想,也抵不住傻逼般的坚持!