目录
组件数据存放二
双向绑定案例
methods
实现
<div id="app">
<my-input :input="inputVule" @change="changeVal" />
</div>
<template id="my-input">
<div>
<input type="text" v-model="value" @input="change" />
<!-- 等同于 -->
<!-- <input type="text" @input="change(value = $event.target.value)" /> -->
<p>props 当前值:{{ input }}</p>
<p>data 当前值:{{ value }}</p>
</div>
</template>
<script type="text/javascript">
const app = new Vue({
el: '#app',
data:{
inputVule: ‘props value’
},
methods:{
changeVal(value) {
this.inputVule = value
}
},
components:{
'my-input': {
props: {
input : String
},
template: '#my-input',
methods: {
change() {
this.$emit('change', this.value)
}
},
data() {
return {
value: 'data value'
}
}
}
}
})
</script>
watch
实现
<div id="app">
<my-input @change="changeVal" :input="inputVule" />
</div>
<template id="my-input">
<div>
<input type="text" v-model="value" />
<p>props 当前值:{{ input }}</p>
<p>data 当前值:{{ value }}</p>
</div>
</template>
<script type="text/javascript">
const app = new Vue({
el: '#app',
data:{
inputVule: 'props value'
},
methods:{
changeVal(value) {
this.inputVule = value
}
},
components:{
'my-input': {
props: {
input : String
},
template: '#my-input',
data() {
return {
value: 'data value'
}
},
watch: {
value(newVal, oldVal) {
console.log(newVal)
console.log(oldVal)
this.$emit('change', newVal) }
}
}
}
})
</script>
父组件中使用 v-model
一个组件上的 v-model
默认会利用名为 value
的 prop 和名为 input
的事件,但是像单选框、复选框等类型的输入控件可能会将 value
attribute 用于不同的目的。model
选项可以用来避免这样的冲突:
<div id="app">
<my-checkbox v-model="checkValue" />
</div>
<template id="my-checkbox">
<div>
<input type="checkbox" :checked="checked" @change="changeVal" />
<p>props 当前值:{{ checked }}</p>
<p>data 当前值:{{ value }}</p>
</div>
</template>
<script type="text/javascript">
const app = new Vue({
el: '#app',
data:{
checkValue: false
},
components:{
'my-checkbox': {
props: {
checked : Boolean
},
model: {
prop: 'checked',
event: 'change'
},
template: '#my-checkbox',
data() {
return {
value: false
}
},
methods: {
changeVal(event) {
this.value = event.target.checked
this.$emit('change', this.value)
}
}
}
}
})
</script>
父子组件访问方式
有时候我们需要父组件直接访问子组件,子组件直接访问父组件,或者是子组件访问跟组件。
父组件访问子组件:使用 $children
或 $refs
。
子组件访问父组件:使用 $parent
。
$children
<div id="app">
<parent-c></parent-c>
</div>
<template id="parent">
<div>
<button @click="getChildC">获取所有子组件信息</button>
<child-c1></child-c1>
<child-c2></child-c2>
</div>
</template>
<template id="child1">
<div>
<p>{{ msg }}</p>
</div>
</template>
<template id="child2">
<div>
<p>{{ msg }}</p>
</div>
</template>
<script type="text/javascript">
Vue.component('parentC', {
template: '#parent',
methods: {
getChildC() {
const children = this.$children;
for (let child of children) {
console.log(child.msg);
}
}
},
components:{
'child-c1': {
template: '#child1',
data() {
return {
msg: '我是子组件1信息'
}
}
},
'child-c2': {
template: '#child2',
data() {
return {
msg: '我是子组件2信息'
}
}
}
}
})
const app = new Vue({
el: '#app'
})
</script>
$refs
$children
有个缺陷,通过 $children
访问子组件时,是一个数组类型,访问其中的子组件必须通过索引值。但是当子组件过多,我们需要拿到其中一个时,往往不能确定它的索引值,甚至还可能会发生变化。有时候,我们想明确获取其中一个特定的组件,这个时候就可以使用 $refs
。
$refs
和 ref
指令通常是一起使用的。
我们先通过 ref
给某一个子组件绑定一个特定的 ID。再通过this.$refs.ID
就可以访问到该组件了。
<div id="app">
<parent-c></parent-c>
</div>
<template id="parent">
<div>
<button @click="getChildC">获取所有子组件信息</button>
<child-c1 ref="child1"></child-c1>
<child-c2 ref="child2"></child-c2>
</div>
</template>
<template id="child1">
<div>
<p>{{ msg }}</p>
</div>
</template>
<template id="child2">
<div>
<p>{{ msg }}</p>
</div>
</template>
<script type="text/javascript">
Vue.component('parentC', {
template: '#parent',
methods: {
getChildC() {
/* const children = this.$children;
for (let child of children) {
console.log(child.msg);
} */
console.log(this.$refs.child1.msg);
console.log(this.$refs.child2.msg);
}
},
components:{
'child-c1': {
template: '#child1',
data() {
return {
msg: '我是子组件1信息'
}
}
},
'child-c2': {
template: '#child2',
data() {
return {
msg: '我是子组件2信息'
}
}
}
}
})
const app = new Vue({
el: '#app'
})
</script>
$parent
如果我们想在子组件中直接访问父组件,可以通过$parent
。
<div id="app">
<parent-c></parent-c>
</div>
<template id="parent">
<div>
<button @click="getChildC">获取所有子组件信息</button>
<child-c1 ref="child1"></child-c1>
<child-c2 ref="child2"></child-c2>
</div>
</template>
<template id="child1">
<div @click="showParent">
<p>{{ msg }}</p>
</div>
</template>
<template id="child2">
<div @click="showParent">
<p>{{ msg }}</p>
</div>
</template>
<script type="text/javascript">
Vue.component('parentC', {
template: '#parent',
data() {
return {
msg: '我是父组件信息'
}
},
methods: {
getChildC() {
/* const children = this.$children;
for (let child of children) {
console.log(child.msg);
} */
console.log(this.$refs.child1.msg);
console.log(this.$refs.child2.msg);
}
},
components:{
'child-c1': {
template: '#child1',
data() {
return {
msg: '我是子组件1信息'
}
},
methods: {
showParent() {
console.log(this.$parent.msg)
}
}
},
'child-c2': {
template: '#child2',
data() {
return {
msg: '我是子组件2信息'
}
},
methods: {
showParent() {
console.log(this.$parent.msg)
}
}
}
}
})
const app = new Vue({
el: '#app'
})
</script>
注意事项: 尽管在 Vue 开发中,我们允许通过
$parent
来访问父组件,但是在真实开发中尽量不要这样做。 子组件应该尽量避免直接访问父组件的数据,因为这样耦合度太高了。 如果我们将子组件放在另外一个组件之内,很可能该父组件没有对应的属性,往往会引起问题。 另外,更不好做的是通过$parent
直接修改父组件的状态,那么父组件中的状态将变得飘忽不定,很不利于我的调试和维护。