组件化编程
组件: 实现局部功能的代码、资源的集合
提高代码复用率、运行效率
将应用按照功能划分为各个组件,即组件化
将一个大的js文件按照功能模块划分,即模块化
非单文件组件
一个文件中有多个组件
- 创建组件:
//创建第一个组件
const c1 = Vue.extend(
{//没有el属性
//template组件的模板,只能一个根节点且<template>不能为根
template: `
<div>
<div>{{ name }}</div>
<div>{{ age }}</div>
<button @click='alert'>点击显示</button>
</div>
`,
data: function(){ //防止组件重用时,引用同一个数据对象,操作混乱
return {
name: "jack",
age: 23,
}
},
methods: {
alert(){
console.log("点击了一个按钮")
},
},
}
)
//创建第二个组件
const c2 = Vue.extend(
{//没有el属性
template: `
<div>
<div>{{ name }}</div>
<div>{{ age }}</div>
</div>
`,
data: function(){ //防止组件重用时,引用同一个数据对象,操作混乱
return {
name: "jack2",
age: 25,
}
},
}
)
- 注册组件
new Vue(
{
el: "#container",
components: {//注册局部组件
c1: c1,
c2,
},
}
)
- 使用组件
<div id="container">
<c1></c1>
<c2></c2>
</div>
配置全局组件,多个Vue实例管理的容器都可以直接使用
Vue.component(‘c3’, c3)
组件的命名方式
components对象中的key
-
一个单词
component / Component -
多个单词
‘my-component’
MyComponent(脚手架使用) -
不能使用Html已有的标签,组件内部可以通过name指定其在开发者工具中的名字,Vue.extend部分可以省略,直接给一个对象。
组件的嵌套
const child = Vue.extend({
template: `
<div>
<span>{{ info }}</span>
</div>
`,
data(){
return {
name: "jack",
age: 23,
info: "这是子组件的内容",
}
},
})
//定义父组件,并在内部注册、使用子组件
const parent = Vue.extend({
template: `
<div>
<span>{{ info }}</span>
<child></child>
</div>
`,
data(){
return {
name: "parent",
age: 23,
info: "这是父组件的内容",
}
},
components: {//在父组件内部,注册子组件
child,
},
})
//父组件在Vue实例中注册,且在Vue实例管理的容器中使用
app管理组件
const app = Vue.extend({
template: `
<div>
<parent1></parent1>
<parent2></parent2>
</div>
`,
//注册所有的顶层组件
components: {
parent1,
parent2,
},
})
//将app管理组件注册到Vue实例
new Vue({
template: `<app></app>`,
el: "#container",
conponents: {app},
})
VueComponent构造函数
- 由Vue.extend创建的组件,本质是一个VueComponent构造函数,在模板中渲染时,Vue去创建对应的组件实例对象,即new VueComponent
- 每次创建组件,产生的VueComponent不同
- 组件中的data函数、methods内的函数、computed、watch内的函数中,this均为组件实例对象;Vue实例中的自然是Vue实例。
- VueComponent实例,简称vc;Vue实例对象简称vm
构造函数
<script>
// 定义构造函数
function Person(name, age){
// this 是构造函数的实例
this.name = name
this.age = age
}
console.log("构造函数的显式原型:", Person.prototype)
person = new Person("jack", 23)
console.log("实例对象的隐式原型:", person.__proto__)
// 显式原型放属性
// 隐式原型读属性 两者是同一个对象
// VueComponent.prototype.__proto__ === Vue.prototype
//让vc实例对象可以读取到Vue原型的属性、方法
</script>
单文件组件
文件中只能由一个组件,且文件名为xxx.vue;
vscode需要安装一个插件vetur。
创建一个组件 jack.vue
<template>
<!-- jack 组件的模板 -->
<div>
<h5>jack component</h5>
<span v-bind:class="css">{{ name }}</span><br>
<span>{{ age }}</span>
<button @click="showInfo">点击显示信息</button>
</div>
</template>
<script>
// data 、methods 交互
// 默认暴露组件,然后在其他文件import Component from './Component.vue'
export default {
// 开发工具中显示的名字
name: "Jack",
data(){
return {
name: "jack",
age: 23,
info: "component of jack",
css: "test",
}
},
methods: {
showInfo(event){
// this 是组件实例对象
console.log(this)
alert(this.info)
},
},
}
</script>
<style>
/* 正常些css */
.test{
background-color: pink;
}
</style>
创建第二个组件 Lucy.vue
<template>
<!-- jack 组件的模板 -->
<div>
<h5>Lucy component</h5>
<span v-bind:class="css">{{ name }}</span><br>
<span>{{ age }}</span>
<button @click="showInfo">点击显示信息</button>
</div>
</template>
<script>
// data 、methods 交互
// 默认暴露组件,然后在其他文件import Component from './Component.vue'
export default {
// 开发工具中显示的名字
name: "Lucy",
data(){
return {
name: "lucy",
age: 22,
info: "component of lucy",
css: "test",
}
},
methods: {
showInfo(event){
// this 是组件实例对象
console.log(this)
alert(this.info)
},
},
}
</script>
<style>
/* 正常些css */
.test{
background-color: lightblue;
}
</style>
创建管理组件App.vue
<template>
<div>
<jack></jack>
<Lucy></Lucy>
</div>
</template>
<script>
// 导入组件
import jack from './jack.vue'
import Lucy from './Lucy.vue'
// App组件管理多个组件
export default {
name: "App",
data(){
return {}
},
// 注册组件
components: {
jack,
Lucy,
},
}
</script>
<style>
/* 不定义css */
</style>
创建入口文件main.js
// 入口文件
import App from './App.vue'
new Vue({
el: "#container",
template: `
<div>
<App></App>
</div>
`,
comments: {App},
})
创建页面index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>页面</title>
</head>
<body>
<!-- 创建容器 -->
<div id="container"></div>
<!-- 引入Vue.js 框架 -->
<script src="/static/js/vue.js"></script>
<!-- 引入 入口文件main.js -->
<script src="./main.js"></script>
</body>
</html>
整体目录结构
以上代码需在脚手架中执行。