组件通信-父组件向子组件传递数据
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Document</title>
</head>
<body>
<div id="app">
<cpn v-bind:cmessage="message" v-bind:cmovies="movies"></cpn>
</div>
<template id="cpn">
<div>
<h2>这是一个cpn标题</h2>
<ul>
<li v-for="item in cmovies">{
{item}}</li>
</ul>
<p>{
{cmessage}}</p>
</div>
</template>
<script src="../js/vue.js"></script>
<script>
const cpn = {
template: "#cpn",
// 对象形式
props: {
cmessage: {
type: String,
// 默认值
default: "aaaa",
// 必须传值
required: true
},
// 类型是对象或者数组时,默认值必须是一个函数
cmovies: {
type: Array,
default() {
return []
}
}
}
}
const app = new Vue({
el: "#app",
data: {
message: "你好",
movies: ["海王", "火影忍者", "进击的巨人", "星际穿越"]
},
components: {
cpn
}
})
</script>
</body>
</html>
1.父组件如何向子组件传递信息
- 在子组件的props中定义cmessage和cmovies,并标出基数据类型。代码如下:
// 无属性要求
props:{
// 1.类型限制
cmovies: Array,
cmessage: String
// 2.多种类型
cname: [String, Array]
// 3.类型种类
// String, Number, Boolean, Array, Object, Data, Function, Symbol
// 4.自定义种类
function Person(firstName, lsatName) {
}
author: Person
}
// 有属性要求
props: {
cmessage: {
// 变量类型
type: String,
// 变量默认值
default: "aaaa",
// 父组件是否必须传值
required: true
},
// 类型是对象或者数组时,默认值必须是一个函数
cmovies: {
type: Array,
default() {
return []
}
}
}
- 父组件在调用子组件时将本组件的信息传入,父组件中使用v-bind将子组件中的变量名绑定,绑定的信息为父组件中想要传递的信息变量。代码如下:
<cpn v-bind:cmessage="message" v-bind:cmovies="movies"></cpn>
- 此时即可在子组件中使用在props中定义的变量,子组件中cmessage的值等于父组件中message的值,同理子组件中cmovies的值等于父组件中movies的值。子组件模版代码如下:
<template id="cpn">
<div>
<h2>这是一个cpn标题</h2>
<ul>
<li v-for="item in cmovies">{
{item}}</li>
</ul>
<p>{
{cmessage}}</p>
</div>
</template>
效果图如下:
组件通信-子组件向父组件传递数据
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Document</title>
</head>
<body>
<!-- 父组件模版 -->
<div id="app">
<cpn @item-click="cpnClick"></cpn>
</div>
<!-- 子组件模版 -->
<template id="cpn">
<div>
<button
v-for="item in categories"
:key="item.id"
@click="btnClick(item)"
>
{
{item.name}}
</button>
</div>
</template>
<script src="../js/vue.js"></script>
<script>
// 1.子组件
const cpn = {
template: "#cpn",
data() {
return {
categories: [
{
id: "aaa", name: "热门推荐" },
{
id: "bbb", name: "手机数码" },
{
id: "ccc", name: "家用家电" },
{
id: "ddd", name: "电脑办公" }
]
}
},
methods: {
btnClick(item) {
// 子组件将得到的数据传递给父组件
// 发射一个事件
this.$emit("item-click", item)
}
}
}
// 2.父组件
const app = new Vue({
el: "#app",
data: {
message: "你好"
},
components: {
cpn
},
methods: {
cpnClick(item) {
console.log("cpnClick", item.id, item.name)
}
}
})
</script>
</body>
</html>
1.子组件如何向父组件传递信息
- 在子组件的data变量中定义想要传递给父组件的内容。代码如下:
const cpn = {
template: "#cpn",
data() {
return {
categories: [
{
id: "aaa", name: "热门推荐" },
{
id: "bbb", name: "手机数码" },
{
id: "ccc", name: "家用家电" },
{
id: "ddd", name: "电脑办公" }
]
}
}
}
- 子组件绑定点击事件,向父组件发射数据。代码如下:
<template id="cpn">
<div>
<button
v-for="item in categories"
:key="item.id"
@click="btnClick(item)"
>
{
{item.name}}
</button>
</div>
</template>
methods: {
btnClick(item) {
// 子组件发射一个事件将得到的数据传递给父组件
this.$emit("item-click", item)
}
}
- 父组件在调用子组件时在本地新建一个事件接收数据传递,v-bind绑定发射的事件名,注意此时父组件的在调用本组件函数时不用传递参数。代码如下:
<cpn @item-click="cpnClick"></cpn>
methods: {
cpnClick(item) {
console.log("cpnClick", item.id, item.name)
}
}
效果图如下:
组件访问-父访问子(children/refs)
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Document</title>
</head>
<body>
<div id="app">
<cpn></cpn>
<cpn ref="test"></cpn>
<button @click="btnClick1">按钮1</button>
<button @click="btnClick2">按钮2</button>
</div>
<template id="cpn">
<div>
我是子组件
</div>
</template>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: "#app",
data: {
message: "你好"
},
methods: {
btnClick1() {
// 1.$children
console.log(this.$children)
console.log(this.$children[1].name)
},
btnClick2() {
// 2.$refs => 对象类型,默认是一个空的对象 ref='test'
// 可以获得指定的子组件,一般都是用这种
console.log(this.$refs.test.name)
}
},
components: {
cpn: {
template: "#cpn",
data() {
return {
name: "我是子组件的name"
}
}
}
}
})
</script>
</body>
</html>
1.$children的使用场景
有时同一个子组件,在父组件中可能会用到多次,那么在父组件中想使用子组件中的data变量,即可使用$ c h i l d r e n children children直接获得。如上文代码中,父组件多次使用子组件,则在父组件中打印children可以遍历所有的子组件。代码如下:
<div id="app">
<cpn></cpn>
<cpn></cpn>
<button @click="btnClick1">按钮1</button>
<button @click="btnClick2">按钮2</button>
</div>
methods: {
btnClick1() {
console.log(this.$children)
console.log(this.$children[1].name)
}
}
效果图如下:
2.$refs的使用场景
看了$ c h i l d r e n children children之后,我想大家都意识到一个问题,就是父组件中需要确定子组件的下标,这在开发中肯定是不方便的,而$refs能帮我们找到指定的子组件,只需在调用子组件时添加一个标记即可。代码如下:
<div id="app">
<cpn></cpn>
<cpn ref="test"></cpn>
<button @click="btnClick1">按钮1</button>
<button @click="btnClick2">按钮2</button>
</div>
methods: {
btnClick2() {
// 可以获得指定的子组件,一般都是用这种
console.log(this.$refs.test.name)
}
}
效果图如下:
组件访问-子访问父(parent/root)
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Document</title>
</head>
<body>
<div id="app">
<cpn></cpn>
</div>
<template id="cpn">
<div>
<!-- 我是子组件
<button @click="btnClick">按钮</button> -->
<h2>我是cpn组件</h2>
<ccpn></ccpn>
</div>
</template>
<template id="ccpn">
<div>
我是子组件
<button @click="btnClick">按钮</button>
</div>
</template>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: "#app",
data: {
message: "你好"
},
components: {
cpn: {
template: "#cpn",
data() {
return {
name: "这是cpn组件的name"
}
},
components: {
ccpn: {
template: "#ccpn",
methods: {
btnClick() {
// 1.访问父组件$parent
console.log(this.$parent);
console.log(this.$parent.name);
// 2.访问根组件$root
console.log(this.$root)
console.log(this.$root.message)
}
}
}
}
}
}
})
</script>
</body>
</html>
1.上文代码逻分析
你猜的没错,又是套娃,准确的说是父组件也有自己的父组件。那子组件使用$ p a r e n t parent parent访问自己的父组件,使用$root访问自己的根组件(太太太太…太爷爷)。效果图如下:
第一次记录自己的学习笔记,如果您发现问题,欢迎指点。