vue系列文章目录
第一章:Vue基础知识笔记(模板语法、数据绑定、事件处理、计算属性)(一)
第二章:Vue基础知识(计算属性、监视属性、computed和watch之间的区别、绑定样式)(二)
第三章:Vue基础知识(条件渲染、列表渲染、收集表单数据、过滤器)(三)
第四章:Vue基础知识(内置指令、自定义指令、Vue生命周期)(四)
第五章:Vue基础知识之组件机制(非单文件组件、单文件组件)(五)
第六章:Vue创建脚手架(六)
第七章:Vue使用脚手架(ref、props、mixin、插件、scoped)(七)
第八章:Vue组件通信(组件的自定义事件、全局事件总线、消息订阅与发布、插槽、props)(八)
第九章:Vue使用脚手架(nextTick、Vue封装的过度与动画、vue脚手架配置代理)(九)
第十章:Vuex(十)
第十一章:vue-router(基本使用、路由重定向、多级路由、路由命名、路由的query和params参数、路由的props配置)(十一)
第十二章:vue-router(路由的两种工作模式、router-link的replace属性、编程式路由导航、缓存路由组件keep-alive、路由守卫【全局路由守卫、独享路由守卫、组件内路由守卫】)(十二)
转跳 -> Vue3相关文章
承接第八章组件通信继续拓展
文章目录
一、v-model(实现父子组件数据同步)
v-model: 指令,可以收集表单数据【text、radio、checkbox、range】等等 切记:v-model收集checkbox需要用数组收集
v-model:实现原理 : 通过value和 @input ,实现父子数据同步
代码片段:
Parent.vue
<template>
<div>
<h2>父组件-v-model</h2>
<input type="text" v-model="msg" />
<span>{{ msg }}</span>
<br />
<h2>父组件-value和input事件实现v-model</h2>
<!-- 原生DOM当中是有oninput事件:当表单元素发生文本的变化的时候就会立即出发,通过value和input事件实现v-model -->
<input type="text" :value="msg" @input="msg = $event.target.value" />
<span>{{ msg }}</span>
<!--并非原生DOM:自定义组件-->
<!-- 通过value和input事件实现v-model,此处的input为自定义事件 -->
<Children :value="msg" @input="msg = $event"></Children>
<Children v-model="msg"></Children>
<hr />
</div>
</template>
<script type="text/ecmascript-6">
import Children from "./Children.vue";
export default {
name: "Parent",
data() {
return {
msg: "哈哈哈",
};
},
components: {
Children,
},
};
</script>
Children.vue
<template>
<div style="background: #ccc; height: 50px">
<h2>孩子组件----{{ value }}</h2>
<!-- 通过发送父组件的自定义事件,同步数据 -->
<input :value="value" @input="$emit('input', $event.target.value)" />
</div>
</template>
<script type="text/ecmascript-6">
export default {
name: "Children",
props: ["value"],
};
</script>
运行结果:
二、属性修饰符.sync(实现父子组件数据同步)
将.sync修饰符设置在父组件传递给子组件的数据上,可以实现父子数据同步
代码案例:
Parent.vue
<template>
<div>
小明的爸爸现在有{{ money }}元
<h2>不使用sync修改符</h2>
<Children :money="money" @update:money="money = $event"></Children>
<h2>使用sync修改符</h2>
<!-- -->
<Children :money.sync="money"></Children>
</div>
</template>
<script type="text/ecmascript-6">
import Children from "./Children.vue";
export default {
name: "Parent",
data() {
return {
money: 10000,
};
},
components: {
Children,
},
};
</script>
Children.vue
<template>
<div style="background: #ccc; height: 50px">
<span>小明每次花100元</span>
<button @click="$emit('update:money', money - 100)">花钱</button>
爸爸还剩 {{ money }} 元
</div>
</template>
<script type="text/ecmascript-6">
export default {
name: "Children",
props: ["money"],
};
</script>
运行结果:
三、$ attrs与$ listeners
$attrs: 组件实例的属性,可以获取到父亲传递的props数据
(前提子组件没有通过props接受)
$listeners: 组件实例的属性,可以获取到父亲传递自定义事件
(对象形式呈现
)
代码案例:
Parent.vue
<template>
<div>
<h2>自定义带Hover提示的按钮</h2>
<!-- 二次封装的HintButton按钮的时候,把人家el-button需要的数据传递过去 -->
<Children
type="success"
icon="el-icon-plus"
title="我是中国人"
@click="handler"
/>
</div>
</template>
<script type="text/ecmascript-6">
import Children from "./Children";
export default {
name: "Parent",
components: {
Children,
},
methods: {
handler() {
alert("弹弹弹");
},
},
};
</script>
Children.vue
<template>
<div>
<a :title="title">
<!-- v-bind动态绑定属性 -->
<el-button v-bind="$attrs" v-on="$listeners">添加</el-button>
</a>
</div>
</template>
<script>
export default {
name: "Children",
props: ["title"],
mounted() {
//this.$attrs:可以获取到父亲传递的数据【props】
//this.$attrs是可以获取父亲传递的props数据,如果子组件通过
//props:[],接受的属性,this.$attrs是获取不到的
console.log(this.$attrs);
console.log(this.$listeners);
},
};
</script>
运行结果:
四、refs.$ children与refs.$ parent
• ref可以获取到某一个组件,子组件的数据
可以在父组件内部获取子组件—实现父子通信
• $children: 可以在父组件内部获取全部的子组件
【返回数组】
• $parent: 可以在子组件内部获取唯一的父组件
【返回组件实例】
代码案例:
Parent.vue
<template>
<div>
<h2>BABA有存款: {{ money }}</h2>
<button @click="JieQianFromXM(100)">找小明借钱100</button><br />
<button @click="JieQianFromXH(150)">找小红借钱150</button><br />
<button @click="JieQianAll(200)">找所有孩子借钱200</button><br />
<button @click="SendInfo">我是baba</button>
<br />
<!-- 小明 -->
<Son ref="xm" />
<br />
<!-- 小红 -->
<Daughter ref="xh" />
</div>
</template>
<script>
import Son from "./Son";
import Daughter from "./Daughter";
export default {
name: "Parent",
data() {
return {
money: 1000,
};
},
mounted() {
console.log(this.$refs.xm);
console.log(this.$refs.xh);
},
methods: {
//找儿子借钱
JieQianFromXM(money) {
//父组件的数据累加100
this.money += money;
this.$refs.xm.money -= money;
},
JieQianFromXH(money) {
//父组件的数据累加150
this.money += money;
this.$refs.xh.money -= money;
},
JieQianAll(money) {
this.money += 2 * money;
this.$children.forEach((item) => (item.money -= money));
//不建议用枚举获取子组件:因为没办法确定到底是那个子组件
// this.$children[0].money -=money;
},
SendInfo() {
//在父组件中获取到子组件(数据+方法)
this.$refs.xm.tinghua();
},
},
components: {
Son,
Daughter,
},
};
</script>
Daughter.vue
<template>
<div style="background: #ccc; height: 50px">
<h3>女儿小红: 有存款: {{ money }}</h3>
<button @click="geiQian(50)">给BABA钱: 50</button>
</div>
</template>
<script>
export default {
name: "Daughter",
data() {
return {
money: 50000,
};
},
methods: {
geiQian(money) {
this.money -= money;
this.$parent.money += money;
},
},
};
</script>
Son.vue
<template>
<div style="background: #ccc; height: 50px">
<h3>儿子小明: 有存款: {{ money }}</h3>
<button @click="geiQian(50)">给BABA钱: 50</button>
</div>
</template>
<script>
export default {
name: "Son",
data() {
return {
money: 30000,
};
},
methods: {
tinghua() {
console.log("我是小明,我听爸爸的话");
},
geiQian(money) {
this.money -= money;
this.$parent.money += money;
},
},
};
</script>
运行结果:
五、provide与inject
由祖先组件使用provide方法传递数据
provide(){
return {
//传递的数据
"属性名":属性值/this.msg
}
}
由子孙组件使用inject注入数据
inject:['属性',"属性"]
代码案例:
Parent.vue
<template>
<div>
<h3>Parent</h3>
{{ money }}
<hr />
<Children></Children>
</div>
</template>
<script type="text/ecmascript-6">
import Children from "./Children.vue";
export default {
name: "Parent",
data() {
return {
money: 10000,
};
},
components: {
Children,
},
provide() {
return {
money: this.money,
};
},
};
</script>
Children.vue
<template>
<div>
<h3>Children</h3>
<hr />
<grandChildren></grandChildren>
</div>
</template>
<script>
import grandChildren from "./grandChildren.vue";
export default {
name: "Children",
components: {
grandChildren,
},
};
</script>
grandChildren.vue
<template>
<div>
<h3>grandChildren</h3>
{{ money }}
</div>
</template>
<script>
export default {
name: "grandChildren",
inject: ["money"],
};
</script>
运行结果: