什么是模块?
什么是组件?
什么是模块化?
其实Vue中,组件就是类似与封装。
此外,组件内部也是可以嵌套的。
组件定义:实现应用中的 局部功能代码(css,html,js等)和资源(mp3,mp4等资源)的集合。
非单文件组件:
单文件组件:
组件的效果就是:谁用到这个组件,它就可以直接调用。
第一步:使用Vue.extend()来创建组件。
使用Vue.extend()创建组件的注意事项:
原因:因为最终所有的组件都要被一个vm管理,由vm决定服务于哪个容器。
也就是让vm来决定这个组件放到哪里就放到哪里,不能让他它自己决定。
对象式的形式,因为组件可以被多个地方使用,如果是对象式的话,一方变化其他的也都会跟这变化,因为只有一个对象。
函数式的形式,就不用担心变化的问题了,因为多个地方调用函数式时,会得到多个对象,这样相互之间就不会影响了。
Vue.config.productionTip = false;
//创建school组件
const school = Vue.extend({
/*
注意点一:创建组件中,一定不要写el配置项,不然会报错。
原因:因为最终所有的组件都要被一个vm管理,由vm决定服务于哪个容器。
也就是让vm来决定这个组件放到哪里就放到哪里,不能让他它自己决定。
// el:"#root",
注意点二:组件的data配置必须是函数式。
对象式的形式,因为组件可以被多个地方使用,如果是对象式的话,一方变化其他的也都会跟这变化,因为只有一个对象。
函数式的形式,就不用担心变化的问题了,因为多个地方调用函数式时,会得到多个对象,这样相互之间就不会影响了。
*/
data(){
return {
schoolName:"北京大学",
address:"北京"
}
}
});
//创建student组件
const student = Vue.extend({
data(){
return {
studentName:"张三",
age:18
}
}
})
第二步:在vm对象中,注册组件。
Vue.config.productionTip = false;
//创建school组件
const school = Vue.extend({
data(){
return {
schoolName:"北京大学",
address:"北京"
}
},
//使用template为这个组件添加上结构。
//注意每一个template必须要有并且只有一个div结构。
template:`
学校名称:{{schoolName}}
学校地址:{{address}}
`
});
//创建student组件
const student = Vue.extend({
data(){
return {
studentName:"张三",
age:18
}
},
template:`
学生姓名:{{studentName}}
学生年龄:{{age}}
`
})
//vm对象
new Vue({
el:"#root",
//使用components来注册组件(局部注册)
components:{
//这里我们定义的组件名和上面的组件定义的变量名一样,可以直接简写为一个
xuexiao:school,
xuesheng:student
}
})
第三步:编写组件标签。
DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>title>
<script src="./js/vue.js">script>
head>
<body>
<div id="root">
<xuexiao>xuexiao>
<hr>
<xuesheng>xuesheng>
div>
<script type="text/javascript">
Vue.config.productionTip = false;
//创建school组件
const school = Vue.extend({
data(){
return {
schoolName:"北京大学",
address:"北京"
}
},
//使用template为这个组件添加上结构。
//注意每一个template必须要有并且只有一个div结构。
template:`
学校名称:{{schoolName}}
学校地址:{{address}}
`
});
//创建student组件
const student = Vue.extend({
data(){
return {
studentName:"张三",
age:18
}
},
template:`
学生姓名:{{studentName}}
学生年龄:{{age}}
`
})
//vm对象
new Vue({
el:"#root",
//使用components来注册组件(局部注册)
components:{
xuexiao:school,
xuesheng:student
}
})
script>
body>
html>
上面注册组件都是局部注册组件,也可全局注册组件
。
使用Vue.component(‘组件名’,组件变量名); 这样所有的vm对象都可以使用这个组件,不需要再在components中注册了。
正常我们在组件命名可以用简写的方式。
Vue.config.productionTip = false;
//定义组件
const school = Vue.extend({
template:`
学校名称:{{name}}
学校地址:{{address}}
`,
data(){
return {
name:"北京大学",
address:"北京"
}
}
})
new Vue({
el:"#root",
data:{
msg:"欢迎学习Vue!"
},
components:{
//正常写应该是school:school , 并且Vue的开发者工具中默认是变成大写开头的School。
school
}
})
对于多个单词组成的组件名,要如下格式:
DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>title>
<script type="text/javascript" src="./js/vue.js">script>
head>
<body>
<div id="root">
<h2>{{msg}}h2>
<my-school>my-school>
div>
<script type="text/javascript">
Vue.config.productionTip = false;
//定义组件
const school = Vue.extend({
template:`
学校名称:{{name}}
学校地址:{{address}}
`,
data(){
return {
name:"北京大学",
address:"北京"
}
}
})
new Vue({
el:"#root",
data:{
msg:"欢迎学习Vue!"
},
components:{
'my-school':school
}
})
script>
body>
html>
==组件的名字不要与我们正常dom元素的名字相同!==例如:我定义了一个名字为h2的组件,那这样在dom上面就直接显示了dom元素的h2标签了。
我们创建组件的时候,可以设置一个name属性配置,一旦设置了name属性,Vue的开发者工具中,它就会使用name的值来读取了。
组件名标签可以缩写为这种样式:
创建组件可以将Vue.extend()省略,只留下一个配置就行。这个是可以的,要知道。
嵌套就是在组件中,嵌套别的组件。
很简单,在组件中定义components就可以了。
有几个注意点:
DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>title>
<script type="text/javascript" src="./js/vue.js">script>
head>
<body>
<div id="root">
div>
<script type="text/javascript">
Vue.config.productionTip = false;
//定义student组件
const student = Vue.extend({
name:"student",
template:`
学生姓名:{{name}}
学生年龄:{{age}}
`,
data(){
return {
name:"张三",
age:"19"
}
}
})
//注意这里有个顺序问题,school组件要使用student组件,student要先加载!
//定义school组件
const school = Vue.extend({
name:"school",
template:`
学校名称:{{name}}
学校地址:{{address}}
`,
data(){
return {
name:"北京大学",
address:"北京"
}
},
//在组件中,注册组件,也就是嵌套组件
components:{
student
}
})
//一般我们通过一个app的组件,来统一管理所有的组件。
const app = Vue.extend({
template:`
`,
components:{
school,
student
}
})
const vm = new Vue({
template:" ",
el:"#root",
components:{
app
}
})
script>
body>
html>
先说一下,VueComponent是怎么出现的,它是通过Vue.extend()被创建出来的!
组件的创建全都依靠了VueComponent构造函数!!!(很重要!)
我们先console.log()一下组件,看看组件的本质。
本质上就是一个VueComponent的构造函数
。
VueComponent构造函数的注意事项:
VueComponent的构造函数
,且不是程序员定义的,是Vue.extend生成的这个VueComponent构造函数。每次调用Vue.extend,返回的都是一个全新的VueComponent!!!也就是模板发现一次组件名对应的标签,就返回一个新的VueComponent。
这些组件的this指向VueComponent实例对象,而不是vue实例对象
。通过控制台查看组件在Vue实体对象的位置,在$children。
首先,了解对于js的原型链方面的知识。
显示原型属性,隐式原型属性。
Vue.config.productionTip = false;
//定义一个构造函数,构造函数和普通函数没什么区别,构造函数开头一般大写。
function Demo(){
this.a = 1;
this.b = 2;
}
//创建Demo实例对象
const d = new Demo();
console.log(Demo.prototype)//显示原型属性
console.log(d.__proto__)//隐式原型属性
//上面这两个对象都对应一个原型对象!
//这里我们设置了Demo的原型属性。
Demo.prototype.x = 99;
//对应的也能在d中找到他对应的原型属性。
console.log(d.__proto__.x);
console.log(d.x);
重要的内置关系就是:组件名.prototype.__prote__ === Vue.prototype 。注意这里的组件名就是VueComponent构造函数
下面的红线,蓝线,黄线都是通过原型链来指向的。
记住VueComponent的原型对象会先指向Vue的原型对象,这样他们之间就会有一个原型链的关系。
(上面这种方式的好处就是当我们设置Vue原型对象的一些属性,也能在组件对象中获取到。)
一说到单文件组件就立刻想到是xxx.vue形式的,我们开发中都是使用的单文件组件。
这里我们想要使用.vue文件就必须要使用vue脚手架的环境。
组件的命名方式最好是下图粉色对号,因为Vue大多数都是这种形式的写法我们也按照这种写法写比较标准。
VS Code可能不认识xxx.vue文件类型的,我们可以下载一个叫Vetur的组件来解决。
单文件组件和非单文件组件的对比:
export暴露就是为了让别人能够引入它。组件就是哪里需要哪里搬。
export有三种暴露方式:
因为const school = Vue.extend({…}); 是可以简写为const school = {…}; 这是Vue的简写形式。
并且我们一定要定义name属性,定义好组件的名字,这样别人使用的时候就可以用该名字来操作了。
大体结构如下:
<template>
<div id="root">
<div>
<h2>学校名称:{{schoolName}}h2>
<h2>学校地址:{{address}}h2>
<button @click="showName">点我提示学校名字button>
div>
div>
template>
<script>
// 组件交互的代码
export default {
name:"School",//给组件起名字,这里的name和我们的当前.vue文件要一致(标准写法)。
data(){
return {
schoolName:"北京大学",
address:"北京"
}
},
methods:{
showName(){
alert(this.schoolName);
}
}
}
script>
<style>
/* 组件的样式 */
style>
这个组件是必不可少的,它是用来汇总所有组件的!
注意下面的注释!
App.vue文件:
<template>
<div id="root">
<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>
<style>
style>
在组件中是不可能有new Vue()对象的!但是在那里创建Vue实例对象呢?就是在main.js中创建Vue实例对象。
main.js不会导入其他的组件,只会导入App.vue组件。因为App.vue组件规定就是所有组件的汇总!
main.js文件:
import App from './App.vue'
new Vue({
el:"#root",
template:` `,//在这里写好了就不用再去index.html或其他网页写标签了。
components:{
App
}
})
main.js已经为我们创建了Vue实例对象,并且还导入了App.vue的组件。这样我们就可以在一个网页来进行了,一般我们在index.html网页来修饰。
DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>单文件组件语法title>
head>
<body>
<div id="root">
div>
<script type="text/javascript" src="../lib/vue.js">script>
<script type="text/javascript" src="main.js">script>
body>
html>
Vue脚手架是Vue官方提供的标准化开发工具平台。
目前Vue脚手架最新版本是4.x版本。
官方vue cli网站:https://cli.vuejs.org/zh/guide/
这里的cli全称为:command line interface。
打开cmd,输入vue或vue --version,来查看是否安装了@vue/cli的安装包。
安装脚手架步骤:
babel是ES6转ES5,eslint是检查js格式的。
.gitignore:git的忽略文件,哪些内容不想让git接受管理,就在里面配置。
babel.config.js:配置babel的配置文件。这个文件一般不由开发人员操作。
package-lock.json记录了node_modules目录下所有模块的具体来源和版本号以及其他的信息。(npm自带的。)
package.json:记录当前项目所依赖模块的版本信息。(npm自带的。)
(通过上面,自然也有npm run build (构建html,js,css文件)和 npm run lint(语法检查)的命令。)
README.md:说明咱们的项目操作啥的,就像git里面的README.md一样。
node_modules导入了很多第三方库,想什么vue.js文件等等都在里面能找到。
src下的main.js文件:
当我们执行npm run serve 命令后,首先就运行main.js文件。换句话说,main.js文件是整个项目的入口文件
为什么main.js文件就是入口文件呢?
/*
main.js文件是整个项目的入口文件。
*/
//引入Vue
import Vue from 'vue'
//引入App组件,它是所有组件的父组件。
import App from './App.vue'
//关闭Vue的生产提示
Vue.config.productionTip = false
//创建Vue的实例对象
new Vue({
//指定容器app
el:"#app",
//render这行代码,作用是将App组件放入容器中。
render: h => h(App),
})
src下的assets目录:
src下的components目录:
我们自己定义的组件都往components目录下放置,该目录就是用来存储我们定义的组件。(除了App.vue组件不存放该目录的下面。)
src下的App.vue文件:
App.vue是所有组件的父组件。专门给main.js调用的。
favicon.ico文件:是网站图标。
index.html文件:是项目整个Vue应用的界面。Vue开发都是单页面应用开发(通过路由操作)。
DOCTYPE html>
<html lang="">
<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">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= htmlWebpackPlugin.options.title %>title>
head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.strong>
noscript>
<div id="app">div>
body>
html>
为什么main.js都没有被index.html引入,就能使用main.js里面的东西呢?