想利用暑假时间好好学习一下vue,会记录每一天的学习内容。 今天是学习vue的第6 天!
起起伏伏乃人生常态,继续加油~
1. 插槽slot
生活中很多地方都有插槽,电脑的USB插槽,插板当中的电源插槽 插槽的目的是让我们原来的设备具备更多的扩展性
组件的插槽:
- 组件的插槽也是为了让我们封装的组件更加具有扩展性
- 让使用者可以决定组件内部的一些内容到底展示什么
如何封装这类组件呢?
如何封装合适呢?抽取共性,保留不同
- 最好的封装方式是将共性抽取到组件中,将区别暴露为插槽
- 一旦我们预留了插槽,就可以让使用者根据自己的需求,决定插槽中插入什么内容
slot基本使用
如何使用slot ?
- 在子组件中,使用特殊的元素
<slot> 可以为子组件开启一个插槽 - 该插槽插入什么内容取决于父组件如何使用
我们通过一个简单的例子,来给子组件定义一个插槽:
<slot> 中的内容表示:如果没有在该组件中插入任何其他内容,就默认显示该内容- 有了这个插槽,父组件如何使用呢?
具名插槽slot
当子组件的功能复杂时,子组件的插槽可能并非是一个
- 比如我们封装一个导航栏的子组件,可能就需要三个插槽,分别代表左边、中间、右边
- 那么,在给插槽插入内容时,我们需要区分插入的是哪一个插槽
- 这时,需要给插槽起一个名字
如何使用具名插槽呢?
- 给
slot 元素添加一个name 属性 <slot name="center"><slot>
2. 编译作用域
可以渲染出来,也就是<cpn v-show="isShow"></cpn> 使用的是Vue 实例的属性
为什么呢?
- 官方给出了一条准则:
父组件模版的所有东西都会在父级作用域内编译; 子组件模版的所有东西都会在子级作用域内编译 - 我们在使用
<cpn v-show="isShow"></cpn> 时,整个组件的使用过程是在父组件Vue 实例的模版中出现的 - 那么他的作用域就是父组件,使用的属性也是属于父组件的属性
- 因此,
isShow 使用的是Vue 实例中的属性,而不是子组件的属性
比如:
<div id="app">
<cpn v-show="isShow"></cpn>
<cpn v-for="item in names"></cpn>
</div>
查找isShow 、names 变量,会看其是在哪一个模版中使用的,这里就是在属于Vue 实例的模版中使用,那么就会在Vue 实例中查找isShow 、names 变量。这里的isShow 、names 变量就是在Vue 实例的作用域内
<template id="cpn">
<div>
<h2>我是子组件</h2>
<p v-show="isShow">我是内容</p>
</div>
</template>
此处查找isShow 变量,则会在该模版(id=“cpn”)对应的组件中查找
3. 作用域插槽
父组件替换插槽标签,但是内容由子组件来提供 我们先提一个需求:
- 子组件中包含一组数据,比如:
pLanguages: ['JavaScript', 'c++', 'Python', 'Java', 'c#', 'Swift'] - 需要在多个页面进行展示:
- 某些页面是以水平方向展示的
- 某些页面是以列表形式展示的
- 某些页面直接展示一个数组…
- 数据在子组件,但是希望父组件告诉我们如何展示,但是父组件不能直接拿到子组件中的数据,怎么办呢?
作用域插槽:准备 在父组件使用我们的子组件时,从子组件如何拿到数据:
- 我们通过
<template slot-scope=slot"> 获取slot 属性 (目前vue的版本已支持,这里不是非要写template) - 再通过
slot.data 就可以获取到刚才我们传入的data 了
4.模块化开发
我们通常会将代码组织在多个js文件中,进行维护,但是这种维护方式,依然不能避免一些灾难性的问题
比如全局变量同名问题
flag = true
flag = false
if (flag) {
console.log(1);
}
但小明会发现代码不能正常运行。 我们可以使用匿名函数来解决这里的flag 重名问题 在小明的a.js 中,使用匿名函数
(function(){
var flag = true
})()
但是如果我们希望在main.js 文件中用到flag ,就不容易使用了,因为flag 此时定义在匿名函数的作用域中,是一个局部变量,无法在别处访问到
这时我们可以将需要暴露到外面的变量,使用一个模块作为出口
var ModuleA = (function() {
var obj = {}
obj.flag = true
obj.func = function (param) {
}
return obj
})()
我们在匿名函数的内部,定义了一个对象,给对象添加了一些需要暴露到外面的属性和方法,最后将这个对象返回,并且使用了一个ModuleA 变量接收 接下来就可以在main.js 中使用属于自己模块的属性和方法了
if (ModuleA.flag){
console.log(1);
}
ModuleA.func('111');
这就是模块最基础的封装 前端模块化开发已经有了很多既有的规范,以及对应的实现方案
常见的模块化规范
- CommonJs、AMD、CMD、ES6的Modules
CommonJs (了解)
模块化有两个核心:导出和导入
CommonJs 的导出:
module.exports = {
flag: true,
test(a,b){
return a+b
}
}
CommonJs 的导入:
let {flag,test} = require('./a.js');
let obj = require('./a.js');
let flag = obj.test;
let test = obj.test;
5.ES6模块化的导入和导出
export 使用
??:export 后必须跟语句
非法:export name;
export let name = 'AIpoem';
export let age = 18;
export let height = 180;
另一种写法:
let name = 'AIpoem';
let age = 18;
let height = 180;
export {name, age, height}
export function test(content) {
console.log(content)
}
export default 某些情况下,一个模块中包含某个功能,我们并不希望给这个功能命名,而且让导入者可以自己来命名
export default function () {
console.log("default function");
}
对应的导出:
import myFunc from './a.js'
??: export default 在整个模块中只能存在一个
import使用
首先我们需要在HTML 中引入两个js文件,并且type 需要设置为module
<script src="./a.js" type="module"></script>
<script src="./main.js" type="module"></script>
main.js 中可以利用import 指令导入a.js 中的内容
import {name, age, height} from './a.js'
console.log(name,age,height);
导入所有信息:
- 通过
* 可以导入模块中所有的export 变量 - 给
* 起一个别名,方便后续使用
import * as info from './a.js'
console.log(info.name);
console.log(info.height):
...
6.Webpack介绍
从本质上来讲,webpack是一个现代的JavaScript应用的静态模块打包工具
模块化:
- 在ES6之前,如果我们想要进行模块化开发,必须借助于其他的工具
- 并且在通过模块化开发完成了项目后,还需要处理模块间的各种依赖,并将其进行整合打包
webpack 其中一个核心就是让我们可以进行模块化开发,并且会帮助我们处理模块间的依赖关系- 不仅是
JavaScript 文件,我们的css 、图片 、json 文件在webpack 中都可以被当作模块来使用 - 这就是
webpack 中模块化的概念
打包:
- 就是将
webpack 中的各种资源模块进行打包,合并成一个或多个包 - 并且在打包的过程中,还可以对资源进行处理,比如压缩图片,将
scss 转成css ,将ES6 语法转成ES5 语法,将TypeScript 转成JavaScript 等操作 - 但是打包的操作,
grunt/gulp 也可以帮助我们完成,它们有什么不同呢?
和grunt/gulp的对比
grunt/gulp 的核心是Task
- 我们可以配置一系列的
task ,并且定义task 要处理的事务(例如ES6、ts转化、图片压缩、scss转成css) - 之后让
grunt/gulp 来一次执行这些task ,而且让整个流程自动化 - 所以
grunt/gulp 也被称为前端自动化任务管理工具
我们来看一个gulp 的task
- 下面的
task 就是将src 下面的所有js 文件转成ES5 的语法 - 并且最终输出到
dist 文件夹中
const gulp = require('gulp');
const babel = require('gulp-babel');
gulp.task('js', () =>
gulp.src('src/*.js')
.pipe(babel({
presets: ['es2015']
}))
.pipe(gulp.dest('dist'))
);
什么时候使用grunt/gulp ?
- 如果你的工程模块依赖非常简单,甚至没有用到模块化的概念
- 只需要进行简单的合并、压缩
- 但是如果整个项目使用了模块化管理,而且相互依赖非常强,我们就可以使用更加强大的
webpack 了
grunt/gulp 和webpack 的区别:
grunt/gulp 更强调前端流程的自动化,模块化不是它的核心webpack 更强调模块化开发管理
7. Webpack安装
- 安装
webpack 首先需要安装Node.js ,Node.js 自带了软件包管理工具npm 因为Node.js 之前我已经装好了 - 之后就可以使用
npm install webpack -g 全局安装webpack
??:mac安装的话要先执行sudo -s 这一步指令获取root权限,出现小钥匙之后输入开机密码,再按回车,之后再使用npm install webpack -g 才可以
- 安装完之后终端输入
webpack -v ,跳出来版本号就是安装成功了
后续可能需要局部安装webpack
|