1.组件化
1.组件的使用
Vue中使用组件的三大步骤:
1.定义组件(创建组件)
2.注册组件
3.使用组件(写组件标签)
1.如何定义一个组件
使用Vue.extend(options)
创建,其中options
和new Vue(options)
时传入的那个options
几乎一样,但也有点区别;
区别如下:
1.el不要写,为什么? ——— 最终所有的组件都要经过一个vm的管理,由vm中的el决定服务哪个容器。
2.data必须写成函数,为什么? ———— 避免组件被复用时,数据存在引用关系。
备注:使用template可以配置组件结构。
2.如何注册组件?
1.局部注册:靠new Vue
的时候传入components
选项
2.全局注册:靠Vue.component('组件名',组件)
<div id="root">
<hello></hello>
<!-- 使用组件 -->
<school></school>
<hr>
<student></student>
</div>
<div id="root2">
<hello></hello>
</div>
</div>
<script>
//定义组件
const school = Vue.extend({
template: `
<div>
<h2>{{name}}</h2>
<h2>{{address}}</h2>
</div>`,
data() {
return {
name: '尚硅谷',
address: '北京'
}
}
})
const student = Vue.extend({
template: `
<div>
<h2>{{name}}</h2>
<h2>{{age}}</h2>
</div>`,
data() {
return {
name: 'tom',
age: 17
}
}
})
//创建hello组件
const hello = Vue.extend({
template: `
<div>
<h2>你好啊!{{name}}</h2>
</div>`,
data() {
return {
name: 'Tom'
}
}
})
//注册全局组件
Vue.component('hello', hello)
//注册组件
new Vue({
el: "#root",
components: {
school: school,
student: student
}
})
new Vue({
el: "#root2"
})
</script>
2.注意点
1.关于组件名:
一个单词组成:
第一种写法(首字母小写):school
第二种写法(首字母大写):School
多个单词组成:
第一种写法(kebab-case命名):my-school
第二种写法(CamelCase命名):MySchool (需要Vue脚手架支持)
备注:
1.组件名尽可能回避HTML中已有的元素名称,例如:h2、H2都不行。
2.可以使用name配置项指定组件在开发者工具中呈现的名字。
2.关于组件标签:
第一种写法:<school></school>
第二种写法:<school/>
备注:不用使用脚手架时,会导致后续组件不能渲染。
3.一个简写方式:
const school = Vue.extend(options)
可简写为:const school = options
3.组件嵌套
组件之间可以进行相互嵌套,
<script>
//注意,子组件必须写在父组件之前,否则,父组件无法解析子组件的内容
const student = Vue.extend({
template: `
<div>
<h2>{{name}}</h2>
<h2>{{age}}</h2>
</div> `,
data() {
return {
name: 'tom',
age: 17
}
}
})
//定义组件
const school = Vue.extend({
template: `
<div>
<h2>{{name}}</h2>
<h2>{{address}}</h2>
<student></student>
</div>
`,
data() {
return {
name: '尚硅谷',
address: '北京'
}
},
//注册组件
components: {
student: student
}
})
new Vue({
el: "#root",
components: {
school: school
}
})
</script>
另外,为了方便管理以及增强可读性,一般在项目中建一个app组件,用来存放其他组件信息,提高开发效率。
定义app组件
<script>
const app = Vue.extend({
//一般来说,模板信息里面配置的都是组件标签,
//而不用写出具体的HTML代码,html代码可以在各自的组件模块进行编写
template: `<div>
<school></school>
<hello></hello>
</div>`,
components: {
school: school,
hello: hello
}
})
</script>
4.VueComponent
1.school组件本质是一个名为VueComponent
的构造函数,且不是程序员定义的,是Vue.extend
生成的。
2.我们只需要写<school/>
或<school></school>
,Vue解析时会帮我们创建school组件的实例对象,即Vue帮我们执行的:new VueComponent(options)
。
3.特别注意:每次调用Vue.extend
,返回的都是一个全新的VueComponent
4.关于this指向:
1.组件配置中:
data函数、methods中的函数、watch中的函数、computed中的函数 它们的this均是VueComponent实例对象
。
2.new Vue(options)配置中:
data函数、methods中的函数、watch中的函数、computed中的函数 它们的this均是Vue实例对象
。
5.VueComponent
的实例对象,以后简称vc(也可称之为:组件实例对象)。Vue的实例对象,以后简称vm。
2.Vue脚手架
1.使用脚手架
官方文档
https://cli.Vuejs.org/zh/
第一步(仅第一次执行):全局安装@Vue/cli
。
npm install -g @Vue/cli
第二步:切换到你要创建项目的目录,然后使用命令创建项目
Vue create xxxx
第三步:启动项目
npm run serve
备注:
- 如出现下载缓慢请配置 npm 淘宝镜像:
npm config set registry https://registry.npm.taobao.org
- Vue 脚手架隐藏了所有 webpack 相关的配置,若想查看具体的 webpack配置, 请执行:
Vue inspect > output.js
2.脚手架的文件结构
├── node_modules
├── public
│ ├── favicon.ico: 页签图标
│ └── index.html: 主页面
├── src
│ ├── assets: 存放静态资源
│ │ └── logo.png
│ │── component: 存放组件
│ │ └── HelloWorld.Vue
│ │── App.Vue: 汇总所有组件
│ │── main.js: 入口文件
├── .gitignore: git版本管制忽略的配置
├── babel.config.js: babel的配置文件
├── package.json: 应用包配置文件
├── README.md: 应用描述文件
├── package-lock.json:包版本控制文件
3.Vue的版本问题
Vue.js
与Vue.runtime.xxx.js
的区别:Vue.js
是完整版的Vue,包含:核心功能 + 模板解析器。Vue.runtime.xxx.js
是运行版的Vue,只包含:核心功能;没有模板解析器。
- 因为
Vue.runtime.xxx.js
没有模板解析器,所以不能使用template这个配置项,需要使用render函数接收到的createElement函数去指定具体内容。
关于Vue.config.js - 使用
Vue inspect > output.js
可以查看到Vue脚手架的默认配置。 - 使用
Vue.config.js
可以对脚手架进行个性化定制,详情见:https://cli.Vuejs.org/zh
4.Vue脚手架项目入门
一般来说,public底下的文件一般不用动,主要有图标信息和页面信息,其中在页面的一下地方用来作为页面的展示区域,其他文件只需要找到id为app的地方就可以
<div id="app">
<!-- built files will be auto injected -->
</div>
</body>
src底下是我们项目功能代码主要编写的地方,其中app.Vue
里面配置了其他组件信息
<template>
<div>
<School/>
<School/>
</div>
</template>
<script>
//导入school组件
import School from '../src/components/School.Vue'
export default{
name:"App",
components:{
School
}
}
</script>
components文件夹底下主要是不同类型的组件信息,可以写不同的组件
<template>
<div class="school">
<h2>学校名称:{{name}}</h2>
<h2>学校地址:{{address}}</h2>
</div>
</template>
<script>
export default{
name:'School',
data(){
return{
name:"xx大学",
address : "北京市"
}
}
}
</script>
<style>
.school{
background-color: aqua;
}
</style>
main.js是项目的入口文件,引入了许多不同的外部资源
<script>
//导入Vue的js文件
import Vue from 'Vue';
import App from './App.Vue';
Vue.config.productionTip=false;
new Vue({
el:"#app",
render:h=>h(App)
})
</script>
5.ref属性
- 被用来给元素或子组件注册引用信息(id的替代者)
- 应用在html标签上获取的是真实DOM元素,应用在组件标签上是组件实例对象
- 使用方式:
- 打标识:
<h1 ref="xxx">.....</h1>
或<School ref="xxx"></School>
- 获取:
this.$refs.xxx
- 打标识:
<div>
<h2 v-text="msg" ref="title"></h2>
<button @click="showBtn" ref="btn">点我输出上方元素
</button>
<School ref="sch"></School>
<Student sex="男" :age="12"></Student>
</div>
<script>
methods:{
showBtn(){
// console.log("123")
console.log(this.$refs.btn);
console.log(this.$refs.sch);
console.log(this.$refs.title);
}
}
</script>
6.props配置项
- 功能:用于父组件给子组件传递数据
- 传递数据:
<Demo name="xxx"/>
- 接收数据:
- 第一种方式(只接收):
props:['name']
- 第二种方式(限制类型):
props:{name:String}
- 第三种方式(限制类型、限制必要性、指定默认值):
- 第一种方式(只接收):
props:{
name:{
type:String, //类型
required:true, //必要性
default:'老王' //默认值
}
}
备注:props是只读的,Vue底层会监测你对props的修改,如果进行了修改,就会发出警告,若业务需求确实需要修改,那么请复制props的内容到data中一份,然后去修改data中的数据。
<template>
<div>
<h1>{{msg}}</h1>
<h2>学生姓名:{{name}}</h2>
<h2>学生性别:{{sex}}</h2>
<h2>学生年龄:{{myAge+1}}</h2>
<button @click="updateAge">尝试修改收到的年龄</button>
</div>
</template>
<script>
export default {
name:'Student',
data() {
console.log(this)
return {
msg:'我是一个尚硅谷的学生',
myAge:this.age
}
},
methods: {
updateAge(){
this.myAge++
}
},
//简单声明接收
// props:['name','age','sex']
//接收的同时对数据进行类型限制
/* props:{
name:String,
age:Number,
sex:String
} */
//接收的同时对数据:进行类型限制+默认值的指定+必要性的限制
props:{
name:{
type:String, //name的类型是字符串
required:true, //name是必要的
},
age:{
type:Number,
default:99 //默认值
},
sex:{
type:String,
required:true
}
}
}
</script>
7.mixin(混入)
- 功能:可以把多个组件共用的配置提取成一个混入对象
- 使用方式:
第一步定义混合:
{
data(){....},
methods:{....}
....
}
第二步使用混入:
全局混入:Vue.mixin(xxx)
局部混入:mixins:['xxx']
以下举个例子来直观的理解一下mixin,假设再student与school中有一个相同的方法用来展示姓名,代码如下
student.vue
<template>
<div>
<h2 @click="showName">学生姓名:{{name}}</h2>
<h2>学生性别:{{sex}}</h2>
</div>
</template>
<script>
export default {
name:'Student',
data() {
return {
name:'张三',
sex:'男'
}
},methods: {
showName(){
alert(this.name)
}
}
}
</script>
school.vue
<template>
<div>
<h2 @click="showName">学校名称:{{name}}</h2>
<h2>学校地址:{{address}}</h2>
</div>
</template>
<script>
export default {
name:'School',
data() {
return {
name:'尚硅谷',
address:'北京',
x:666
}
},
methods: {
showName(){
alert(this.name)
}
}
}
</script>
这里,我们可以将两块代码相同的部分抽取出来,放到minx.js中,然后再需要的地方引用即可。代码如下
minx.js
export const hunhe = {
methods: {
showName(){
alert(this.name)
}
},
mounted() {
console.log('你好啊!')
},
}
export const hunhe2 = {
data() {
return {
x:100,
y:200
}
},
}
student.vue
<template>
<div>
<h2 @click="showName">学生姓名:{{name}}</h2>
<h2>学生性别:{{sex}}</h2>
</div>
</template>
<script>
import {hunhe,hunhe2} from '../mixin'
export default {
name:'Student',
data() {
return {
name:'张三',
sex:'男'
}
}
}
mixins:[hunhe,hunhe2]
}
</script>