1. 什么是组件化
组件化就是把重复的代码提取出来合并成为一个个组件,组件最重要的就是重用(复用),位于框架最底层,其他功能都依赖于组件,可供不同功能使用,独立性强。
Vue 的组件分为全局组件和局部组件。
2. 全局组件与局部组件
2.1 全局组件和局部组件的区别
- 全局组件: 全局组件注册后,任何Vue实例都可以使用。
- 局部组件:只能在当前组测它的Vue实例中使用
2.2 全局组件
2.3 局部注册
局部注册效果图:
2.4 代码部分
2.4.1 全局组件注册代码
<!DOCTYPE html>
<html lang="en">
<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>Document</title>
</head>
<body>
<div id="app">
<!-- 全局组件注册第二步:使用 短横线语法书写组件标签 -->
<!-- 注册组件时名称可以用驼峰命名法和短横线命名法但是使用时必须用短横线命名法 -->
<content-header></content-header>
<template id="header">
<h2>我是模板字符串</h2>
</template>
</div>
<script src="../lib/dep/plugins/vue.js"></script>
<script>
// 全局组件第一步: 注册全局事件
/**
全局组件注册语法:
Vue.component('组件名称',{
data:"组件数据" //与实例不同,这个data必须是函数,且必须返回一个对象
template:模板内容或模板所在的ID //es6 模板语法
})
*/
Vue.component("contentHeader", {
data() {
return {
}
},
//方法一:直接在template 使用模板字符串
// template: `
// <div>
// <h2>我是模板字符串</h2>
// </div>
// `
// 方法二:在html上使用template标签 通过ID绑定组件注册中的template属性
template: "#header"
})
let app = new Vue({
el: "#app",
data() {
return {
}
},
})
</script>
</body>
</html>
2.4.2 局部组件注册代码
<!DOCTYPE html>
<html lang="en">
<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>Document</title>
</head>
<body>
<div id="app">
<index-search></index-search>
<!-- 局部组件写法1 -->
<template id="demo2">
<h2>我是组件二</h2>
</template>
<index-banner></index-banner>
</div>
<script src="../lib/dep/plugins/vue.js"></script>
<script>
// 局部组件写法二
let demo3 = {
data() {
return {
text: "我是组件3"
}
},
template: `<div> {{text}} </div> `
}
let app = new Vue({
el: "#app",
// 局部组件注册在Vue实例的components中
components: {
// 格式为组件名称:组件内容
//组件一无法显示 因为局部组件不支持模板字符串写法
"index-search": `
<div>
<h2>我是组件1</h2>
</div>
`,
"index-nav": "#demo2",
"index-banner": demo3
}
})
</script>
</body>
</html>
3. 子组件和父组件
组件和组件之间存在层级关系。其中一种非常重要的关系就是父子组件的关系,即B组件在A组件的components属性中注册,那么A组件就是B组件的父组件,B组件也只能在A组件中使用(作用域)。
父组件向子组件传值
1.父组件通过v-bind 绑定到子组件标签上
2.子组件通过props接收数据
子组件向父组件传值
- 在子组件中,通过$emit()来触发事件,并传递参数。
- 在父组件中,通过v-on来监听子组件事件,并接收参数。
3.1 父组件向子组件传值
子组件是不能直接引用父组件或者Vue实例的数据的。需要通过父组件传递,子组件通过props接收。
在组件中,使用选项props来声明需要从父级接收到的数据。
props的值有两种方式:
1.字符串数组,数组中元素就是传递的数据名称。
<script>
Vue.component("index-header",{
//props推荐使用对象形式,更精准
//格式:props:["父组件传递过来的参数"]
props:["index","type"] //方式一 不推荐
})
</script>
2.对象,对象可以设置传递的数据类型,也可以设置默认值等等
<script>
Vue.component("index-header",{
props:
// 对象形式 推荐
{
// 基础类型检查 (null匹配所有类型)
propA:Number,//传递的参数:传递的类型
//传递参数的类型可以是多个
propB:[String,Number],
// 还可以定义传递多个属性 如参数默认值 以及没传参数是否报错等
propC:{
type:Number,//传递参数的类型
//参数的默认类型 如果没传递参数显示0
//但是如果是复杂类型的参数 需使用函数写法 并且有返回值
//例如:default(){ return []}
default:0 ,
required:false,//如果父组件未传递参数是否报错
}
}
})
</script>
3.2 子组件向父组件传值
图上方法还有尚未优化的地方:可以把count 在子组件中定义 以及计算运算后传递到父组件 这样父组件只要this.count=count就好了,父组件中只需写一个方法 而不是两个
4. 组件之间通信
有时候我们需要父组件直接访问子组件,子组件直接访问父组件,或者是子组件访问根组件。
父组件访问子组件:使用** c h i l d r e n ∗ ∗ 或 ∗ ∗ children**或** children∗∗或∗∗refs**(推荐)
子组件访问父组件:使用**$parent**
4.1 $children
this.$children是一个数组类型,它包含所有子组件对象
效果图:
4.2 $refs (常用)
refs的使用:
- $refs和ref指令通常是一起使用的。
- 我们通过ref绑定组件标签,设置一个特殊的ID。
- 通过this.$refs.ID就可以访问到该组件了。
效果图:
5. 模块化
5.1 模块化概述
1. 传统开发模式的主要问题
命名冲突和文件依赖。
2. 通过模块化解决上述问题
模块化就是把单独的一个功能封装到一个模块(文件)中,模块之间互相隔离,但是又可以通过特定的接口公开内部成员,也可以依赖别的模块。
模块化是一种思想, 是将大工程拆成小的模块分治的思想,模块化侧重的功能的封装,主要是针对Javascript代码,隔离、组织复制的javascript代码,将它封装成一个个具有特定功能的的模块。
5.1 闭包实现
javascript 的模块化最初是使用闭包来实现的. 使用闭包包裹变量, 以屏蔽外界的访问来形成模块。
var demo = (function () {
return {
add: (a, b)=> {
return a + b;
}
}
})()
5.2 Common.js规范
Common.JS规范规定,每个模块内部,module变量代表当前模块。这个变量是一个对象,它的exports属性(即module.exports)是对外的接口。加载某个模块,其实是加载该模块的module.exports属性。require方法用于加载模块。
CommonJS模块的特点如下:
1.所有代码都运行在模块作用域,不会污染全局作用域。
2.模块可以多次加载,但是只会在第一次加载时运行一次,然后运行结果就被缓存了,以后再加载,就直接读取缓存结果。要想让模块再次运行,必须清除缓存。
3.模块加载的顺序,按照其在代码中出现的顺序。
1.模块分为单文件模块和包
2.模块成员导出 module.exports和exports
3.模块成员导入: require("模块标识符")
var fs = require("fs")
module.exports = function getContent(path) {
return fs.readFileSync(path).toString()
}
5.3 ES6模块化
ES6模块化的规范中定义
- 每一个JS文件都是一个独立的模块
- 导入模块成员使用import关键字
- 暴露模块成员使用export关键字
默认导入和默认导出
默认导出、导出语法:
注意 :每个模块只能使用一次export default
//m1.js
默认导出语法 : export default 默认导出的成员
//定义私有成员
lat a= 0
let b= 0
function show(){
console.log("我是方法")
}
// 将本模块私有成员暴露出去,供其他模块成员使用
//注意 :每个模块只能使用一次export default
export default{
a,
b,
show
}
//index.js
默认导入语法: import 接收名称 from '模块标识符'
import item from '../m1.js'
console.log(item.a)
console.log(item.B)
item.show()
按需导入和按需导出
每个模块中可以使用多次按需导出
按需导入和按需导出语法:
//m1.js
//按需导出语法 export 需要导出的元素
export let name="股票怎么绿了"
let age= 30
export age
export remove =()=>{console.log("茅台快涨")}
//index.js
//按需导入语法:import {要导入属性名} from"模块标识符"
import {name, age, remove} from "./m1.js"
console.log(name)
console.log(age)
6. 模块化和组件化的区别
模块化
模块化侧重于功能或者数据的封装,一组相关的组件可以定义成一个模块,一个暴露了通用验证方法的对象可以定义成一个模块,一个全局的json配置文件也可以定义成一个模块。封装隔离来后,更重要的是解决模块间的依赖关系。
组件化
组件化更多关注的是UI部分,你看到的一个管理界面的弹出框,头部,内容区,确认按钮和页脚都可以是个组件,这些组件可以组成一个弹出框组件,跟其他组件组合又是一个新的组件。
**模块:**按照项目业务内容来划分大模块;
**组件:**按照一些小功能的通用性和可复用性来抽象组件;