想利用暑假时间好好学习一下vue,会记录每一天的学习内容。
今天是学习vue的第6
天!
起起伏伏乃人生常态,继续加油~
生活中很多地方都有插槽,电脑的USB插槽,插板当中的电源插槽
插槽的目的是让我们原来的设备具备更多的扩展性
组件的插槽:
如何封装这类组件呢?
如何封装合适呢?抽取共性,保留不同
如何使用slot
?
可以为子组件开启一个插槽我们通过一个简单的例子,来给子组件定义一个插槽:
中的内容表示:如果没有在该组件中插入任何其他内容,就默认显示该内容当子组件的功能复杂时,子组件的插槽可能并非是一个
如何使用具名插槽呢?
slot
元素添加一个name
属性
为什么呢?
时,整个组件的使用过程是在父组件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”)对应的组件中查找
父组件替换插槽标签,但是内容由子组件来提供
我们先提一个需求:
pLanguages: ['JavaScript', 'c++', 'Python', 'Java', 'c#', 'Swift']
slot
作用域插槽为了让 data
在父级的插槽内容中可用,我们可以将data
作为
元素的一个属性绑定上去:
绑定在
元素上的属性被称为插槽 prop
在父组件使用我们的子组件时,从子组件如何拿到数据:
我们通过获取slot属性
再通过slot.data就可以获取到刚才我们传入data了
的slot-scope
语法已被废弃了
现在用这种:
在父级作用域中,我们可以使用带值的v-slot
来定义插槽 prop
的名字:
在这个例子中,我选择将包含所有插槽 prop
的对象命名为 slotProps
,但你也可以使用任意你喜欢的名字
⚠️: slotProps
是包含所有插槽 prop
的对象,一个
可能有多个插槽prop
,所以不能只用slotProps
,这里就是用了slotProps.data
我们通常会将代码组织在多个js文件中,进行维护,但是这种维护方式,依然不能避免一些灾难性的问题
比如全局变量同名问题
// a.js文件中,小明定义了一个变量
flag = true
// b.js文件中,小红定义了一个变量
flag = false
// main.js文件中,小明想通过flag进行一些判断,完成后续的事情
if (flag) {
console.log(1);
}
但小明会发现代码不能正常运行。
我们可以使用匿名函数来解决这里的flag
重名问题
在小明的a.js
中,使用匿名函数
(function(){
var flag = true
})()
但是如果我们希望在main.js
文件中用到flag
,就不容易使用了,因为flag
此时定义在匿名函数的作用域中,是一个局部变量,无法在别处访问到
这时我们可以将需要暴露到外面的变量,使用一个模块作为出口
var ModuleA = (function() {
// 1.定义一个对象
var obj = {}
// 2.在对象内部添加变量和方法
obj.flag = true
obj.func = function (param) {
//
}
// 3.将对象返回
return obj
})()
我们在匿名函数的内部,定义了一个对象,给对象添加了一些需要暴露到外面的属性和方法,最后将这个对象返回,并且使用了一个ModuleA
变量接收
接下来就可以在main.js
中使用属于自己模块的属性和方法了
if (ModuleA.flag){
console.log(1);
}
ModuleA.func('111');
这就是模块最基础的封装
前端模块化开发已经有了很多既有的规范,以及对应的实现方案
常见的模块化规范
模块化有两个核心:导出和导入
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;
⚠️:export
后必须跟语句
非法:export name;
export
指令用于导出变量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
指令用于导出函数或类export function test(content) {
console.log(content)
}
export default
export default function () {
console.log("default function");
}
对应的导出:
// 这里的myFunc可以根据需要来命名
import myFunc from './a.js'
⚠️: export default
在整个模块中只能存在一个
首先我们需要在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):
...
从本质上来讲,webpack是一个现代的JavaScript应用的静态模块打包工具
模块化:
webpack
其中一个核心就是让我们可以进行模块化开发,并且会帮助我们处理模块间的依赖关系JavaScript
文件,我们的css
、图片
、json
文件在webpack
中都可以被当作模块来使用webpack
中模块化的概念打包:
webpack
中的各种资源模块进行打包,合并成一个或多个包scss
转成css
,将ES6
语法转成ES5
语法,将TypeScript
转成JavaScript
等操作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
更强调模块化开发管理webpack
首先需要安装Node.js
,Node.js
自带了软件包管理工具npm
Node.js
之前我已经装好了npm install webpack -g
全局安装webpack
⚠️:mac安装的话要先执行sudo -s
这一步指令获取root权限,出现小钥匙之后输入开机密码,再按回车,之后再使用npm install webpack -g
才可以
后续可能需要局部安装webpack