vue组件化开发
一、注册组件步骤
1.Vue.extend():
- 调用
Vue.extend()
创建的是一个组件构造器 - 通常在创建组件构造器时,传入
template
代表自定义的组件模板 - 该模板就是要显式的HTML代码。
2.Vue.component():
- 调用
Vue.component()
将组件构造器注册成一个组件,并给它起一个组件的标签名称 - 需要传递两个参数:1.注册组件的标签名 2.组件构造器
3.组件必须挂载在Vue的实例下,否则不会生效
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
<my-cpn></my-cpn>
<my-cpn></my-cpn>
<my-cpn></my-cpn>
</div>
</body>
<script src="../js/vue.js"></script>
<script>
// 1.创建组件构造器对象
const cpnC = Vue.extend({
template: `
<div>
<h2>标题</h2>
<p>内容111</p>
</div>`
})
// 2.注册组件
Vue.component('my-cpn', cpnC) //全局注册 ,全局组件可以在多个vue实例中使用
const app = new Vue({
el: "#app",
data: {
},
//局部组件, 只能在指定的vue实例中使用
components: {
cpn: cpnC
}
})
</script>
</html>
二、注册组件的语法糖
省略
Vue.extend()
,直接使用对象代替
<script>
// 全局注册
Vue.component('cpn1', {
template: `
<div>
<h2>标题1</h2>
<p>内容111</p>
</div>`
})
const app = new Vue({
el: "#app",
data: {
},
// 局部注册
components: {
cpn2: {
template: `
<div>
<h2>标题2</h2>
<p>内容222</p>
</div>`
}
}
})
</script>
三、模板分离的写法
1.通过script标签
<!-- script标签,类型必须是text/x-template -->
<script type="text/x-template" id="cpn">
<div>
<h2>标题1</h2>
<p>内容111</p>
</div>
</script>
Vue.component('cpn', {
template: '#cpn'
})
2.通过template标签
<template id="cpn">
<div>
<h2>标题2</h2>
<p>内容222</p>
</div>
</template>
Vue.component('cpn', {
template: '#cpn'
})
四、组件存放数据
组件对象也可以通过data属性存放数据,但data必须是一个函数,而且需要返回一个对象,对象内部存放数据。
<template id="cpn">
<div>
<h2>{{title}}</h2>
<h2>标题2</h2>
<p>内容222</p>
</div>
</template>
Vue.component('cpn', {
template: '#cpn',
data() {
return {
title: 'abc'
}
}
})
为什么必须是函数?
每个组件实例的函数会返回一个单独的对象,每个对象之间不会相互影响,反而言之,返回同一个对象 会造成组件之间相互影响
五、父子组件通信
子组件不能引用父组件或者Vue实例中的数据,但实际开发中需要将数据从父组件传递给子组件,或者子组件发送给父组件。
比如: 服务器返回的数据有一部分是要给子组件展示的,这个时候就需要父传子了。
- 通过props向子组件传递数据
- 通过事件向父组件发送消息
- 父组件向子组件传递数据
1.1首先在父组件中注册子组件,
1.2在子组件中通过props定义变量接收,
1.3通过绑定属性的形式将值传递给子组件<cpn :cmovies="movies" :cmessage="message"></cpn>
1.4子组件中就可以使用传递过来的值了。
<body>
<div id="app">
<cpn :cmovies="movies" :cmessage="message"></cpn>
</div>
<template id="cpn">
<div>
{{cmovies}}
<h2>{{cmessage}}</h2>
</div>
</template>
</body>
<script src="../js/vue.js"></script>
<script>
// 父传子 props
const cpn = {
template: '#cpn',
// props: ['cmovies', 'cmessage']
props: {
cmessage: {
// 类型限制
type: String,
// 默认值
default: '我很好',
required: true
},
cmovies: {
type: Array,
default() {
return ['aaa', 'bbb']
}
}
}
}
const app = new Vue({
el: "#app",
data: {
message: "你好啊",
movies: ['海王', '海贼王', '海尔兄弟']
},
components: {
cpn
}
})
</script>
注:> 类型是对象或者是数组时,默认值必须是一个函数
v-bind属性绑定时,不支持驼峰命名,例如(cInfo需改为c-info)。
- 子组件向父组件传递数据
2.1在子组件中通过
$emit
发射自定义事件
2.2在父组件中监听自定义事件
<!-- 子组件 -->
<template id="cpn">
<div>
<button v-for="item in categories" @click="btnClick(item)">
{{item.name}}
</button>
</div>
</template>
<!-- 父组件 -->
<div id="app">
<cpn @item-click="cpnClick"></cpn>
</div>
<script>
// 子组件
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)
}
}
}
const app = new Vue({
el: "#app",
methods: {
cpnClick(item) {
console.log('cpnClick', item)
}
},
components: {
cpn
}
})
六、父子组件直接访问
1.父组件通过$children
直接访问子组件
在父组件中通过
$children
获取的是一个vue组件数组,可以调用里面的方法
2.父组件通过$refs
直接访问子组件
默认返回的是一个空对象,需要在应用子组件的地方加上
ref="xxx"
<!-- 父组件 -->
<div id="app">
<cpn></cpn>
<cpn ref="aaa"></cpn>
<button @click="btnClick">点击</button>
</div>
<!-- 子组件 -->
<template id="cpn">
<div>
子组件
</div>
</template>
</body>
<script src="../js/vue.js"></script>
<script>
const cpn = {
template: '#cpn',
data() {
return {
}
},
methods: {
showMessage() {
console.log('showMessage111')
},
}
}
const app = new Vue({
el: "#app",
methods: {
btnClick() {
// console.log(this.$children);
// this.$children[0].showMessage();
// refs 对象类型,
console.log(this.$refs.aaa);
}
},
components: {
cpn
}
})
</script>
- 子组件通过
$parent
访问父组件,使用较少
4.访问根组件$root
vue实例。
焚膏油以继晷,恒兀兀以穷年。