全局组件和局部组件
全局组件写法
// MyComponent.vue
<template>
<div>{{ name }}</div>
</template>
<script>
export default {
data() {
return {
name: 'crj'
};
}
}
</script>
import Vue from 'vue'
import App from './App.vue'
import MyComponent from '@/components/MyComponent.vue'; // 导入自己写的组件文件
Vue.use(MyComponent); // 自定义全局组件的时候需要Vue.use();
Vue.component('my-component', MyComponent); //初始化组件
new Vue({
render: h => h(App)
}).$mount('#app')
// 使用
<template>
<div class="contentViews">
<my-component/>
</div>
</template>
局部组件写法
<template>
<div class="contentViews">
<childZJ/>
</div>
</template>
<script>
import childZJ from "./childZJ.vue"
export default {
components: {
childZJ
}
}
</script>
父组件 => 子组件
属性 props
父组件:parentZJ
<template>
<div class="contentViews">
<childZJ msg="crj" />
</div>
</template>
<script>
import childZJ from "./childZJ.vue"
export default {
components: {
childZJ
}
}
</script>
子组件:childZJ
<template>
<div>
{{ msg }}
</div>
</template>
<script>
export default {
props: {
msg: {
type: String,
default: "c",
required: true
}
}
or
props: ['msg']
}
</script>
引用 refs、子元素 children
父组件:parentZJ
<template>
<div class="contentViews">
<!--用ref给子组件起个名字-->
<childZJ ref="childZJRef" />
</div>
</template>
<script>
import childZJ from "./childZJ.vue"
export default {
components: {
childZJ
},
mounted() {
// 取得子组件的属性,childZJRef是上边ref起的名字,crj是子组件的属性,方法同理。
this.$refs.childZJRef.crj = 'meng'
this.$children[0].crj = 'chen'
}
}
</script>
子组件:childZJ
<template>
<div>
{{ crj }}
</div>
</template>
<script>
export default {
data() {
return {
crj: 'cheng'
};
}
}
</script>
自定义组件在使用 v-model
父组件:parentZJ
<template>
<div class="contentViews">
<!-- 允许一个自定义组件在使用 v-model 时定制 prop 和 event。
默认情况下,一个组件上的 v-model 会把 value 用作 prop 且把 input 用作 event,
但是一些输入类型比如单选框和复选框按钮可能想使用 value prop 来达到不同的目的。
使用 model 选项可以回避这些情况产生的冲突。
-->
<childZJ v-model="crj"/>
</div>
</template>
<script>
import childZJ from "./childZJ.vue"
export default {
components: {
childZJ
},
data() {
return {
crj: 'cheng'
};
}
}
</script>
子组件:childZJ
<template>
<div>
<el-input @input="handleChange" :value="currentValue" />
</div>
</template>
<script>
export default {
props: ['value'],
data() {
return {
currentValue: this.value
}
},
watch: {
value: {
handler(newVal) {
this.currentValue = newVal;
},
// 代表在wacth里声明了a这个方法之后立即先去执行handler方法,如果设置了false,那么效果和上边例子一样
immediate: true,
deep: true
}
},
methods: {
handleChange(value) {
this.currentValue = value;
this.$emit('input', this.currentValue)
}
}
}
</script>
子组件 => 父组件:自定义事件
父组件:parentZJ
<template>
<div class="contentViews">
<childZJ ref="childZJRef" @add="cartAdd"/>
<!--父组件中通过监测add事件执行一个方法cartAdd,然后取到子组件中传递过来的值-->
</div>
</template>
<script>
import childZJ from "./childZJ.vue"
export default {
components: {
childZJ
},
methods: {
cartAdd(e, crj) {
console.log(e, crj);
}
}
}
</script>
子组件:childZJ
<template>
<div>
<div @click="$emit('add', $event, crj)">点击</div>
<div @click="handleAdd($event)">点击</div>
</div>
</template>
<script>
export default {
data() {
return {
crj: 'cheng'
};
},
methods: {
handleAdd(e) {
// 通过按钮的点击事件触发方法,然后用$emit触发一个add的自定义方法,传递this.crj数据。
this.$emit('add', e, this.crj)
}
}
}
</script>
兄弟组件:通过共同祖辈组件
父组件:parentZJ
<template>
<div class="contentViews">
<childZJ/>
<childZJTwo/>
</div>
</template>
<script>
import childZJ from "./childZJ.vue"
import childZJTwo from "./childZJTwo.vue"
export default {
components: {
childZJ,
childZJTwo
}
}
</script>
子组件一:childZJ
<template>
<div>
<div @click="handleAdd">点击</div>
</div>
</template>
<script>
export default {
data() {
return {
crj: 'cheng'
};
},
methods: {
handleAdd() {
this.$parent.$emit('add', this.crj)
}
}
}
</script>
子组件二:childZJTwo
<template>
<div>{{ name }}</div>
</template>
<script>
export default {
data() {
return {
name: ''
};
},
created() {
this.$parent.$on('add', (crj) => {
this.name = crj;
})
}
}
</script>
祖先和后代之间
父组件:parentZJ
<template>
<div>
<h3>当前主题色为{{ theme }}</h3>
<button @click="changeTheme('blue')">蓝色</button>
<button @click="changeTheme('green')">绿色</button>
<button @click="changeTheme('red')">红色</button>
<hr>
<childZJ></childZJ>
</div>
</template>
<script>
import childZJ from './childZJ.vue'
export default {
components: {
childZJ
},
provide() {
return {
theme: this.theme,
changeTheme: this.changeTheme
}
},
data() {
return {
theme: 'blue'
}
},
methods: {
changeTheme(theme) {
this.theme = theme
}
}
}
</script>
子组件:childZJ
<template>
<div>
<childZJTwo />
</div>
</template>
<script>
import childZJTwo from './childZJTwo.vue'
export default {
components: {
childZJTwo
}
}
</script>
孙组件:childZJTwo
<template>
<div>
<h3>我是子组件</h3>
<p>当前主题色为:{{theme}}</p>
<button @click="changeTheme1('blue')">蓝色</button>
<button @click="changeTheme1('green')">绿色</button>
<button @click="changeTheme1('red')">红色</button>
</div>
</template>
<script>
export default {
inject: ['theme', 'changeTheme'],
mounted() {
console.log(this.theme) // blue
},
methods: {
changeTheme1(theme) {
this.changeTheme(theme)
}
}
}
</script>
任意两个组件之间:事件总线 或 vuex
main.js
import Vue from 'vue'
import App from './App.vue'
//关闭Vue的生产提示
Vue.config.productionTip = false
//创建vm
new Vue({
el:'#app',
render: h => h(App),
// beforeCreate中模板未解析,且this是vm
beforeCreate(){
Vue.prototype.$bus = this //安装全局事件总线
}
})
TestA.vue:
<template>
<div>
<h2>姓名:{{name}}</h2>
<button @click="sendName">给TestB组件传递数据</button>
</div>
</template>
<script>
export default {
name:'TestA',
data(){
return{
name:'路飞'
}
},
methods:{
// 触发事件,事件名不能重复
sendName(){
this.$bus.$emit('lufei', this.name);
}
},
}
</script>
TetsB.vue:
<template>
<div>
<h2>籍贯:{{native}}</h2>
<h2>家庭住址:{{adress}}</h2>
</div>
</template>
<script>
export default {
name:'TestB',
data(){
return{
native:'东海',
adress:'东海风车村',
}
},
mounted(){
// 绑定事件
this.$bus.$on('lufei', (data)=>{
console.log('我是TestB组件,收到了数据', data);
})
},
// 销毁对应自定义事件
beforeDestroy(){
this.$bus.$off('lufei')
}
}
</script>
方法二
自定义:eventBus.js
// 模拟vuex
import Vue from 'vue'
const eventBus = new Vue()
export default eventBus
或者
// Bus :事件派发、监听和回调管理
class Bus {
constructor() {
this.callbacks = {}
}
$on(name,fn) {
this.callbacks[name] = this.callbacks[name] || []
this.callbacks[name].push(fn)
}
$emit(name,args) {
if (this.callbacks[name]) {
this.callbacks[name].forEach(cb => cb(args));
}
}
}
export default Bus
main.js
import EventBus from './components/eventBus.js'
Vue.prototype.$bus = new EventBus()
TestA.vue
this.$bus.$on('foot', this.handle)
methods: {
handle(val) {
console.log(val);
}
}
TetsB.vue
this.$bus.$emit('foot', '11233')