一、组件基础
【官网定义】
1、组件是可复用的 Vue 实例 ;
2、它们与 new Vue 接收相同的选项,例如 【data】、【computed】、【watch】、【methods】以及【生命周期钩子】等;
3、仅有的例外是没有像 el 这样根实例特有的选项
4、一个组件的 data 选项【必须是一个函数】,因此每个实例可以维护一份被返回对象的独立的拷贝
【命名方式】
1、【连接符形式】 <my-component-name>
适用于【DOM】与【template】
2、【驼峰式】 <my-component-name>
仅适用于【template】
【总结】
1、当使用 【驼峰式】 定义一个组件时,你在引用这个自定义元素时两种命名法都可以使用。
2、也就是说 和 都是可接受的。
3、注意,尽管如此,直接在【DOM】(即非字符串的模板) 中使用时只有【连接符形式】是有效的。
【注册类型】
1、全局注册
Vue.component("header-app", {
// 组件中的data都是一个函数 , 返回对象
data() {
return {
msg: "全局的组件header-app"
}
},
// 必须有一个根标签
template: `
<header>
{{msg}}
<button @click='test'>按钮</button>
<DemoC />
</header>
`,
methods: {
test() {
alert("测试组件中的方法")
}
},
components: {
DemoC: cc
}
})
2、局部注册 —类似于按需引入
let vm = new Vue({
el: "#app",
data: {
msg: "vm中的msg"
},
// 2、注册局部组件 FooterApp
// 3、外部引入组件 DemoC
components: {
FooterApp: {
data() {
return {
msg: "FooterApp的msg"
}
},
template: `
<footer>
{{msg}}
<button @click='test'>按钮</button>
</footer>
`,
methods: {
test() {
alert("测试组件中的方法--footerApp")
}
}
},
DemoC: cc
},
methods: {
test() {
alert("vm中的")
}
}
})
【总结】
1、被全局注册的组件,可以在全局任何一个组件内使用
2、被局部注册的组件,只能在当前在这里插入代码片注册的范围内使用
二、组件化开发实战回顾
1. 分析页面结构
【组件分区】
【页面结构】
2.组件抽离 【以homeRight为例】
2.1 思路分析:
a、【页面右侧】分为【右边上半区域】和【右边下半区域】
b、【右边下半区域】中可抽离出【表单组件】
2.2 具体源码:
1. homeRight 【页面右侧】
(function () {
window.homeRight = {
template: `
<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
<!--右边上半区域-->
<homeTop @delete_hobby="deleteHobby" :hobbies='hobbies'></homeTop>
<!--右边下半区域-->
<homeDown :deltetEmp='deltetEmp' :empList="empList">
</homeDown>
</div>
`,
components: {
homeTop,
homeDown
},
data() {
return {
hobbies: ["吃", "喝", "玩", "乐"],
empList: [
{ id: 1, name: "小红", num: 20240311 },
{ id: 2, name: "小王", num: 20240311 },
{ id: 3, name: "小刚", num: 20240311 }
]
}
}
}
}())
2.homeTop 【右边上半区域】
(function () {
window.homeTop = {
template: `
<div>
<h1 class="page-header">{{i}}</h1>
<div class="row placeholders">
<div v-for="(item,index) in hobbies" class="col-xs-6 col-sm-3 placeholder">
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" width="200"
height="200" class="img-responsive" alt="Generic placeholder thumbnail">
<h4>{{item}}</h4>
<span class="text-muted" @click="deleteHobby(index)">删除</span>
</div>
</div>
</div>
`,
props:['hobbies'],
methods: {
deleteHobby(index){
this.$emit("delete_hobby",index)
}
},
created () {
PubSub.subscribe('test', (e, num) => {
this.i = num
})
},
data () {
return {
i:0
}
}
}
}())
3.homeDown 【右边下半区域】
(function () {
window.homeDown = {
template: `
<div>
<h2 class="sub-header">Section title</h2>
<slot name='111'>111</slot>
<slot name='222'>222</slot>
<div class="table-responsive">
<table class="table table-striped">
<thead>
<tr>
<th>#</th>
<th>Header</th>
<th>Header</th>
<th>Header</th>
</tr>
</thead>
<tbody>
<Item :key='item.id' v-for="(item,index) in empList"
:emp='item' :deltetEmp="deltetEmp" :index='index'></Item>
</tbody>
</table>
</div>
</div>
`,
components: {
Item
},
props: {
"empList": Array,
"deltetEmp":Function
}
}
}())
4.Item 【表单组件】
(function () {
// 可以在tr这里写v-for吗??
window.Item = {
template: `
<tr>
<td>{{emp.id}}</td>
<td>{{emp.name}}</td>
<td>{{emp.num}}</td>
<td><a href="www.baidu.com" @click.prevent='deltetEmpIndex'>删除</a></td>
</tr>
`,
props: {
"emp": {
require: true,
type: Object
},
'index': {
require: true,
type: Number
},
"deltetEmp": {
require: true,
type: Function
}
},
methods: {
deltetEmpIndex() {
if (window.confirm("你确定要删除")) {
this.deltetEmp(this.index)
}
}
}
}
}())
3. 极致组件化
3.1 根组件提取app.js
1. 具体操作
a、将index.html中<div id="#app">标签体中的代码提取,变成根组件存入app.js中
b、app.js的template中引用了AppNavbar、AppLeaf和AppHome组件,所以我们要将index.html中的components选项中的组件对象剪切到App组件对象中。
2. 源码
// 组件入口 app.js
(function () {
template = `
<div>
<!--头部导航区域-->
<app-nav-bar></app-nav-bar>
<!--核心区域:分左右两边-->
<app-home></app-home>
</div>
`
window.App = {
template,
components: {
AppNavBar,
"AppHome":AppHome
}
}
}())
3.2 提取index.html中的js文件
1. 具体操作
前index.html文件中还有JS代码,可以将这些JS代码提取出来放到main.js
2. 源码
// 程序入口
new Vue({
el: '#app',
template: '<App></App>',
components: {
App
}
})
3.3 引入
1. 具体操作
引入app.js 和 main.js文件
2. 源码
<!-- 组件入口 相当于 App.vue -->
<script src="./components/app.js"></script>
<!-- 程序入口 相当于app.js -->
<script src="./main.js"></script>