若重要,总会想办法(Vue学习笔记two)
志向太远,不可怕;没有到达,不可怕;可怕的是没有志向,失去了奋斗的方向。
你好,我是梦阳辰!期待与你相遇!
为什么要使用插槽?
slot翻译为插槽:
在生活中很多地方都有插槽,电脑的USB插槽,插板当中的电源插槽。
插槽的目的是让我们原来的设备具备更多的扩展性。
比如电脑的USB我们可以插入U盘、硬盘、手机、音响、键盘、鼠标等等
组件的插槽
组件的插槽也是为了让我们封装的组件更加具有扩展性。让使用者可以决定组件内部的一些内容到底展示什么。
例子∶移动网站中的导航栏。
移动开发中,几乎每个页面都有导航栏。
导航栏我们必然会封装成一个插件,比如nav-bar
组件。一旦有了这个组件,我们就可以在多个页面中复用了。但是,每个页面的导航是一样的吗?
不一样!
即不同的组件要求展示的东西不一样,插槽就可以解决这个问题。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="../res/js/vue.js"></script>
</head>
<body>
<cpn>
</cpn>
<div id="app">
<my-cpn><button>我是被插入的东西1</button></my-cpn>
<my-cpn><button>我是被插入的东西2</button></my-cpn>
<my-cpn></my-cpn>
</div>
<template id="cpn">
<div>
<h3>{{title}}</h3>
<p>我是内容1</p>
<slot><h3>我是默认值</h3></slot><!--插槽,这里面也可写一些默认值-->
</div>
</template>
<script>
/*es6可以使用`来代替"和'
* */
//2.注册组件
Vue.component('my-cpn',{
template:`#cpn`,
data(){
return{
title:'有点东西!'
}
}
})
const app = new Vue({
el:"#app",
data:{
message:"梦阳辰你好!",
}
})
</script>
</body>
</html>
结果:
具名插槽(有名字)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="../res/js/vue.js"></script>
</head>
<body>
<cpn>
</cpn>
<div id="app">
<my-cpn><span slot="center">搜索框</span></my-cpn>
</div>
<template id="cpn">
<div>
<slot><h3>左边</h3></slot><!--插槽,这里面也可写一些默认值-->
<slot name="center"><h3>中间</h3></slot><!--插槽,这里面也可写一些默认值-->
<slot><h3>右边</h3></slot><!--插槽,这里面也可写一些默认值-->
</div>
</template>
<script>
/*es6可以使用`来代替"和'
* */
//2.注册组件
Vue.component('my-cpn',{
template:`#cpn`,
data(){
return{
title:'有点东西!'
}
}
})
const app = new Vue({
el:"#app",
data:{
message:"梦阳辰你好!",
}
})
</script>
</body>
</html>
vue根据变量在哪个模板,作用域就在哪个实例中。
准则∶父组件模板的所有东西都会在父级作用域内编译;子组件模板的所有东西都会在子级作用域内编译。
作用域插槽
父组件替换插槽的标签,但是内容由子组件来提供。
父组件想要拿到子组件中的数据:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="../res/js/vue.js"></script>
</head>
<body>
<div id="app">
<mycpn></mycpn>
<mycpn>
<template v-slot="slot">
<span>{{slot.data.join(' |')}}</span>
</template>
</mycpn>
</div>
<template id="cpn">
<div>
<slot :data="languages">
<ul>
<li v-for="item in languages">{{item}}</li>
</ul>
</slot><!--插槽,这里面也可写一些默认值-->
</div>
</template>
<script>
/*es6可以使用`来代替"和'
* */
const app = new Vue({
el:"#app",
data:{
message:"梦阳辰你好!",
},
components:{
mycpn:{
template:`#cpn`,
data(){
return{
languages:['java','c','c++','python','javaScript']
}
}
}
}
})
</script>
</body>
</html>
为什么要模块发开发?
如果没有模块开发,团队合作时,不同的人定义了同一个全局变量名,导致冲突。
并且当js文件过多时,弄清楚他们的顺序就是一件比较头疼的事情。
以前可以使用命名闭包的方式解决命名冲突问题。但是很多代码无法进行复用。
有什么方法解决复用问题吗?
以前:在es5时,可以在闭包内新建一个对象,保存你要复用的东西,然后用return返回改对象进行复用。
var modrleB =(function ({
//定义一个对象
var obj={}
var name =‘小红’var flag = false
console.log(name);
//在对象中添加要复用的东西
obj.flag = flag
return obj;
})()
上面是我们自定义的模块化。
但是:
幸运的是,前端模块化开发已经有了很多既有的规范,以及对应的实现方案。
常见的模块化规范:
CommonJS,AMD,CMD,ES6的Moduels
没错,在es6,自带模块化。
CommonJS的导出
module.exports m {
flag: true,test(a, b){
return a + b),
demo(a, b)(
return a b
)
CommonJS的导入
// ConmonS模块
let {test, demo, flag }= require( " modulcA ');
//等同于
let _mA- require( ' modu1cA");
let test =_mA.test;
let demo = _mA.demo;
let f1ag =_mA.flag;
node.js底层实现了这些功能
引入时声明模块化,模块之间就不能相互使用。
<script src="a.js" type="module"></script>
除非它自己导出一些内容,其他模块才能使用。
a.js
var name="小明"
var flag = true;
function sum(num1,num2) {
return num1-num2;
}
if(flag){
console.log(sum(3,6));
}
export{
flag,sum
}
b.js
var name="梦阳辰"
var flag = true;
function sum(num1,num2) {
return num1+num2;
}
if(flag){
console.log(sum(3,6));
}
export{
flag,sum
}
//导出方式二
export var num =1;
export function num3(num1,num2) {
return num1*num2;
}
c.js
import {flag,sum,num} from "./b.js";
if(flag){
alert(sum(20,30));
}
alert(num)
首页:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="a.js" type="module"></script>
<script src="b.js" type="module"></script>
<script src="c.js" type="module"></script>
</head>
<body>
</body>
</html>
export指令用于导出变量函数…。
//导出类
export class Person{
}
export default指令导出,导入时名字可以随意,但不允许存在多个。
var address ="上海市"
export default address;
导入:
import aa from "./a.js";
统一全部导入:
import * as ff from "./a.js";
从本质上来讲,webpack是一个现代的JavaScript应用的静态模块打包工具。
Webpack 是一个前端资源加载/打包工具。它将根据模块的依赖关系进行静态分析,然后将这些模块按照指定的规则生成对应的静态资源。
也就是:模块和打包。
webpack可以前端模块化方案的代码:转换成浏览器可以识别的代码。
前端模块化:
在ES6之前,我们要想进行模块化开发,就必须借助于其他的工具,让我们可以进行模块化开发。
并且在通过模块化开发完成了项目后,还需要处理模块间的各种依赖,并且将其进行整合打包。
然而webpack其中一个核心就是让我们可能进行模块化开发,并且会帮助我们处理模块间的依赖关系。
而且不仅仅是JavaScript文件,我们的CSS、图片、json文件等等在webpack中都可以被当做模块来使用(在后续我们会看到)。
这就是webpack中模块化的概念。
打包:
打包如何理解呢?
理解了webpack可以帮助我们进行模块化,并且处理模块间的各种复杂关系后,打包的概念就非常好理解了。
就是将webpack中的各种资源模块进行打包合并成一个或多个包(Bundle)。
并且在打包的过程中,还可以对资源进行处理,比如压缩图片,将scss转成css,将ES6语法转成ES5语法,将TypeScript转成JavaScript等等操作。
还有一种打包方式gulp/grunt他没有模块化,适合没有用到模块化的工程。
在安装 Webpack 前,你本地环境需要支持 node.js
node.js自带了软件包管理工具npm。
由于 npm 安装速度慢,本教程使用了淘宝的镜像及其命令 cnpm
npm install -g cnpm --registry = https://registry.npm.taobao.org
使用 cnpm 安装 webpack:
cnpm install webpack@3.6.0 -g
npm 和 cnpm 的区别
(1) 两者之间只是 node 中包管理器的不同
(2) npm是node官方的包管理器。cnpm是个中国版的npm,是淘宝定制的 cnpm (gzip 压缩支持) 命令行工具代替默认的 npm:
(3)如果因为网络原因无法使用npm下载,那cnpm这个就派上用场了。
全局安装与非全局安装:
-g:全局安装。将会安装在C:\Users\Administrator\AppData\Roaming\npm,并且写入系统环境变量; 非全局安装:将会安装在当前定位目录; 全局安装可以通过命令行在任何地方调用它,本地安装将安装在定位目录的node_modules文件夹下,通过require()调用;
你可以使用任何模块化开发:然后交给webpack打包:
例如使用commonJS模块导入导出:
mathUtil.js
function add(num1,num2) {
return num1+num2;
}
function multiplied(num1,num2){
return num1*num2;
}
module.exports={
add,multiplied
}
index.js
const {add,multiplied} =require('./mathUtils')
alert(add(20,50))
web打包:
先cd到项目目录:
在使用命令:
webpack 要打包的入口文件路径 指定目录和文件名称
webpack会自动处理依赖文件。
方式二:使用配置文件打包
通过cnpm init
命令建好package.json文件。
新建webpack.config.js文件:
const path = require('path')
module.exports={
entry:'./src/index.js',//入口
output: {
path:path.resolve(__dirname,'dist'),//动态获取路径,node语法
filename:'bundle.js'
},
}
cd到项目目录:在输入命令webpack
即可打包。
打包成功后,生成bundle.js文件:
/******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, {
/******/ configurable: false,
/******/ enumerable: true,
/******/ get: getter
/******/ });
/******/ }
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/