- 模块:向外提供特定功能的js呈现
- 组件:用来实现局部(特定)功能效果的代码集合
- 模块化:当应用中的 js 都以模块来编写的, 那这个应用就是一个模块化的应用
- 组件化:当应用中的功能都是多组件的方式来编写的, 那这个应用就是一个组件化的应用
编写组件-非单文件组件
非单文件组件:一个文件中包含有n个组件
Vue中使用组件的三大步骤:
- 定义组件(创建组件)
- 注册组件
- 使用组件(写组件标签)
定义组件
组件是可理解为可以复用的vm实例,使用Vue.extend(options)创建,其中options和new Vue(options)时传入的那个options几乎一样,data、回调、计算、监听等等,除了el
区别:
- el不要写:最终所有的组件都要经过一个vm的管理,由vm中的el决定服务哪个容器
- data必须写成函数 :避免组件被复用时,数据存在引用关系
- 使用template可以配置组件结构
- 其他的回调、监听等等都是配置在组件内部而非vue实例
// 创建school组件const school = Vue.extend({// 组件里面模版内容template: `<div><h1>{{ schoolName }}{{ address }}</h1></div>`,data: function () {return {schoolName: "school", address: "Beijing"}}})// 创建student组件const student = Vue.extend({template: `<div><h1>{{ name }}{{ address }}</h1></div>`,data: function () {return {name: "student", address: "Beijing"}}})
// 简写形式
// const school = Vue.extend(options) 可简写为:const school = options// 创建组件-简写
const school = {// 组件里面模版内容template: `<div><h1>{{ schoolName }}{{ address }}</h1></div>`,data: function () {return {schoolName: "school", address: "Beijing"}}}// 如果简写,vue源码会完成调用extend
注册组件
- 局部注册
// 创建vmnew Vue({el: "#root",data: {},// 注册组件-局部注册components: {// key:value形式,key为实际的组件名字,可以不和上面创建的名字一致school:school,student}})
-
全局注册
// 全局注册组件Vue.extend("student",student)
使用组件
<div id="root"><!-- 编写组件标签,标签为components里面的key --><school></school><student></student></div>
注意事项
1.关于组件名:
一个单词组成:
第一种写法(首字母小写):school
第二种写法(首字母大写):School 多个单词组成:
第一种写法(kebab-case命名):my-school
第二种写法(CamelCase命名):MySchool (需要Vue脚手架支持)
备注:
(1).组件名尽可能回避HTML中已有的元素名称,例如:h2、H2都不行。
(2).可以使用name配置项指定组件在开发者工具中呈现的名字。2.关于组件标签:
第一种写法:
第二种写法:
备注:不用使用脚手架时,会导致后续组件不能渲染
组件嵌套
// 创建student组件const student = Vue.extend({template: `<div><h1>{{ name }}{{ address }}</h1></div>`,data: function () {return {name: "student", address: "Beijing"}},})// 创建school组件const school = Vue.extend({template: `<div><h1>{{ schoolName }}{{ address }}</h1><!-- 使用 student组件 --><student></student></div>`,data: function () {return {schoolName: "school", address: "Beijing"}},// 注册组件-将student注册给school组件,school的局部组件components:{student}})// 创建vmnew Vue({el: "#root",data: {},components: {school:school,}})
在vue中,vue可以只管理一个组件,由该组件管理其余组件
// 创建app组件const app = {template: `<!-- app内调用 其余组件--><div><student></student><school></school></div>`,// 将其余组件注册给appcomponents: {school,student}}// 创建vmnew Vue({el: "#root",data: {},// 调用app组件template: `<app></app>`,components: {// 将app注册给 vueapp}})
VueComponent
- 组件本质是一个名为VueComponent的构造函数,不是程序员定义的,是Vue.extend生成
console.log(school) // VueComponent(options) {this._init(options);}
-
只需要写
或 ,Vue解析时帮我们创建school组件的实例对象,即Vue帮我们执行的:new VueComponent(options) -
每次调用Vue.extend,返回的都是一个全新的VueComponent
// extend部分源码 var Sub = function VueComponent (options) {this._init(options);};return Sub
-
组件配置中:data函数、methods中的函数、watch中的函数、computed中的函数,它们的this均是VueComponent实例对象
const school = Vue.extend({name:"school",template: `<div><h1>{{ schoolName }}{{ address }}</h1></div>`,data: function () {console.log(this)// VueComponent {_uid: 3, _isVue: true, __v_skip: true, _scope: EffectScope, $options: {…}, …}return {schoolName: "school", address: "Beijing"}},})
-
new Vue(options)配置中:data函数、methods中的函数、watch中的函数、computed中的函数,它们的this均是Vue实例对象
-
组件实例对象可以访问到Vue原型上的属性和方法
VueComponent.prototype.__proto__ === Vue.prototype // true
编写组件-单文件组件
单文件组件:一个文件中只包含1个组件 ,文件后缀是以.vue结尾的
.vue文件模版
<script>
// 编写组件的交互逻辑、数据等等</script><template><!-- 编写组件的结构 html --></template><style scoped>
/* 编写组件的样式 */
</style>
编写组件
- 编写一个Student 单文件组件,将该组件暴露出去 Student.vue
<script>
// 创建组件-默认暴露
export default {name: "Student",data: function () {return {name: "vue", address: "Beijing"}},methods: {tips(event) {alert(event.target.value)}}
}</script><template><!-- 编写结构 --><div class="student"><h1>名字:{{ name }}</h1><h1>地址:{{ address }}</h1><button @click="tips"></button></div></template><style scoped>
// 编写样式
.class {width: 300px;height: 300px;background-color: skyblue;
}</style>
-
创建App主组件-注册其他组件,App.vue
<script>// 引入Student组件 import Student from "./Student.vue";export default {name: "App",// 注册Student组件components:{Student}}</script><template><div><Student></Student></div></template><style scoped></style>
-
编写js文件,创建vm实例,注册App组件 - main.js
// 引入App组件 import App from './App.vue' // 创建Vue实例 new Vue({el:"#root",data:{test:"test"},components:{App} })