一、slot
组件的插槽是为了让组件更具有扩展性,也可以让使用者决定组件内部的一些内容是什么
slot的基本使用
<div class = "app">
<cpnt></cpnt> /*没有插入标签,使用默认值*/
<cpnt>
<span>一个</span> /*插入一个标签*/
</cpnt>
<cpnt>
<span>多个</span> /*插入多个标签*/
<div>多个</div>
<h2>多个</h2>
</cpnt>
</div>
<template id = "cpnt">
<div>
<h2>子组件</h2>
<slot> /*定义插槽*/
<button>click</button> /*插槽的默认值,如果没有默认值则在使用插槽的时候把内容全部放在slot里面*/
</slot>
</div>
</template>
<script>
const cpnt = {
template: '#cpnt'
};
const app = new Vue({
el: '.app',
components: {
cpnt,
}
})
</script>
slot的具名插槽
<div class = "app">
<cpnt></cpnt> /*原始形态*/
<cpnt> /*使用slot属性*/
<span>slot没有slot属性就默认改没有name的插槽</span>
<span slot="leftclick">slot改左边插槽的内容</span>
<span slot="centerclick">slot改中间插槽的内容</span>
<span slot="rightclick">slot改右边插槽的内容</span>
</cpnt>
<cpnt> /*使用v-slot属性,不过v-slot必须在template或者自定义组件里面使用*/
<template v-slot:centerclick>
<span>v-slot改中间插槽的内容</span>
</template>
<template v-slot:default> /*没有定义name默认为default*/
<span>v-slot没有slot属性就默认改没有name的插槽</span>
</template>
<template v-slot:leftclick>
<span>v-slot改左边插槽的内容</span>
</template>
<template v-slot:rightclick>
<span>v-slot改右边插槽的内容</span>
</template>
</cpnt>
</div>
<template id = "cpnt">
<div>
<h2>子组件</h2>
<slot name="leftclick"> /*定义name,要注意大小写的关系,因为在HTML里面标签的attr属性大小写不敏感*/
<button>leftClick</button>
</slot>
<slot name="centerclick">
<button>centerClick</button>
</slot>
<slot name="rightclick">
<button>rightClick</button>
</slot>
<slot>
<button>noNameClick</button>
</slot>
</div>
</template>
<script>
const cpnt = {
template: '#cpnt'
};
const app = new Vue({
el: '.app',
components: {
cpnt,
}
})
</script>
不过在官网的2.6.0版本里面推荐使用v-slot指令(上面也有说明)
详情点击这里
也可以参考下面这里
作者:gongph
链接:https://juejin.im/post/5c64e11151882562e4726d98
来源:掘金
编译作用域
一句话:父级模板里的所有内容都是在父级作用域中编译的;子模板里的所有内容都是在子作用域中编译的。
点击查看官网
作用域插槽
父组件获得子组件里面的数据,再对数据进行与子组件不同渲染方式
比如下面的案例:
<div class = "app">
<cpnt></cpnt> /*默认组件*/
<cpnt>
<template v-slot:cname="slot1"> /*使用v-slot代替slot、slot-scope,且必须再template里面,
这里的slot1为插槽数据对象,cname为选择的那个插槽*/
<h2>{{ slot1 }}</h2>
<h4 v-for="item in slot1.names">{{ item }}--father</h4>
</template>
<template slot-scope="slot2" slot="cage"> /*必须再template里面,这里的slot2为插槽数据对象,cage为选择的那个插槽*/
<h2>{{ slot2 }}</h2>
<h4 v-for="items in slot2.ages">{{ items }}--father</h4>
</template>
</cpnt>
</div>
<template id = "cpnt">
<span>
<slot :names="name" name="cname" :ages="age"> /*确定name和与插槽的数据绑定*/
<h2>names</h2>
<ul>
<li v-for="item in name">{{ item }}--son</li>
</ul>
</slot>
<slot :ages="age" name="cage">
<h2>age</h2>
<ul>
<li v-for="item in age">{{ item }}--son</li>
</ul>
</slot>
</span>
</template>
<script>
const cpnt = {
template: '#cpnt',
data() {
return {
name: ['毛毛', '李老板', '涂涂', '翠花'],
age: [10, 20, 30, 40],
}
}
};
const app = new Vue({
el: '.app',
components: {
cpnt,
}
})
</script>
与$refs不同的是 v-slot是在 DOM里面获得数据 的,而前者是 在script标签里面获得数据
二、模块化开发(需要对应的环境)
为了避免全区变量重名、控制js的文件的引入顺序模块化开发应运而生,一个模块就是好比一个房间,不同房间有不同房间东西且不同房间是可以相互访问的
比如下面的的这个例子(以前ES5的写法):
常见的模块化开发:
CommonJS是node.js的模块化
三、模块化的两个核心:导入和导出
CommonJS的模块化 (需要nodejs环境)
导出(module.exports):
且module.exports等于exports,这里是把module.exports的地址传给了exports,且系统在查找导出值的时候只查找module.exports
例如:
let a = 100;
/*exports; 这里导出的是一个默认 { }
module.exports = a; 这里导出的是 100,不过这里都是注释没有导出值
*/
exports.a = a; // 这里给导出的对象添加了一个a属性,且值为100,对象为{ a: 100 }
module.exports.b = a; // 这里给导出的对象添加了一个b属性,且值为100,对象为{ a: 100, b: 100 }
exports = { user: '涂涂' } // 此时导出的仍然是{ a: 100, b: 100 },因为只更改了exports的指向,而系统查找的时候是找module.exports,当然module.exports并没有改变
/*module.exports = { user: '涂涂' } // 此时导出的是{ user: '涂涂' }
*/
导入(require):
导入的默认内容是对象,当然导出的也可以是定义的其他对象,也可以是数字与字符串。
require方法加载第三方包模块的机制:
1、 require(‘第三方包’)优先在加载第三方包的模块的同级目录下的node_modules中查找第三方包
2、 找到该第三方包中的package.json文件,并且找到里面的main属性对应的入口模块,该 入口模块即为加载的三方模块
3、 如果要加载的第三方包中没有找到package.json文件或者package.json中没有main属性,则默认加载第三方包的 index.js文件为第三方模块
4、 如果在加载第三方包的模块的同级目录下没有找到的node_modules,就依次往上找(父级),直到找到磁盘的根目录都没找到就会报错:can not find module xxx
要注意的是一个模块在第一次被使用的时候会执行一次,并在使用的过程中进行初始化,之后再把模块导出的结果 缓存起来一边下一次使用
例如:
let a = require('./index2'); // 执行一次,并缓存导出的结果
let b = require('./index2'); // 不会再执行,直接使用缓存导出的结果
console.log(a === b) // true
ES6的模块化
导出(export):
在导出的时候script标签必须要有type="module"
/*这个是导入与导出的大前提*/
<script type="module" src="aaa.js"></script>
导出方法一:
let name = '涂涂';
let age = 18;
function fn() {
console.log('Hello , world!');
}
class people {
constructor(name){
this.name = name;
}
sayHello(){
console.log('Hello, there');
}
}
export {
name,
age,
fn,
people
}
导出方法二:
/*定义时导出*/
export let name = '涂涂';
export let age = 18;
export function fn() {
console.log('Hello , world!');
}
export class people {
constructor(name){
this.name = name;
}
sayHello(){
console.log('Hello, there');
}
}
导出方法三:
/*这种导出只能在同一模块中,不允许存在多个*/
export default let name = '涂涂';
导入(import):
导入方法一:
/*下面这种导入方式对应着前面第一、二种的导出方法,不过这种方式不可以更改导入数据的变量名,必须有大括号*/
import {flag} from "./aaa.js";
导入方法二:
/*下面这种导入方式对应着前面第三种的导出方法,这种方式可以更改导入数据的变量名,且没有大括号*/
import names from "./aaa.js";
导入方法三:
/*下面这种导入方式对应着前面第一、二种的导出方法,这种方式是导出所有值并赋值给item(对象类型)*/
import * as item from "./bbb.js";
导入和导出的都为对象
四、webpack(依赖nodejs环境)
webpack是一个现代的JavaScript应用的静态模块打包工具,他可以在我们模块化开发完成后处理各个模块之间的依赖和对各种资源进行整合、打包合并成一个或多个包,我们的CSS、图片、json文件等在webpack中都可以被当作模块来使用,webpack强调的是模块化
而gulp的核心是task,且使用gulp的项目模块依赖很简单,gulp强调前端流程的自动化
webpack、nodejs、npm的关系
安装webpack首先需要安装nodejs,nodejs里面自带了软件包管理器npm,而npm里面可以下载webpack
五、Vue的打包
Vue在最终构建发布版本的时候,他构建了两个版本:
runtime-only:在代码里面不能有任何的template
runtime-compiler:在代码里,可以有template,因为compiler可以用于编译template
六、el与template的区别
template会完全替换el对应元素的内容
七、webpack的横幅plugin
plugin:插件,通常是对某个现有的框架的扩充
loader:只要用于转换某些类型的模块,他是一个转换器
plugin使用步骤:通过npm安装plugin(一些plugin已经内置就不需要安装了),然后再webpack.config.js里面配置插件
添加版权声明的plugin:
/*在webpack.config.js里面*/
const webpack = require('webpack');
module.exports = {
entry: ……
output: ……,
module: ……,
resolve: ……,
plugins: [
new webpack.BannerPlugin('最终版权归OoOinfinityOoO所有'),
]
};
打包html的plugin
他可以自动生成一个index.html 文件(也可以指定模板来生成),再将打包的js文件自动通过script标签来插入到body里面
/*通过npm安装*/
npm install html-webpack-plugin --sava-dev
/*修改webpack.config.js文件*/
const htmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: ……
output: ……,
module: ……,
resolve: ……,
plugins: [
new htmlWebpackPlugin({
template: './index.html'
}),
]
};
js的压缩plugin
/*通过npm安装*/
npm install uglifyjs-webpack-plugin@1.1.1 --save-dev
/*修改webpack.config.js文件*/
const uglifyjsWebpackPlugin = require('uglifyjs-webpack-plugin');
module.exports = {
entry: ……
output: ……,
module: ……,
resolve: ……,
plugins: [
new uglifyjsWebpackPlugin()
]
};
八、webpack-dev-server搭建本地服务器
/*通过npm安装*/
npm install webpack-dev-server@2.9.3 --save-dev
/*修改webpack.config.js文件*/
module.exports = {
entry: ……
output: ……,
module: ……,
resolve: ……,
plugins: ……,
devServer: {
contentBase: './dist',
inline: true
}
};
/*修改package.json文件*/
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack", /*构建时使用的脚本*/
"dev": "webpack-dev-server --open" /*开发时搭建本地服务器,--open是开启服务时自动打开localhost:8080*/
}
九、webpack配置的抽离
/*通过npm安装*/
npm install webpack-merge
const webpackMerge = require('webpack-merge');
const baseConfig = require('./base.config');
module.exports = webpackMerge(baseConfig, {
……
});
三个文件分别是base.config.js、prod.config.js、dev.config.js
再对package.json配置
以上的都是关于vue cli2的手动配置(头大),不过以后都是通过脚手架来进行配置
本文只用于个人学习与记录