一、prop知识点复习[父组件传值给子组件]
props 是父组件传递值给子组件,子组件接收 Props Down
因为props是单向传递,变量num=5从父组件传递给子组件,子组件想要修改num的值是不能直接修改的,需要通过emit触发父组件的方法传递值回父组件
props写法:
1、props 写成数组格式
子组件接收一个参数
props: ['initialCounter']
子组件接收一个以上参数
props: ['initialCounter','propC']
2、props 写成json格式,常用
props: {
initialCounter: {
type: String, // 类型
required: true, // 是否是必填,否为false
default: 'abc' // 默认值
},
propE: {
type: Object,
// 对象或数组默认值必须从一个工厂函数获取
default: function () {
return { message: 'hello' }
}
},
propC: {
type: String,
required: true
},
}
用prop传递一个初始值
data 定义新变量存
props: ['initialCounter'],
data: function () {
return {
counter: this.initialCounter
}
}
或者使用计算属性取默认值
props: ['initialCounter'],
data: function () {
return {
}
},
computed:{
counter(){
return this..initialCounter
}
}
用prop 以一种原始的值传入且需要进行转换
props: ['size'],
computed: {
normalizedSize: function () {
return this.size.trim().toLowerCase()
}
}
二、$emit 子组件传值给父组件
需要改变通过prop传给子组件的参数,在子组件中用$emit触发父组件的自定义事件
如:父组件传num给子组件:<tab num="5"></tab>
子组件接收:props: [num]
子组件自定义事件给父组件改变num初始值:<button @click='change('6')'>
change(data){ this.$emit('changeNum', data)}
父组件触发事件改变值
<tab num="5" @changeNum = 'changeClick'></tab>
changeClick(data){ this.num = data}
三、v-model 在子组件和父组件通信
父组件通过v-model双向绑定num值传递给子组件
<tab v-model="num" ></tab>
子组件默认接收参数value:props: [value]
子组件默认传递自定义事件input:this.$emit('input', data)
<template>
<div class="app-container">
<InputNumber v-model="parentNum" @input="change" /> // v-model 传值,@input接收事件,change重新定义的新方法名
</div>
</template>
<script>
import InputNumber from './InputNumber'
export default {
name: 'UserManager',
components: {
InputNumber
},
data() {
return {
parentNum: 5
}
},
methods: {
change(data) {
this.parentNum = data
}
}
}
</script>
子组件
<template>
<div class="inputNumber">
<button @click="change(-1)">-</button>
<input :value="value" type="text"> // :value="value" 第一个value input的value属性,第二个value是v-model默认专递给子组件的参数
<button @click="change(1)">+</button>
</div>
</template>
<script>
export default {
props: {
value: { // 默认接收value参数
type: Number,
required: true
}
},
data() {
return {
}
},
methods: {
change(data) {
this.$emit('input', this.value + data) //默认传递input事件给父组件
}
}
}
四、应用
1、InputNumber 计数器(父组件和子组件传递值)
父组件:
// 使用子组件 并从父组件传递num变量给子组件,重写子组件传递回来的方法 改变num的值
<InputNumber :num="numParent" @input-change="handleIncrementParent" />
<script>
import InputNumber from './InputNumber' // 引入子组件
export default {
components: {
InputNumber
},
data() {
return {
numParent: 5
}
},
methods: {
handleIncrementParent(evalue) { // 触发子组件传递回来的方法
this.numParent = evalue
}
}
}
</script>
子组件
<div>
<button @click="handleIncrement(-1)">-</button>
<input :value="num" type="text"> //
<button @click="handleIncrement(1)">+</button>
</div>
<script>
export default {
props: { // 接收父组件传来的num
num: {
type: Number,
required: true
}
},
data() {
return {
// num: 1 // 这里data不能重复定义num,若是需要针对这个num做处理,可以通过computed计算属性
}
},
methods: {
handleIncrement(count) {
if (this.num <= 0 && count < 0) {
this.$emit('input-change', 0)
} else {
this.$emit('input-change', this.num + count)
}
}
}
}
</script>
2、Tabs 标签页
应用页面 index(父组件)
<template>
<div class="app-container">
// 步骤4
<tabs v-model="activeName">
<tab-panes label="用户管理" name="first">用户管理1</tab-panes>
<tab-panes label="角色管理" name="second">角色管理2</tab-panes>
</tabs>
</div>
</template>
<script>
import tabs from './tab' // 步骤1
import tabPanes from './tabPanes'
export default {
name: 'UserManager',
components: { // 步骤2
tabs,
tabPanes
},
data() {
return {
activeName: 'first' // 步骤3
}
},
created() {
},
methods: {
}
}
</script>
tab子组件(index页面的子组件,tabPanes的父组件)
<template>
<div class="tab-wrapper">
<div class="tab-header">
<span v-for="item in tabPanes" :key="item.name" :class="{active: activeName == item.name}" @click="tabClick(item)">{{ item.label }}</span>
</div>
<div class="tab-body">
<slot />
</div>
</div>
</template>
<script>
export default {
props: {
value: {
type: String,
required: true
}
},
data() {
return {
tabPanes: []
}
},
computed: {
activeName() {
return this.value
}
},
mounted() {
this.tabPanes = this.$children // 这里的children为tab-panes
},
methods: {
tabClick(tab) {
this.$emit('input', tab.name)
}
}
}
</script>
tabPanes子组件
<template>
<div v-show="name == $parent.activeName"><slot /></div>
</template>
<script>
export default {
props: {
label: {
type: String,
required: true
},
name: {
type: String,
required: true
}
},
data() {
return {
}
},
mounted() {
console.log(this.$parent) // 这里的parent为tab组件
}
}
</script>
网友评论