1 模块与组件、模块化与组件化
模块
- 理解:向外提供特定功能的 js 程序,一般就是一个 js 文件
- 为什么:js 文件很多很复杂
- 作用:复用、简化 js 的编写,提高 js 运行效率
组件
- 定义:用来实现局部功能的代码和资源的集合(html/css/js/image…)
- 为什么:一个界面的功能很复杂
- 作用:复用编码,简化项目编码,提高运行效率
模块化
当应用中的 js 都以模块来编写的,那这个应用就是一个模块化的应用
组件化
当应用中的功能都是多组件的方式来编写的,那这个应用就是一个组件化的应用
2 非单文件组件
- 非单文件组件:一个文件中包含有 n 个组件
- 单文件组件:一个文件中只包含有 1 个组件
2.1基本使用
Vue 中使用组件的三大步骤:
- 定义组件(创建组件)
- 注册组件
- 使用组件(写组件标签)
定义组件
使用**Vue.extend(options)
**创建,其中 options
和 new Vue(options)
时传入的那个 options 几乎一样,但也有点区别;
区别如下:
- el不要写,为什么? ——— 最终所有的组件都要经过一个
vm
的管理,由vm
中的el
决定服务哪个容器。
- data必须写成函数,为什么? ———— 避免组件被复用时,数据存在引用关系。
创建一个组件案例:Vue.extend()
创建
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| <script type="text/javascript"> Vue.config.productionTip = false;
const school = Vue.extend({ template:` <div class="demo"> <h2>学校名称:{{schoolName}}</h2> <h2>学校地址:{{address}}</h2> <button @click="showName">点我提示学校名</button> </div> `, data(){ return { schoolName:'尚硅谷', address:'北京昌平' } }, methods: { showName(){ alert(this.schoolName) } }, }); </script>
|
讲解一下面试小问题:data 必须写成函数:
这是js
底层设计的原因:举个例子
对象形式
1 2 3 4 5 6 7 8 9 10 11
| let data = { a: 99, b: 100 };
let x = data; let y = data;
x.a = 66; console.loh(x); console.log(y);
|
函数形式
1 2 3 4 5 6 7 8 9 10
| function data() { return { a: 99, b: 100 } } let x = data(); let y = data(); console.log(x === y);
|
备注:使用template可以配置组件结构。
注册组件
- 局部注册:
new Vue
的时候传入 components 选项,局部注册(只有注册了那个组件的才能使用)
- 全局注册:
Vue.component('组件名',组件)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <script> new Vue({ el: '#root', data: { msg:'你好啊!' }, components: { school: school, student: student } }) </script>
|
全局注册(所有的都可以使用)
1 2 3 4
| <script> Vue.component('hello', hello) </script>
|
使用组件
1 2 3 4 5 6 7 8 9 10 11 12
| <div id="root"> <hello></hello> <hr> <h1>{{msg}}</h1> <hr> <school></school> <hr> <student></student> </div>
|
2.2 组件注意事项
关于组件名:
一个单词组成:
- 第一种写法(首字母小写):school
- 第二种写法(首字母大写):School(推荐)
多个单词组成:
- 第一种写法(kebab-case命名):my-school
- 第二种写法(CamelCase命名):MySchool (需要Vue脚手架支持)(推荐)
备注:
- 组件名尽可能回避HTML中已有的元素名称,例如:h2、H2都不行。
- 可以使用
name
配置项指定组件在开发者工具中呈现的名字。
关于组件标签:
- 第一种写法:
<school></school>
- 第二种写法:
<school/>
备注:不用使用脚手架时,会导致后续组件不能渲染。
一个简写方式: const school = Vue.extend(options)
可简写为:const school = options
2.3 组件的嵌套
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
| <div id="root"></div>
<script type="text/javascript"> Vue.config.productionTip = false;
const student = Vue.extend({ name: 'student', template: ` <div> <h4>学生姓名:{{name}}</h4> <h4>学生年龄:{{age}}</h4> </div> `, data() {return {name: '尚硅谷',age: 18}} });
const school = Vue.extend({ name: 'school', template: ` <div> <h3>学校名称:{{name}}</h3> <h3>学校地址:{{address}}</h3> <student></student> </div> `, data() {return {name: '尚硅谷',address: '北京'}}, components: { student } });
const hello = Vue.extend({ template: `<h3>{{msg}}</h3>`, data() {return {msg: '欢迎来到尚硅谷学习!'}} });
const app = Vue.extend({ template: ` <div> <hello></hello> <school></school> </div> `, components: { school, hello } });
new Vue({ el: '#root', template: '<app></app>', components: { app } }) </script>
|
2.4 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
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| <div id="root"> <school></school> <hello></hello> </div>
<script type="text/javascript"> Vue.config.productionTip = false;
const school = Vue.extend({ name: 'school', template: ` <div> <h2>学校名称:{{name}}</h2> <h2>学校地址:{{address}}</h2> <button @click="showName">点我提示学校名</button> </div> `, data() {return {name: '尚硅谷',address: '北京'}}, methods: {showName() {console.log('showName', this)}}, });
const test = Vue.extend({ template: `<span>atguigu</span>` });
const hello = Vue.extend({ template: ` <div> <h2>{{msg}}</h2> <test></test> </div> `, data() {return {msg: '你好啊!'}}, components: { test } });
const vm = new Vue({ el: '#root', components: { school, hello } }) </script>
|
Vue 在哪管理 VueComponent
2.5 一个重要的内置关系
- 一个重要的内置关系:
VueComponent.prototype.__proto__ === Vue.prototype
- 为什么要有这个关系:让组件实例对象(vc)可以访问到 Vue原型上的属性、方法。
例: main.js
中Vue.prototype.Axios = Axios;
,组件 xxx.vue
中就可以使用 this.Axios({});
3 单文件组件
单文件组件就是将一个组件的代码写在 .vue
这种格式的文件中,webpack 会将 .vue
文件解析成 html,css,js这些形式。
单文件组件的案例:
School.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| <template> <div class="demo"> <h2>学校名称:{{name}}</h2> <h2>学校地址:{{address}}</h2> <button @click="showName">点我提示学校名</button> </div> </template>
<script> export default { name:'School', data(){ return { name:'尚硅谷', address:'北京昌平' } }, methods: { showName(){ alert(this.name) } }, } const school = Vue.extend({ name:'School', data(){ return { name:'尚硅谷', address:'北京昌平' } }, methods: { showName(){ alert(this.name) } }, }); export default school; </script>
<style> .demo{ background-color: orange; } </style>
|
Student.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <template> <div> <h2>学生姓名:{{name}}</h2> <h2>学生年龄:{{age}}</h2> </div> </template>
<script> export default { name:'Student', data(){ return { name:'张三', age:18 } } } </script>
|
App.vue
用来汇总所有的组件(大总管)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <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
在这个文件里面创建 vue 实例
1 2 3 4 5 6 7
| import App from './App.vue'
new Vue({ el:'#root', template:`<App></App>`, components:{App}, })
|
index.html
在这写 vue 要绑定的容器
1 2 3 4 5 6 7 8 9 10 11 12 13
| <!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>练习一下单文件组件的语法</title> </head> <body> <div id="root"></div> <script type="text/javascript" src="../js/vue.js"></script> <script type="text/javascript" src="./main.js"></script> </body> </html>
|