Vue基础(四)

一、插槽

1. 为什么使用slot

slot翻译为插槽,组件的插槽:

  1. 组件的插槽也是为了让我们封装的组件更加具有扩展性。
  2. 让使用者可以决定组件内容的一些内容到底展示什么。

京东头部导航栏例子:
在这里插入图片描述

2. 如何在组件中使用slot呢?

如何去封装这类的组件呢?

  1. 它们也很多区别,但是也有很多共性。
  2. 如果,我们每一个单独去封装一个组件,显然不合适:比如每个页面都返回,这部分内容我们就要重复去封装。
  3. 但是,如果我们封装成一个,好像也不合理:有些左侧是菜单,有些是返回,有些中间是搜索,有些是文字,等等

如何封装合适呢?抽取共性,保留不同

  1. 最好的封装方式就是将共性抽取到组件中,将不同暴露为插槽。
  2. 一旦我们预留了插槽,就可以让使用者根据自己的需求,决定插槽中插入什么内容。
  3. 是搜索框,还是文字,还是菜单。由调用者自己来决定。

3. slot的基本使用(匿名插槽)

了解了为什么用slot,我们再来谈谈如何使用slot?

  1. 在子组件中,使用特殊的元素<slot>就可以为子组件开启一个插槽。
  2. 该插槽插入什么内容取决于父组件如何使用。
<div id='app'>
        <comp>
			<a href="">这是a</a>
			<button type="button">按钮</button>
		</comp>
    </div>  

    <template id="tmpl">
        <div>
			<!-- <slot></slot> -->
            <h1>这是标题标签</h1>
			<slot></slot>
        </div>
    </template>
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    
  </style>
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
  <div id="app1">
    <my-con></my-con>
    <my-con>
      <h2>我是h2标签的内容</h2>
      <p>我是p标签的内容</p>
    </my-con>
  </div>
</body>

<template id="template1">
    <div>
      <slot>我是插槽中的默认内容!!</slot>
    </div>
</template>
<script>
  var componentA = {
    template: '#template1',
  }
  const vm1 = new Vue({
    el: '#app1',
    data: {
      
    },
    components: {
      myCon: componentA
    }
  })
</script>

</html>

4. 具名插槽

当子组件的功能复杂时,子组件的插槽可能并非是一个。

  1. 比如我们封装一个导航栏的子组件,可能就需要三个插槽,分别代表左边、中间、右边。
  2. 那么,外面在给插槽插入内容时,如何区分插入的是哪一个呢?
  3. 这个时候,我们就需要给插槽起一个名字

如何使用具名插槽呢?

  1. 非常简单,只要给slot元素一个name属性即可
  2. <slot name='myslot'></slot>
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    
  </style>
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
  <div id="app1">
    <my-con>
      <div slot="left">左侧</div>
      <div slot="right">右侧</div>
      <div slot="center">中间</div>
    </my-con>
  </div>
</body>

<template id="template1">
    <div>
      <slot name="left">我是左侧插槽中的默认内容!!</slot>
      <slot name="center">我是中间侧插槽中的默认内容!!</slot>
      <slot name="right">我是右侧插槽中的默认内容!!</slot>
    </div>
</template>
<script>
  var componentA = {
    template: '#template1',
  }
  const vm1 = new Vue({
    el: '#app1',
    data: {
      
    },
    components: {
      myCon: componentA
    }
  })
</script>

</html>

5. 作用域插槽

默认情况下,父组件使用子组件,插槽数据默认是拿父组件的数据,而不是子组件拿数据。

作用域插槽在父组件使用我们的子组件时, 插槽的数据从子组件中拿到数据,而不是从父组件拿到。

在这里插入图片描述

6. 作用域插槽的多种写法

  <div id='app'>
		<!-- 第一种写法 -->
		 <comp>
			<button slot="btn" slot-scope="obj">按钮{{obj.mynum}}、{{obj.tit}}</button>
        </comp>
		
		<!-- 第二种写法(主流) -->
		<comp>
			 <template slot="btn" slot-scope="obj">
			 	<button>按钮{{obj.mynum}}、{{obj.tit}}</button>
			 </template>			
		 </comp>
		 
		 <!-- 第三种写法 -->
		 <comp v-slot:btn="obj">
			<button >按钮{{obj.mynum}}、{{obj.tit}}</button>
		 </comp>
		
		<!-- 第四种写法 -->
		<comp>
			<template v-slot:btn="obj">
				<button >按钮{{obj.mynum}}、{{obj.tit}}</button>
			</template>		
		</comp>
    </div>  

二、Webpack

从本质上来说,webpack是一个静态模块打包工具

要想让我们写好的模块化代码在各式各样的浏览器上能做到兼容,就必须借助于其他工具;而webpack的其中一个核心就是让我们可以进行模块化开发,并帮我们处理模块间的依赖关系。不仅仅是Javascript文件,我们的css、图片、json文件等在webpack中都可以当作模块来使用,这就是webpack的模块化概念。

1. gulp和webpack

Gulp侧重于前端开发的 整个过程 的控制管理(像是流水线),我们可以通过给gulp配置不同的task(通过Gulp中的gulp.task()方法配置,比如启动server、sass/less预编译、文件的合并压缩等等)来让gulp实现不同的功能,从而构建整个前端开发流程。

gulpfile.js

var gulp = require('gulp');
var uglify = require('gulp-uglify'); //压缩代码

// 压缩js
gulp.task('uglify',function(){
    var combined = combiner.obj([
        gulp.src('src/scripts/**/*.js'), //需要压缩的js文件路径
        sourcemaps.init(),
        uglify(), //压缩js
        sourcemaps.write('./'),
        gulp.dest('dest/scripts') //生成的js文件的目录
    ]);
});

//默认任务
gulp.task('default',['uglify']);

Webpack有人也称之为 模块打包机 ,由此也可以看出Webpack更侧重于模块打包,当然我们可以把开发中的所有资源(图片、js文件、css文件等)都可以看成模块,最初Webpack本身就是为前端JS代码打包而设计的,后来被扩展到其他资源的打包处理。Webpack是通过loader(加载器)和plugins(插件)对资源进行处理的。

2. webpack初体验

1. 生成项目依赖文件
// 执行后生成package.json文件
 
2. 安装依赖
// 最后的参数-D是安装到package.json的开发依赖devDependencies(开发环境)对象里,也可以用 --save-dev代替
npm install webpack webpack-cli -D

// 全局安装webpack和webpack-cli
npm i webpack webpack-cli -g

// -S是--save的简写,这样安装的话,会安装到dependencies(生产环境)对象里,也可以用 --save代替
npm install jquery -S
// package.json
{
  "name": "webpack-demo",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "webpack": "^4.40.2",
    "webpack-cli": "^3.3.9"
  },
  "dependencies": {
    "jquery": "^3.4.1"
  }
}

devDependencies与dependencies的区别:

在发布npm包的时候,本身dependencies下的模块会作为依赖,一起被下载;devDependencies下面的模块就不会自动下载了;但对于项目而言,npm install 会自动下载devDependencies和dependencies下面的模块。

3.创建入口文件

index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <ul>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
  </ul>
</body>
<script src="./index.js"></script>
</html>

index.js

import $ from 'jquery'
$('ul li:even').css({background: 'red'})
$('ul li:odd').css({background: 'green'})

在浏览器打开

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eg975Ha0-1612656690612)(img/1568968799462.png)]

为什么会这样?因为浏览器并不兼容import引入模块这种方式,所以我们要用到webpack打包

4. 通过webpack打包

// 执行命令  output输出
webpack index.js -o dist/bundle.js

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ox3jKmdO-1612656690613)(img/1568968968751.png)]

出现这个报错,这是因为命令行执行时候会找全局的webpack,但是我们并没有安装全局的webpack,所以我们可以安装全局webpack,或者是使用脚本方式启动

package.json

{
  "name": "webpack-demo",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "webpack index.js -o dist/bundle.js"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "webpack": "^4.40.2",
    "webpack-cli": "^3.3.9"
  },
  "dependencies": {
    "jquery": "^3.4.1"
  }
}

执行package.json文件中添加的start命令

// 生成 dist文件夹和bundle.js文件
npm run start

然后再把index.html原来引入index.js的地方改成是通过webpack生成的bundle.js

<!--index.html文件-->
<!--<script src="./index.js"></script>-->
<script src="./dist/bundle.js"></script>

最终浏览器看到的效果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1ytia8cK-1612656690614)(img/1568969333664.png)]

优化

webpack index.js -o dist/bundle.js 这一句其实是可以写在一个配置文件里

webpack.config.js:

const path = require('path');

module.exports = {
  entry: path.join(__dirname, './index.js'),	// dirname代表索引到文件所在目录
  output: {
    path: path.join(__dirname, './dist'),
    filename: 'bundle.js'
  }
}

package.json:

"scripts": {
    "start": "webpack --config webpack.config.js"
  }

5.webpack-dev-server

这时候如果修改index.html的背景颜色red改成是gray,会发现浏览器刷新也没有效果,需要再跑一次npm run start命令才有用,这时候就需要webpack-dev-server(热重载)

安装:

npm install webpack-dev-server -D

package.json:

"scripts": {
    "start": "webpack-dev-server --config webpack.config.js --open --port 3002 --hot"
  }
// --open 自动打开浏览器
// --port 服务监听的端口 3002
// --hot  自动更新

这里注意:

1、启动webpack-dev-server后, 你在目标文件夹中是看不到编译后的文件的,实时编译后的文件都保存到了内存当中。想看到bundle.js文件,可以运行localhost:3002/bundle.js查看

2、既然bundle.js已经不在dist目录下,因此,如果没有其他的webpack配置项,上面的命令也可以简写为:

"scripts": {
  "start": "webpack-dev-server --open --port 3002 --hot"
}

index.html

<script src="./bundle.js"></script>

6. html-webpack-plugin

安装:npm install html-webpack-plugin -D

webpack.config.js

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: path.join(__dirname, './index.js'),
  output: {
    path: path.join(__dirname, './dist'),
    filename: 'bundle.js'
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: path.join(__dirname, './index.html'),
      filename: 'index.html'
    })
  ]
}

删掉index.html文件里面的bundle.js引用,因为html-webpack-plugin会自动把打包出来的bundle自动加到我们的index.html代码里

7. css-loader

创建一个index.css

index.css

body {
    background: skyblue;
}

index.js

import $ from 'jquery'
$('ul li:even').css({background: 'gray'})
$('ul li:odd').css({background: 'green'})

import './index.css'

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OBxTaBp5-1612656690615)(img/1568972642846.png)]

为什么报错,因为webpack默认是不识别.css文件的,需要我们通过 loader.css 文件进行解释成正确的模块。

安装css-loader和style-loader

npm install css-loader style-loader -D 
//index.css -> bundle.js -> style-loader -> <style> index.html
// css-loader的作用是将index.css文件解析为webpack能识别的模块,然后打包进bundle.js里面,但是这样样式并未成功显示在浏览器中。
// style-loader的作用就是将打包到bundle.js中的样式绑定到浏览器上,以style标签的形式显示出来

webpack.config.js

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: path.join(__dirname, './index.js'),
  output: {
    path: path.join(__dirname, './dist'),
    filename: 'bundle.js'
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: path.join(__dirname, './index.html'),
      filename: 'index.html'
    })
  ],
  module: {
    rules: [{
      test: /\.css$/,
      use: ['style-loader', 'css-loader']	// 注意:这里的数组是反向读取的(即从右往左)
    }]
  }
}

补充:引入的文件是less

安装:npm install less-loader less -D

规则:

{

​ test: /.less$/,

​ use: [‘style-loader’, ‘css-loader’, ‘less-loader’]

}

8. ES6 转 ES5

安装

npm install babel-core babel-loader@7.1.5 babel-plugin-transform-runtime babel-preset-env babel-preset-stage-0 -D
const fn = () => {
  console.log(123)
}

配置loader

{test:/\.js/,use:['babel-loader'],exclude:/node_modules/} 

exclude表示排除掉 node_modules下载的依赖项。这样可以加速网站开发,而且我们也只需要对我们的项目src

源文件进行编译即可。

新增.babelrc文件

{ 
    "presets":["env","stage-0"], 
    "plugins":["transform-runtime"] 
} 

新增并在index.js中引入main.js,然后使用es6语法

const fn = () => {
  console.log(123)
}

fn()

执行命令编译

npm run start 

编译后的结果

var fn = function fn() {\n    console.log(123);\n}

至此关于webpack的基本配置已经到这里。

解释

babel-present-env 仅仅包括 babel-present-2015 、2016、2017,不包括: babel-stage-x ,也不包括 babel-polyfill

babel-present-env 仅仅转换 新版的语法 如:箭头函数,并不转换新版api 如:Array.include转换新版

api及抹平浏览器之间的差异(兼容ie)需要 babel-polyfill

babel-polyfill 会污染全局,比较暴力。而 babel-plugin-transfrom-runtime 是哪里需要就给

哪里转换。

babel-plugin-transform-runtime 主要做了一下三件事:

当你使用 generators/async 函数时,自动引入 babel-runtime/regenerator (使用 regenerator

运行时而不会污染当前环境) 。

自动引入 babel-runtime/core-js 并映射 ES6 静态方法和内置插件(实现polyfill的功能且无全局污染,

但是实例方法无法正常使用,如 “foobar”.includes(“foo”) ) 。

移除内联的 Babel helper 并使用模块 babel-runtime/helpers 代替(提取babel转换语法的代

码)。

9. html热更新

在安装过html-webpack-plugin之后,安装:

npm install --save-dev raw-loader

在webpack.config.js中配置raw-loader:

module.exports = {
  ......
  module: {
    rules: [
      {
         test: /\.(htm|html)$/,
         use: [
           'raw-loader'
         ]
      },
      ......
    ]
  }
}

index.js 中引入html:

import './index.html'
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue基础Web项目模板下载非常简单,可以按照以下步骤进行: 第一步,打开浏览器,访问Vue官方网站(https://cn.vuejs.org/)。 第二步,点击页面上方的“文档”按钮,进入Vue的文档页面。 第三步,在文档页面的左侧导航栏中,找到“起步 - 快速原型”这一部分。 第步,在“起步 - 快速原型”部分中,你可以看到一个“下载vue-cli”按钮,点击它。 第五步,你将被带到Vue CLI的GitHub页面,这是Vue的一个脚手架工具,用于快速搭建Vue项目。 第六步,滚动页面,找到一个名为“vue-cli 3.x”的链接,点击它。 第七步,你将跳转到Vue CLI 3.x的npm页面,其中包含有关Vue CLI的详细信息和用法。 第八步,翻滚页面,你可以看到一个类似于“npm install -g @vue/cli”的命令,这是用于全局安装Vue CLI的命令。 第九步,打开终端,输入上述命令并执行,等待安装完成。 第十步,安装完成后,在终端中输入“vue create 项目名称”,其中“项目名称”是你想要创建的项目的名称。 第十一步,按照终端中的提示,选择需要的特性、配置和插件,然后等待项目创建完成。 第十二步,项目创建完成后,你就可以在本地磁盘中找到你的项目文件夹,里面包含了一个基础Vue Web项目模板。 总结起来,下载Vue基础Web项目模板只需要通过Vue CLI工具进行项目的创建和初始化,然后你就可以在本地磁盘中找到你的项目文件夹了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值