非单文件组件:一个文件中包含有n个组件
单文件组件:一个文件中只包含1个组件
18、非单文件组件
1.基本使用
Vue中使用组件的三大步骤
- 定义组件(创建组件)
- 注册组件
- 使用组件(写组件标签)
定义组件
使用Vue.extend(options)
创建,其中option
s和new Vue(options)
时传入的那个options
几乎一样,但也有点区别;
- el不要写, 最终所有的组件都要经过一个vm的管理,由vm中的el决定服务哪个容器。
- data必须写成函数,避免组件被复用时,数据存在引用关系。
注册组件
- 局部注册:靠
new Vue
的时候传入components
选项 - 全局注册:靠
Vue.component('组件名',组件)
使用组件(写组件标签)
<school></school>
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>1-基本使用</title>
<!-- 引入Vue -->
<script src="../js/vue.js"></script>
</head>
<body>
<div id="root">
<h1>{{msg}}</h1>
<hr>
<hello></hello>
<!-- 第三步:使用组件 -->
<school></school>
<hr>
<student></student>
<hr>
</div>
<div id="root2">
<hello></hello>
</div>
<script>
Vue.config.productionTip = false;
// 第一步:创建school组件
const school = Vue.extend({
template:`
<div>
<h2>学校名称:{{schoolName}}</h2>
<h2>学校地址:{{address}}</h2>
<button @click="showName">点我提示学校名</button>
</div>
`,
// el: '#root', // 组件定义时一定不要写el配置项,
// 存储数据
data(){
return {
schoolName:'梅洛天庭',
address:'赤乌恒星'
}
},
methods: {
showName(){
alert(this.schoolName);
}
},
})
// 第一步:创建student组件
const student = Vue.extend({
template:`
<div>
<h2>学生姓名:{{studentName}}</h2>
<h2>学生年龄:{{age}}</h2>
</div>
`,
data(){
return {
studentName:'彦',
age:18
}
}
})
// 第一步:创建hello组件
const hello = Vue.extend({
template: `
<div>
<h2>你好呀!{{name}}</h2>
</div>
`,
data() {
return {
name: 'Tom'
}
},
})
Vue.component('hello',hello)
// 创建vm
const vm = new Vue({
// 绑定容器
el: '#root',
data: {
msg:'你好呀!'
},
// 第二步:注册组件 -- 局部注册
components: {
school,
student
}
})
new Vue({
el: '#root2',
})
</script>
</body>
</html>
2.几个注意点
关于组件名
一个单词组成
- 第一种写法(首字母小写):school
- 第二种写法(首字母大写):School
多个单词组成
- 第一种写法(kebab-case命名):my-school
- 第二种写法(CamelCase命名):MySchool (需要Vue脚手架支持)
备注:
- 组件名尽可能回避HTML中已有的元素名称,例如:h2、H2都不行
- 可以使用name配置项指定组件在开发者工具中呈现的名字
关于组件标签
- 第一种写法:
<school></school>
- 第二种写法:
<school/>
- 备注:不用使用脚手架时,
<school/>
会导致后续组件不能渲染
一个简写方式:
const school = Vue.extend(options)
可简写为:const school = options
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>几个注意点</title>
<script src="../js/vue.js"></script>
</head>
<body>
<div id="root">
<h2>{{msg}}</h2>
<xuexiao></xuexiao>
<hello></hello>
<hr>
<!-- <xuexiao/> -->
</div>
<script>
Vue.config.productionTip = false;
// 创建组件
const s = Vue.extend({
name:'school',
template:`
<div>
<h2>学校名称:{{schoolName}}</h2>
<h2>学校地址:{{address}}</h2>
</div>
`,
data(){
return {
schoolName:'梅洛天庭',
address:'赤乌恒星'
}
},
})
const hello = {
template:`
<div>
<h2>学校hello</h2>
</div>
`,
}
const vm = new Vue({
// 绑定容器
el: '#root',
// 存储数据
data: {
msg:'欢迎学习Vue!'
},
components: {
xuexiao:s,
hello
}
})
</script>
</body>
</html>
3.组件的嵌套
<!DOCTYPE html>
<html lang="zh">
<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>
<!-- 引入Vue -->
<script src="../js/vue.js"></script>
</head>
<body>
<!-- 准备一个容器 -->
<div id="root">
</div>
<script>
Vue.config.productionTip = false;
// 创建组件
const student = Vue.extend({
template:`
<div>
<h2>学生姓名:{{studentName}}</h2>
<h2>学生年龄:{{age}}</h2>
</div>
`,
data(){
return {
studentName:'彦',
age:18
}
}
})
const school = Vue.extend({
name:'school',
template:`
<div>
<h2>学校名称:{{schoolName}}</h2>
<h2>学校地址:{{address}}</h2>
<student></student>
</div>
`,
data(){
return {
schoolName:'梅洛天庭',
address:'赤乌恒星'
}
},
components:{
student
}
})
const hello = Vue.extend({
template: `
<div>
<h2>你好呀!{{name}}</h2>
</div>
`,
data() {
return {
name: 'Tom'
}
},
})
const app = Vue.extend({
template:`
<div>
<school></school>
<hello></hello>
</div>
`,
components: {
school,
hello,
}
})
const vm = new Vue({
template:'<app></app>',
// 绑定容器
el: '#root',
// 注册组件
components: {
app,
}
})
</script>
</body>
</html>
4.VueComponent
关于VueComponent
school
组件本质是一个名为VueComponent
的构造函数,且不是程序员定义的,是Vue.extend
生成的- 我们只需要写
<school/>
或<school></school>
,Vue解析时会帮我们创建school组件的实例对象,即Vue帮我们执行的:new VueComponent(options)
- 特别注意:每次调用
Vue.extend
,返回的都是一个全新的VueComponent
!!!! 关于this指向
- 组件配置中,data函数、methods中的函数、watch中的函数、computed中的函数 它们的this均是【VueComponent实例对象】
new Vue(options)
配置中,data函数、methods中的函数、watch中的函数、computed中的函数 它们的this均是【Vue实例对象】
VueComponent
的实例对象,以后简称vc
(也可称之为:组件实例对象). Vue的实例对象,以后简称vm
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>VueComponent</title>
<!-- 引入Vue -->
<script src="../js/vue.js"></script>
</head>
<body>
<div id="root">
<school></school>
<hello></hello>
</div>
<script>
Vue.config.productionTip = false;
// 第一步:创建school组件
const school = Vue.extend({
template:`
<div>
<h2>学校名称:{{schoolName}}</h2>
<h2>学校地址:{{address}}</h2>
<button @click="showName">点我提示学校名</button>
</div>
`,
// el: '#root', // 组件定义时一定不要写el配置项,
// 存储数据
data(){
return {
schoolName:'梅洛天庭',
address:'赤乌恒星'
}
},
methods: {
showName(){
alert(this.schoolName);
}
},
})
const test = Vue.extend({
template: '<span>葛小伦</span>'
})
const hello = Vue.extend({
template: `
<div>
<h2>你好呀!{{name}}</h2>
<test></test>
</div>
`,
data() {
return {
name: 'Tom'
}
},
components:{
test,
}
})
const vm = new Vue({
// 绑定容器
el: '#root',
// 存储数据
data: {},
components: {
school,
hello
}
})
</script>
</body>
</html>
5.一个重要的内置关系
一个重要的内置关系:
VueComponent.prototype.__proto__
===Vue.prototype
为什么要有这个关系:让组件实例对象(vc)可以访问到 Vue原型上的属性、方法
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>一个重要的内置关系</title>
<script src="../js/vue.js"></script>
</head>
<body>
<div id="root">
<student></student>
</div>
<script>
Vue.config.productionTip = false;
function Demo(){
this.a = 1;
this.b = 2;
}
const d = new Demo();
console.log(Demo.prototype); // 显示原型属性
console.log(d.__proto__); // 隐式原型属性
Demo.prototype.x = 99;
const student = Vue.extend({
template:`
<div>
<h2>学生姓名:{{studentName}}</h2>
<h2>学生年龄:{{age}}</h2>
<button @click="showX">点我输出x</button>
</div>
`,
data(){
return {
studentName:'彦',
age:18
}
},
methods: {
showX(){
console.log(this.x);
}
},
})
const vm = new Vue({
// 绑定容器
el: '#root',
// 存储数据
data: {
msg:'你好!'
},
components: {
student
}
});
Vue.prototype.x = 99;
console.log(student.prototype.__proto__ === Vue.prototype);
</script>
</body>
</html>
19、单文件组件
export const school = Vue.extend
==> 分别暴露
export {school}
==> 统一暴露
export default school
==> 默认暴露
School.vue
<template>
<!-- 组件的结构 -->
<div class="demo">
<h2>学校名称:{{schoolName}}</h2>
<h2>学校地址:{{address}}</h2>
<button @click="showName">点我提示学校名</button>
</div>
</template>
<script>
// 组件交互相关的代码(数据、方法等)
export default {
name:'School',
data(){
return {
schoolName:'梅洛天庭',
address:'赤乌恒星'
}
},
methods: {
showName(){
alert(this.schoolName);
}
},
};
</script>
<style>
/* 组件的样式 */
.demo{
background-color: orange;
}
</style>
Student.vue
<template>
<div>
<h2>学生姓名:{{studentName}}</h2>
<h2>学生年龄:{{age}}</h2>
</div>
</template>
<script>
export default {
name:'Student',
data(){
return {
studentName:'彦',
age:18
}
}
}
</script>
App.vue
<template>
<div>
<School></School>
<Student></Student>
</div>
</template>
<script>
// 引入组件
import School from "./School.vue";
import Student from "./Student.vue";
export default {
name:'App',
components:{
School,
Student
}
}
</script>
main.js
import App from './App.vue'
new Vue({
el:'#root',
template:`<App></App>`,
components: {App}
})
index.html
<!DOCTYPE html>
<html lang="zh">
<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>
<!-- 引入Vue -->
<script src="../js/vue.js"></script>
</head>
<body>
<!-- 准备一个容器 -->
<div id="root"></div>
<script type="text/javascript" src="./main.js"></script>
</body>
</html>
注:浏览器运行,报错
Cannot use import statement outside a module
属于正常现象,因为没有对
vue
进行解析