组件
实现局部功能的代码和资源的集合
非单文件组件
1.定义组件(创建组件)
2.注册组件
3.使用组件(写组件标签)
定义
使用Vue.extend(options)
创建,其中options和new Vue(options)时传入的有点区别
- el不写。最终所有的组件要经过vm的管理,有vm中的el决定哪个容器
- data必须写成函数。避免组件复用时,数据存在引用关系
使用template配置组件结构
注册
局部注册:new Vue时传入components
选项
全局注册:使用Vue.component('组件名','组件')
编写组件标签
<school></school>
<body>
<div id="root">
<!-- 使用组件-->
<employee></employee>
<hr>
<department></department>
</div>
</body>
<script>
//定义组件
const employee = Vue.extend({
template: `
<div>
<h2>{{ name }}</h2>
<h2>{{ age }}</h2>
<button @click="showName">点击提示姓名</button>
</div>
`,
data() {
return {
name: '胡梓卓',
age: 18
}
},
methods: {
showName() {
alert(this.name);
}
}
});
const department = Vue.extend({
template: `
<div>
<h2>{{ name }}</h2>
<h2>{{ numberOfPeople }}</h2>
<button @click="showName">点击提示部门名称</button>
</div>
`,
data() {
return {
name: '智能制造部',
numberOfPeople: 203
}
},
methods: {
showName() {
alert(this.name);
}
}
});
new Vue({
el: '#root',
//注册组件
components: {
employee: employee,
department: department
},
data: {},
method: {},
computed: {},
watch: {},
filters: {},
directives: {}
});
</script>
注意点⚠️
组件名
一个单词组成:
(首字母小写):school
(首字母大写):School
多个单词组成:
(kebab-case):my-school
(CamelCase):MySchool
注意:
(1)组件名不要写成html中已有的元素名称
(2)可以使用name配置向指定组件在开发者工具中呈现的名字(第三方组件库)
组件标签
<school></school>
<school/>
不能使用脚手架时,<school/>
会导致后续组件不能渲染
声明组件简写
const school = Vue.extend({options}) => const school = {options}
组件嵌套
<!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>Document</title>
<script src="https://cn.vuejs.org/js/vue.js"></script>
</head>
<body>
<div id="root">
<app></app>
</div>
</body>
<script>
const student = Vue.extend({
name: 'student',
data() {
return {
name: '涂鏊飞',
age: 22
}
},
template: `
<div>
<h2>{{ name }}</h2>
<h2>{{ age }}</h2>
</div>
`,
components: {}
});
const hello = Vue.extend({
name: 'hello',
template: `
<h1>介绍</h1>
`
});
const school = Vue.extend({
name: 'school',
data() {
return {
name: '湖北工程学院',
adress: '湖北孝感'
}
},
template: `
<div>
<div>
<h2>{{ name }}</h2>
<h2>{{ adress }}</h2>
</div>
<student></student>
</div>
`,
//注册子组件,模板包含student,外部要包含一个根节点
components: {
student
}
});
const app = Vue.extend({
name: 'app',
template: `
<div>
<hello></hello>
<school></school>
</div>
`,
//管理school和hello
components: {
school, hello
}
});
new Vue({
el: '#root',
components: {
app
},
data: {},
method: {},
computed: {},
watch: {},
filters: {},
directives: {}
});
</script>
</html>
VueComponent构造函数
-
school組件本质是一个VueComponent的构造函数
-
Vue解析时,会帮我们创建school的组件实例对象,即执行new VueComponent(options)
-
每次调用Vue.extend,返回的是全新的VueComponent组件实例对象
-
关于this指向
(1)组件配置中:
data,methods,watch,comptued指向【VueComponent组件实例对象】,简称vc
(2)new Vue(options)配置中:
data,methods,watch,comptued指向【Vue实例对象】
vue实例与组件实例
组件是可复用的 Vue 实例,所以它们与 new Vue
接收相同的选项,例如 data
、computed
、watch
、methods
以及生命周期钩子等。仅有的例外是像 el
这样根实例特有的选项。
内置关系
原型链
function Demo() {
this.a = 1999;
this.b = 2000;
}
const d = new Demo();
console.log(d.__proto__);
console.log(Demo.prototype === d.__proto__);
Demo.prototype.c = 2022;
console.log(d.c);
VueComponent.prototype.__proto__ === Vue.prototype
const app = Vue.extend({});
console.log(app.prototype.__proto__ === Vue.prototype) //true
让组件实例对象可以访问到vue原型上的属性和方法
单文件组件
⚠️main.js导入
import App from './App.vue'
需要在脚手架环境运行!!!
Uncaught SyntaxError: Cannot use import statement outside a module
School.vue
<template>
<div>
<h2>学校名称:{{ name }}</h2>
<h2>学校地址:{{ address }}</h2>
</div>
</template>
<script>
export default {
name: "School",
data() {
return {
name: '湖北工程学院',
address: '湖北省孝感市'
}
}
}
</script>
<style scoped>
h2 {
color: #0dff1d;
}
</style>
Student.vue
<template>
<div>
<h2>学生姓名:{{ name }}</h2>
<h2>学生年龄:{{ age }}</h2>
</div>
</template>
<script>
export default {
name: "Student",
data() {
return {
name: '涂鏊飞',
age: '22'
}
}
}
</script>
<style scoped>
h2 {
color: #1c036c;
font-weight: 700;
}
</style>
App.vue
<template>
<div>
<school></school>
<student></student>
</div>
</template>
<script>
import School from './School'
import Student from './Student'
export default {
name: "App",
components: {
Student, School
}
}
</script>
main.js
import App from './App.vue'
new Vue({
el: '#root',
components: {
App
},
template: `<app></app>`
})
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>单文件组件</title>
</head>
<body>
<div id="root">
</div>
</body>
<script src="https://cn.vuejs.org/js/vue.js"></script>
<script src="./main.js"></script>
</html>