0%

第十五天

第十五天

watch监视数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<!DOCTYPE html>
<html lang="zh-CN">

<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>watch属性</title>
<script src="./js/vue.js"></script>
<script src=""></script>
</head>

<body>

<div id="app">
<!-- 分析: -->
<!-- 1. 我们要监听到文本框数据的改变,这样才能知道什么时候去拼接出一个fullname -->
<!-- 2. 如何监听到 文本框的数据的改变? -->
<input type="text" v-model="firstname"> +
<input type="text" v-model="lastname"> =
<input type="text" v-model="fullname">
</div>
<script>
var vm = new Vue({
el: "#app",
data: {
firstname: '',
lastname: '',
fullname: '',
},
methods: {},
watch: {
// 使用这个属性可以监视data中指定的数据的变化,然后触发watch中对应的function处理函数
firstname: function (newVal, oldVal) { // firstname可加可不加'' ,如果是first-name就必须加''
// console.log('监视到了firstname的变化');
// this.fullname = this.firstname + '-' + lastname;
// console.log(newVal+'---'+oldVal);
this.fullname = newVal + "-" + this.lastname;
},
lastname: function (newVal) {
this.fullname = this.firstname + "-" + newVal;
}
}
});
</script>

</body>

</html>

watch监视路由地址的改变

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
<!DOCTYPE html>
<html lang="zh-CN">

<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>watch-监视路由地址的改变</title>
<script src="./js/vue.js"></script>
<script src="./js/vue-router.js"></script>
</head>

<body>

<div id="app">
<router-link to="/login">登录</router-link>
<router-link to="/register">注册</router-link>
<router-view></router-view>
</div>
<script>
var login = {
template: '<h1>登录组件</h1>'
};
var register = {
template: '<h1>注册组件</h1>'
}
var router = new VueRouter({
routes: [{
path: '/login',
component: login
},
{
path: '/register',
component: register
}
]
});
var vm = new Vue({
el: "#app",
data: {},
methods: {},
router,
watch: {
// this.$route.path
'$route.path': function (newVal, oldVal) {
// console.log(newVal + '---' + oldVal);
if (newVal === "/login") {
console.log("欢迎登录");
} else if (newVal === "/register") {
console.log("欢迎注册");
}
}
}
});
</script>

</body>

</html>

computed 计算属性的使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<!DOCTYPE html>
<html lang="zh-CN">

<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>computed</title>
<script src="./js/vue.js"></script>
<script src=""></script>
</head>

<body>

<div id="app">
<input type="text" v-model="firstname"> +
<input type="text" v-model="lastname"> =
<input type="text" v-model="fullname">
<p>{{fullname}}</p>
<p>{{fullname}}</p>
<p>{{fullname}}</p>
<!-- 三个只输出一次"fullname被触发",表示computed的缓存 -->
</div>
<script>
var vm = new Vue({
el: "#app",
data: {
firstname: '',
lastname: '',
// fullname:''
},
methods: {},
computed: { // 在computed中,可以定义一些属性,称为计算属性,其本质就是一个方法,只是在使用时是将其名称直接当做属性使用,并不会将计算属性当作方法调用

// 注意:计算属性,在引用时,一定不要加()去调用,直接将其当作普通属性使用即可
// 注意:只要计算属性function内部,所用的任何data中的数据发生变化,就会立即重新计算
// 注意:计算属性的求值结果,会被缓存,方便下次直接使用,如果计算属性中所有数据都没有发生过变化,则不会重新对计算属性求值
'fullname': function () {
console.log("fullname被触发");
return this.firstname + '-' + this.lastname;
}
}
});
</script>

</body>

</html>

watch、computed和methods之间的对比

  1. computed属性的结果会被缓存,除非依赖的响应式属性变化才会重新计算。主要当作属性来使用
  2. methods方法表示一个具体的操作,主要书写业务逻辑
  3. watch一个对象,键是需要观察的表达式,值是对应回调函数。主要用来监听某些特定数据的变化,从而进行某些具体的业务逻辑操作;可以看作是computedmethods的结合体

Webpack

什么是webpack

webpack是前端的一个项目构建工具,它是基于Node.js开发出来的一个前端工具

webpack使用

  1. npm init -y
  2. 创建两个文件夹src、dist(打包后输出的文件夹)
  3. 在src下新建index.html
  4. 在src下新建main.js(项目的JS入口文件)
  5. 测试打包 webpack ..js -o ..js
  6. 在index.html中手动引入bundle.js

webpack实现自动打包

  1. 安装webpack-dev-server npm i webpack-dev-server -D
  2. 在根目录新建webpack.config.js文件并进行配置
  3. 根据提示安装本地webpack和webpack-cli
  4. 在package.json添加指令
  5. 在终端 npm run dev

webpack使用插件

  1. 安装html-webpack-plugin npm i html-webpack-plugin -D(根据index.html在内存中生成页面并将bundle.js注入)
  2. 在webpack.config.js配置plugins

webpack使用第三方loader模块

  1. 安装css-loader style-loader npm i style-loader css-loader -D
  2. 在webpack.config.js中配置module
  3. 在main.js使用import引用
  4. 其它非js文件的使用同理(图片和字体文件都对应 file-loader url-loader)

webpack实例

index.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<!DOCTYPE html>
<html lang="zh-CN">

<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>列表隔行变色</title>
<!-- 注意:不推荐直接在这里引用任何包和css文件 -->
<!-- main中的代码,涉及到es6新语法,浏览器不识别 -->
<!-- <script src="main.js"></script> -->
<!-- 通过webpack,将main.js进行处理,生成bundle.js -->
<!-- <script src="/bundle.js"></script> -->
<!-- 当使用html-webpack-plugin之后,我们不再需要手动处理bundle.js的引用路径了,因为这个插件已经自动创建了一个script并引用了正确的路径 -->

<!-- 能实现,但会产生二次请求 -->
<!-- <link rel="stylesheet" href="./css/index.css"> -->
</head>

<body>
<ul>
<li>这是第1个li</li>
<li>这是第2个li</li>
<li>这是第3个li</li>
<li>这是第4个li</li>
<li>这是第5个li</li>
<li>这是第6个li</li>
<li>这是第7个li</li>
<li>这是第8个li</li>
<li>这是第9个li</li>
<li>这是第10个li</li>
</ul>
<div id="app"></div>

<span class="glyphicon glyphicon-heart" aria-hidden="true"></span>
<script>

</script>

</body>

</html>

webpack.config.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
// 配置文件
const path = require('path');

// 启用热更新的第二步
// const webpack = require('webpack');
// 导入在内存中生成HTML页面的插件
// 只要是插件,都一定要放到plugins节点中
const htmlWebpackPlugin = require('html-webpack-plugin');
// 插件的两个作用:
// 1. 自动在内存中根据指定页面生成一个内存页面
// 2. 自动把打包好的bunlde.js 追加到页面中

// 这个配置文件,其实就是一个JS文件,通过Node中的模块操作,向外暴露一个配置对象
module.exports = {
entry: path.join(__dirname, './src/main.js'), //入口,表示要使用webpack打包哪个文件
output: { // 输出文件相关的配置
path: path.join(__dirname, './dist'), //指定打包好的文件输出目录
filename: 'bundle.js' //指定输出文件名称

},
// devServer: {
// contentBase: path.join(__dirname, './src'),
// port: 3000,
// open: true,
// hot: true // 网页不刷新即可重载;bundle.js以打补丁形式更新,启用热更新的第一步
// },
// plugins:[ // 配置插件的节点
// new webpack.HotModuleReplacementPlugin() //new 一个热更新的模块对象,第三步
// ]
plugins: [
new htmlWebpackPlugin({ // 创建一个在内存中生成HTML页面的插件
template: path.join(__dirname, './src/index.html'), // 指定模板页面,将来会根据指定页面路径,去生成内存中页面
filename: 'index.html' //指定生成的页面的名称
})
],
module: { //这个节点用于配置所有第三方模块加载器
rules: [ // 所有第三方模块的匹配规则
{
// 配置处理.css文件的第三方loader
test: /\.css$/,
use: ['style-loader', 'css-loader'] // 调用顺序:从右到左
},
{ // 处理图片路径
test: /\.(jpg|png|gif|bmp|jpeg)$/,
use: 'url-loader?limit=1000&name=[hash:8]-[name].[ext]'
// limit 给定的值是图片的大小,单位是字节,如果引用的图片大于或等于limit,则不会被转为base64格式字符串,否则会被转为base64
// name用来表示图片名,[hash:8]表示8位哈希值 防止重名 [name]表示原名称 [ext]表示原后缀名
},
{ // 处理字体文件
test: /\.(ttf|eot|svg|woff|woff2)$/,
use: 'url-loader'
}
]
}
}



// 当我们在控制台直接输入webpack命令执行时,webpack操作:
// 1. webpack发现,我们没有通过命令形式,指定入口和出口
// 2.webpack就会去项目根目录查找'webpack.config.js'配置文件
// 3. 当找到配置文件后, webpack会去解析执行这个配置文件, 当解析执行完配置文件后, 就得到配置文件中导出的配置对象
// 4. 当webpack拿到配置对象后,就拿到了配置对象中指定的入口和出口,然后进行打包构建

package.json

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
{
"name": "webpack",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "webpack-dev-server --open --port 3000--hot"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"jquery": "^3.4.1",
"webpack-cli": "^3.3.6"
},
"devDependencies": {
"css-loader": "^3.1.0",
"html-webpack-plugin": "^3.2.0",
"style-loader": "^0.23.1",
"webpack-dev-server": "^3.7.2"
}
}

webpack babel配置

main.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Person {
static info = {
name: 'zs',
age: 20
}
}
console.log(Person.info);
// 在webpack中默认只能处理一部分ES6新语法,一些更高级的ES6语法或ES7语法,webpack无法处理,这里就需要用第三方loader,来帮助webpack处理这些高级的语法,当第三方loader把高级语法转为低级语法后,会把结果交给webpack去打包到bundle.js
// 通过Babel,可以帮我们将高级语法转为低级语法
// 在webpack中,安装Babel使用指令:
// npm install -D babel-loader @babel/plugin-proposal-class-properties
// npm i -D @babel/core babel-preset-env @babel/preset-react babel-preset-stage-0
// 在webpack配置文件中,在module节点下的rules数组中,添加新的匹配规则
// {test:/\.js$/,use:'babel-loader',exclude:'/node_modules/}
// 注意:在配置babel的loader规则时,必须把node_modules目录通过exclude排除,原因:
// 1. 如果不排除,则babel会把node_modules中所有第三方JS文件都打包编译,这样会非常消耗CPU,同时,打包速度非常慢
// 2. 即使babel将所有node_modules中的JS转换完了,项目也无法正常运行
// 3. 在项目的根目录中,新建一个.babelrc 的Babel配置文件,属于JSON格式,所以在写.BABELRC配置时,必须符合JSON语法规范,不能写注释,字符串必须用双引号
// 在.babelrc写如下配置:
// {
// "presets": ["@babel/react", "@babel/env"], // 语法
// "plugins": ["@babel/plugin-proposal-class-properties"]
// }

.babelrc

1
2
3
4
{
"presets": ["@babel/react", "@babel/env"], // 语法
"plugins": ["@babel/plugin-proposal-class-properties"]
}

webpack.config.js

1
2
3
4
5
6
7
8
9
module: {
rules: [
{
test: /\.js$/,
use: 'babel-loader',
exclude: /node_modules/
}
]
}