Vue学习-------------(17)组件进阶使用
组件数据的存放
- data属性必须是一个函数
- 而且这个函数返回一个对象,对象内部保存着数据
将计数器封装为组件
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Untitled</title>
</head>
<body>
<div id="app">
<cpn></cpn>
</div>
<template id="ccc">
<div>
<h2>当前计数:{{counter}}</h2>
<button @click="increment">+</button>
<button @click="decrement">-</button>
</div>
</template>
<script src="../js/vue.js"></script>
<script>
Vue.compotent('ccc' ,{
template: '#ccc',
data() {
return{
counter: 0
}
},
methods: {
increment() {
this.counter++
},
decrement() {
this.counter--
}
}
})
//root组件
const app = new Vue({
el: '#app' ,
})
</body>
</html>
组件是可复用的vue实例,一个组件被创建好之后,就可能被用在各个地方,而组件不管被复用了多少次,组件中的data数据都应该是相互隔离,互不影响的,基于这一理念,组件每复用一次,data数据就应该被复制一次,之后,当某一处复用的地方组件内data数据被改变时,其他复用地方组件的data数据不受影响。
父子组件的通信:
- 通过props向子组件传递数据
- 通过事件向父组件发送消息
Vue实例和子组件的通信与父组件和子组件的通信过程是一样的
props用法:
- 在组件中,使用选项props来声明需要从父组件接收的数据
- props的值有两种方式:
- 方式一:字符串数组,数组中的字符串就是传递时的名称
- 方式二:对象,对象可以设置传递时的类型,也可以设置默认值等
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Untitled</title>
</head>
<body>
<div id="app">
<cpn :cmovies="movies" :cmessage="message"></cpn>
</div>
<template id="ccc">
<div>
<h2>{{cmovies}}</h2>
</div>
</template>
<script src="../js/vue.js"></script>
<script>
const cpn = {
template: '#ccc',
//数组写法:
//props: ['cmovies', 'cmessage'],
//对象写法:
props: {
//类型限制:
//cmovies: Array ,
//cmessage: String,
//设置默认值:
cmessage: {
type: String,
default: 'aaaaaaaaaaaa',
required: true //加上这个属性就必须给cmessage传值
}
//类型是对象或者数组时,默认值必须是一个函数
cmovies: {
type: Array,
default() {
return []
}
}
},
data() {
return{
}
},
methods: {
}
})
//root组件
const app = new Vue({
el: '#app' ,
data: {
movies: ['海贼王', '海尔兄弟'],
message: '你好啊'
},
compotents: {
cpn //字面量增强写法
}
})
</body>
</html>
自定义事件:
- 当子组件需要向父组件传递数据时,就要用到自定义事件
- 之前学习的v-on不仅仅可以用于监听DOM事件,也可以用于组件间的自定义事件
自定义事件流程:
- 在子组件中,通过$emit()来触发事件
- 在父组件中,通过v-on来监听子组件事件
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Untitled</title>
</head>
<body>
<div id="app">
<cpn @item-click="cpnClick"></cpn>
</div>
<template id="ccc">
<div>
<button v-for="item in categories" @click="btnClick(item)">
{{item.name}}
</button>
</div>
</template>
<script src="../js/vue.js"></script>
<script>
const cpn = {
template: '#ccc',
data() {
return{
categories[
{id: 'aaa', name: '热门推荐'},
{id: 'bbb', name: '手机数码'},
{id: 'ccc', name: '家用家电'},
{id: 'ddd', name: '电脑办公'}
]
}
},
methods: {
btnClick(item) {
//发射事件:自定义事件
this.$emit('item-click', item)
}
}
})
//root组件
const app = new Vue({
el: '#app' ,
data: {
},
compotents: {
cpn //字面量增强写法
},
methods: {
cpnClick(item) {
console.log(item)
}
}
})
</body>
</html>
有时候我们需要父组件直接访问子组件,子组件直接访问父组件,或者是子组件访问根组件
- 父组件访问子组件:使用$children或者$refs
- 子组件访问父组件:使用$parent
$children的使用(实际开发中不常用):
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Untitled</title>
</head>
<body>
<div id="app">
<cpn></cpn>
<cpn></cpn>
<cpn></cpn>
<button @click="btnClick">按钮</button>
</div>
<template id="ccc">
<div>
<p>我是子组件</p>
</div>
</template>
<script src="../js/vue.js"></script>
<script>
const cpn = {
template: '#ccc',
data() {
return{
name: '我是子组件的name'
}
},
methods: {
showMessage() {
console.log("showMessage")
}
}
})
//root组件
const app = new Vue({
el: '#app' ,
data: {
},
compotents: {
cpn //字面量增强写法
},
methods: {
btnClick() {
console.log(this.$children);
for(let c of this.$children) {
console.log(c.name);
c.showMessage();
}
}
}
})
</body>
</html>
$refs的使用:
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Untitled</title>
</head>
<body>
<div id="app">
<cpn></cpn>
<cpn ref="aaa"></cpn>
<cpn></cpn>
<button @click="btnClick">按钮</button>
</div>
<template id="ccc">
<div>
<p>我是子组件</p>
</div>
</template>
<script src="../js/vue.js"></script>
<script>
const cpn = {
template: '#ccc',
data() {
return{
name: '我是子组件的name'
}
},
methods: {
showMessage() {
console.log("showMessage")
}
}
})
//root组件
const app = new Vue({
el: '#app' ,
data: {
},
compotents: {
cpn //字面量增强写法
},
methods: {
btnClick() {
console.log(this.$refs);
console.log(this.$refs.aaa.name);
}
}
}
})
</body>
</html>
$parent的使用(开发中不常使用,且不建议使用):
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Untitled</title>
</head>
<body>
<div id="app">
<cpn></cpn>
</div>
<template id="ccc">
<div>
<p>我是子组件</p>
<button @click="btnClick"></button>
</div>
</template>
<script src="../js/vue.js"></script>
<script>
const cpn = {
template: '#ccc',
methods: {
btnClick() {
console.log("this.$parent") //访问跟组件:$root
}
}
})
//root组件
const app = new Vue({
el: '#app' ,
data: {
},
compotents: {
cpn //字面量增强写法
},
methods: {
}
})
</body>
</html>
浙公网安备 33010602011771号