Web前端-Vue2.0框架学习

Web前端-Vue框架学习

  • 1. 前端工程化与Webpack
    • 1.1 隔行变色的demo实现
    • 1.2 webpack的基本使用
    • 1.3 webpac插件
      • 1.3.1 webpack-dev-server插件
      • 1.3.2 html-webpack-plugin
    • 1.4 webpack中的loader(加载器)
      • 1.4.1 css-loader
      • 1.4.2 less-loader
      • 1.4.3 url-loader & file-loader (处理url路径相关的文件)
      • 1.4.4 打包处理js文件中的高级语法
    • 1.5 打包发布
    • 1.6 Source Map
  • 2. Vue的基础入门
    • 2.1 vue简介
    • 2.2 vue的基本使用
    • 2.3 vue的调试工具
    • 2.4 vue的指令
      • 2.4.1 内容渲染指令
      • 2.4.2 属性绑定指令
      • 2.4.3 事件绑定
      • 2.4.4 事件/按键 修饰符
      • 2.4.5 双向绑定
      • 2.4.6 条件渲染指令
      • 2.4.7 列表渲染指令
    • 2.5 品牌列表案例
    • 2.6 过滤器
    • 2.7 侦听器
    • 2.8 计算属性
    • 2.9 axios
    • 2.10 vue-cli
    • 2.11 vue组件
      • 2.11.1组件的基本使用
      • 2.11.2 组件之间的父子关系
      • 2.11.3 私有组件和全局组件
      • 2.11.4 组件的props
    • 2.12 生命周期
    • 2.13 组件之间的数据共享
    • 2.14 ref
    • 2.15 动态组件
    • 2.16 插槽
    • 2.17 自定义指令
    • 2.18 eslint
    • 2.19 路由
      • 2.19.1 实现简易的前端路由
      • 2.19.2 vue-router的基础使用
      • 2.19.3 嵌套路由
      • 2.19.4 动态路由
      • 2.19.5 声明式导航 & 编程时导航
      • 2.19.6 导航守卫

1. 前端工程化与Webpack

webpack: 是前端项目工程化的具体解决方案,其主要功能,是提供了友好的前端模块化开发支持以及代码压缩混淆、处理浏览器端JavaScript的兼容性、性能优化等强大的功能。 目前Vue,React等前端项目,基本都是基于webpack工程化开发

1.1 隔行变色的demo实现

在这我们使用一个demo(创建列表隔行变色项目)来说明webpack的基本使用方法:

  1. 新建一个项目空白目录, 并运行npm init -y命令,初始化包管理配置文件package.json
  2. 新建src源代码目录
  3. 新建src-> index.html首页和src->index.js脚本文件
  4. 初始化首页基本结构
  5. 运行npm install jquery -S命令,安装jQuery。之前我们都是直接下载jQuery文件拷贝到项目,这里直接使用npm命令安装。
  6. 通过ES6模块化的方式导入jQuery,实现列表隔行变色效果

注意: -S 是–save的缩写, 是告诉 npm把包安装到dependencies目录下

Web前端-Vue2.0框架学习_第1张图片

上述效果直接运行把如图的错误, 浏览器的兼容性错误。

1.2 webpack的基本使用

webpack的安装: 我们可以在终端运行如下命令,安装webpack相关的两个包:npm install [email protected] [email protected] -D

注意:-D 是 --save-dev的简写 是告诉npm把该包安装在devDependencies目录下, 只在开发模式下使用

  • 在项目根目录中,创建名为webpack.config.js的webpack配置文件,并初始化如下配置
// 使用Node.js中的到处语法,向外到处一个webpack的配置对象
module.exports = {
    // mode用来指定构建模式, 可选值 development 和 production
    // 开发时一定要用development,因为追求的是打包的速度,而不是体积
    // 反过来,发布上线的时候一定能要用production,因为上线追求的是体积小,而不是打包速度
    mode: 'development'
}
  • package.json的scripts节点下,新增dev脚本如下
"scripts": {
	// 自定义脚本: dev(脚本名称) , npm run dev 执行名称为dev的脚本
    "dev" : "webpack"
  },
  • 在终端中运行npm run dev命令,启动webpack进行项目的打包构建

运行npm run dev 报如下错误:
Web前端-Vue2.0框架学习_第2张图片
原因: node.js版本太高, 本人这里是v18.12.1, 我这里解决是把node.js的版本降低到v16.19.1

注意: webpack.config.js配置文件是在npm run dev时,执行dev脚本文件之前,会读取这个配置文件的内容, 然后根据配置文件的内容来打包运行项目

1.3 webpac插件

  • 在webpack4.x和5.x的版本中,有如下默认约定:
    • 默认打包入口文件为scr -> index.js
    • 默认的输出文件路径 dist -> mani.js
    • 注意: 我们也可以在webpack.config.js中修改打包的默认约定

在webpack.config.js配置文件中,通过entry节点指定打包的入口。通过output节点自定打包的出口

const path = require('path')
module.exports = {
    // mode用来指定构建模式, 可选值 development 和 production
    mode: 'development',
    entry: path.join(__dirname, './src/index.js'),// 打包入口文件的路径
    output: {
        path: path.join(__dirname, './dist'), // 输出文件的存放路径
        filename: 'bundle.js' // 输出文件的名称
    }
}

1.3.1 webpack-dev-server插件

webpack插件: 通过安装和配置第三方的插件,可以拓展webpack的能力,从而让webpack用起来更方便。最常用的webpack插件有如下两个:

  • webpack-dev-server : 类似node.js阶段用到的nodemon工具, 每当修改了源代码,webpack会自动进行项目的打包盒构建。安装命令:npm install [email protected] -D
  • 配置webpack-dev-server:
    • 修改package.json -> scripts 中的dev 命令如下"dev": "webpack serve"
    • 在此执行npm run dev
    • 在浏览器中http://localhost:8080/地址,查看自动打包效果
    • 注意:webpack-dev-server会启动一个实时打包的http服务器

当我们配置好package.json文件之后,执行npm run dev命令可能发生如下错误, 产生原因可能是没有安装webpack-cli库或者是webpack-cli库的版本过低导致
Web前端-Vue2.0框架学习_第3张图片

  • 注意(再次执行npm run dev 后):
    • 可以发现页面已经运行在http://localhost:8080/上了
    • 之前输入在dist的文件下的bundle.js 文件, 直接输入在/跟路径下面了,并且是隐藏文件,我们看不到的, 但是我们可以直接使用

Web前端-Vue2.0框架学习_第4张图片

由上面结果可知webpack-dev-server 插件并没有把生成的bundle.js文件放到物理磁盘,而是直接放到内存中

1.3.2 html-webpack-plugin

html-webpack-plugin: webpack中的html插件(类似一个模版引擎插件),可以通过此插件自定制index.html页面的内容
终端执行命令npm install [email protected] -D

在webpack.config.js配置文件中配置该插件:
Web前端-Vue2.0框架学习_第5张图片

当我们执行npm run dev之后,点击http://localhost:8080/之后不会出现,需要我们选择的页面,而是直接展示index.html页面。

  • html-webpack-plugin插件做的事情:
    • 通过HTML插件复制到项目根目录中的index.html页面,也被放到了内存中
    • HTML插件生成的index.html页面自动注入了打包的bundle.js文件

Web前端-Vue2.0框架学习_第6张图片

我们可以在webpack.config.js配置文件中,可以通过devserver节点对webpack-dev-server插件进行更多的配置,示例代码如下:
Web前端-Vue2.0框架学习_第7张图片
注意: 凡事修改了webpack.config.js配置文件,或修改了package.js配置文件,必须重启实时打包的服务器,否则最新的配置文件无法生效

1.4 webpack中的loader(加载器)

在实际开发过程中,webpack默认只能打包处理.js后缀名结尾的模块。其它非.js后缀名结尾的模块,webpack默认处理不了,需要调用loader加载器才可以正常打包,否则会报错!

loader加载器的作用:协助webpack大包处理特定的文件模块。比如:

  • CSS-loader可以处理打包.css相关的文件
  • less-loader可以打包处理.less相关文件
  • babel-loader可以打包处理webpack无法处理的高级JS语法

loader的调用过程:
Web前端-Vue2.0框架学习_第8张图片

1.4.1 css-loader

// 导入样式(在webpack中一切皆模块,都可以ES6导入语法进行导入和使用)
// 如果某个模块中,使用from接收到的成员为undefined,则没有必要进行接收
import '../css/index.css'

当我们在index.js中导入.css文件时报如下错误:
在这里插入图片描述
安装处理.css文件的loader:

	module.exports = {
    module: { //所有第三方文件模块的匹配规则
        rules: [ // 文件后缀名的匹配规则
            {test: /\.css$/, use:['style-loader', 'css-loader']}
        ]
    }
}

其中test表示匹配的文件类型use表示对应要调用的loader
注意: use数组中指定的loader顺序是固定,多个loader的调用顺序是从后往前调用

  1. webpack默认只能打包处理.js结尾的文件,处理不了他后缀的文件
  2. 由于代码中包含了index.css这个文件,因此webpack默认处理不了
  3. 当webpack发现某个文件处理不了时候,会查找webpack.config.js这个配置文件,看module.rule数组中,是否匹配了对应的loader加载器
  4. webpack是把index.css这个文件,先转交给最后一个loader进行处理(先转交给css-loader)
  5. 当css-loader处理完毕之后,会把处理的结果,转交给下一个loader(转交给style-loader)
  6. 当style-loader处理完毕之后,发现没有下一个loader了,于是把处理的结果,转交给webpack
  7. webpack把style-loader处理的结果,合并到/dist/bundle.js中,最终生成打包好的文件

Web前端-Vue2.0框架学习_第9张图片

1.4.2 less-loader

  1. 运行npm install [email protected] [email protected] -D 命令
  2. 在webpack.config.js的module -> rules数组中,添加loader规则如下:
module: { //所有第三方文件模块的匹配规则
        rules: [ // 文件后缀名的匹配规则
            {test: /\.less$/, use:['style-loader', 'css-loader', 'less-loader']},
        ]
    }

1.4.3 url-loader & file-loader (处理url路径相关的文件)

在HTML页面中,例如icon图标,可以转换成base64字符串,如果是直接图片路径下载的话,浏览器需要多发送一个请求。 但是如果我们直接使用base64字符串来加载的话,在你请求网页的时候,就会直接把把图片解析展示出来,而不是请求完网页,在发送一次图片的请求。

如果你的icon图片很多,那么可以省略很多次图片的请求, 这也是网页性能优化的一个点。但是base64字符串方式有个缺点,就是图片转换成base64字符串之后,体积会变大,所以大图片不是适合转换base64字符串。

icon小图片的优化,除了使用base64字符串的方式,还可以使用精灵图。

在这里插入图片描述
我们可以安装一个专门处理URL和文件的插件:

  1. 运行npm install [email protected] [email protected] -D 命令
  2. 在webpack.conig.js的module -> rules数组中,添加loader规则如下:
	module: { //所有第三方文件模块的匹配规则
        rules: [ // 文件后缀名的匹配规则
        // 如果需要调用loader只有一个,则只传递一个字符串也行,如果有多个loader,则必须指定数组
            {test: /\.jpg|png|gif/, use: ['url-loader?limit=2222']},
        ]
    }

其中之后的是loader的参数项

  • limit用来指定图片的大小,单位是字节(byte)
  • 只有<=limit大小的图片,才会被转换成base64格式的图片

在这里插入图片描述

1.4.4 打包处理js文件中的高级语法

webpack只能打包处理一部分高级的JavaScript语法。对于那些webpack无法处理的高级js语法,需要借助与babel-loader进行打包处理。例如webpack无法处理下面JavaScript代码:

$(function(){
    
    $('li:odd').css('background-color','red')
    $('li:even').css('background-color', 'green')
})


// 定义名为info的装饰器
function info(target) {
    // 为目标添加静态属性 info
	// 装饰给谁用, target就只像谁
    target.info = 'Person info'
}

// 为Person类 应用info装饰器
@info 
class Person {}

// 打印Person 的静态属性 info
console.log(Person.info);

Web前端-Vue2.0框架学习_第10张图片
装饰给谁用, target指向谁 这里 targer指向person

运行命令安装对应依赖包:npm install [email protected] @babel/[email protected] @babel/[email protected] -D
在webpack.config.js的module -> rules数组中,添加到loader规则如下:

module: { //所有第三方文件模块的匹配规则
        rules: [ // 文件后缀名的匹配规则
        // 注意必须使用排除项,因为node_modules目录下的第三方包不需要被打包, 因为第三方中的js兼容性,不需要程序员关心
            {test: /\.js$/, use: 'babel-loader', exclude: '/node_modules'},
        ]
    }

在项目的根目录下,创建名为babel.config.js的配置文件,定义Babel的配置项如下:

module.exports = {
    plugins: [
        // 声明babel可用插件, 将来webpack在调用babel-loader的时候,会先加载plugins差价来使用
        ["@babel/plugin-proposal-decorators", { legacy: true }]
    ]
}

详情参考Babel的官网地址:babel-loader的官网地址

1.5 打包发布

配置webpack的打包发布:

  1. package.json文件的scripts节点下,新增build命令如下:
"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "webpack serve", // 开发环境中, 运行dev命令 在开发环境中加入serve指定是把打包的文件放到内存中,并没有放到物理磁盘中
    "build": "webpack --mode production" // 项目发布时,运行build命令 。 不需要serve指定,项目发布中需要把文件打包在物理磁盘上。然后发送到后台发布
  },

--mode 是一个参数项,用来指定webpack的运行模式production代表生产环境,会对打包生成的文件进行代码压缩性能优化
注意: 通过 --mode 指定的参数项, 会覆盖webpack.config.js中的model选项

当我们执行npm run build指令后,生成的dist的结构目录如下:
在这里插入图片描述
我们会发现所有的文件全都在一个文件下,这样看起来会很混乱,我们可以在webpack.config.js配置文件中配置,把文件分类生成到不同的子目录下:
Web前端-Vue2.0框架学习_第11张图片

图片文件楚了上面配置方法,还可以这样配置{test: /\.jpg|png|gif/, use: 'url-loader?limit=2222&outputPath=image'},
配置文件后,再次执行命令npm run build后生成的目录如下:
Web前端-Vue2.0框架学习_第12张图片

为了在每次打包发布时自动清理掉dist目录中的旧文件,可以安装并配置clean-webpack-plugn插件:

  1. 运行npm install [email protected] -D命令
  2. 按需导入插件、得到插件的构造函数之后,创建插件的实例对象
// 按需导入,得到插件的构造函数之后,创建插件的实例对象
// 这种导入方式是结构赋值,得到的结果相当于解析了一层
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
// 创建
const cleanPugin = new CleanWebpackPlugin()

module.exports = {
    // 把创建的cleanPugin 插件实例对象, 挂载plugin结点中
    plugins: [cleanPugin],
    }

1.6 Source Map

什么是Source Map?

Source Map就是一个信息文件, 里面存储着位置的信息。也就是说, Source Map文件中存储着压缩混淆后的代码,所对应的转换前的位置
有了它,出错的时候,除错工具将直接显示原始代码, 而不是转换后的代码,能够极大的方便后期的调试。

默认Source Map的问题: 开发环境下默认生成的Source Map, 记录的是生成后的代码的位置。会导致运行时报错的行数源代码的行数不一致的问题。示意图如下:
Web前端-Vue2.0框架学习_第13张图片

开发环境下,推荐在webpack.config.js中添加如下配置,即可保证运行时报错行数源代码的行数保持一致:

module.exports = {
    // eval-source-map 仅限在“开发模式”下使用,不建议在”生产模式“下使用
    devtool:'eval-source-map',
    }

webpack生产环境下的Source Map: 在生产环境下,如果省略了devtool选项,则最终生成的文件中不包含Source Map。这能欧防止原始代码通过Source Map的形式暴露给别有所图之人:

Web前端-Vue2.0框架学习_第14张图片

注意: 在实际发布的时候,建议大家把devtool的值设置为nosources-source-map或直接关闭Source Map

在生产环境下,,如果想在定位报错行数的同时,展示具体报错的源码。此时可以将devtool的值设置为source-map。实际效果如图所示:
Web前端-Vue2.0框架学习_第15张图片

  • Source Map的最佳实践
    • 开发环境: 建议把devtool的值设置为eval-source-map,好处:可以精准定位到具体的错误行
    • 生产环境下:建议关闭Source Map或将devtool的值设置为nosources-source-map , 好处:防止源码泄漏,提高网站的安全性

在实际开发中需要自己配置webpack吗?
不需要
实际开发中会使用命令行工具(俗称CLI)一键生成带有webpack的项目,所有的webpack配置项都是现成的,我们只需要知道哦啊webpack中的基本概念即可

最后我们在代码中可以指定@符号表示src这一层目录, 这样我们在导入文件的时候就不用使用../../等这样的符号, 直接从src这一层目录往下找文件, 不是从里往外找:


module.exports = 
    resolve: {
        alias: {
            // 告诉webpakck, 程序员写的代码中, @符号表示src这一层目录
            '@':path.join(__dirname, './src/')
        }
    }
}

2. Vue的基础入门

2.1 vue简介

vue是一套用于构建用户界面的前端框架。vue框架的特性,主要体现在如下两个方面:

  1. 数据驱动视图
  2. 双向数据绑定

数据驱动视图:

在使用vue的页面中,vue会监听数据的变化,从而自动重新渲染页面的结构。示意图如下:

Web前端-Vue2.0框架学习_第16张图片
好处: 当页面数据发生变化时,页面会自动重新渲染
注意: 数据驱动视图是单向的数据绑定

双向数据绑定: 在填写表单时,双向数据绑定可以辅助开发者不操作DOM的前提下自动把用户填写的内容同步到数据源中

Web前端-Vue2.0框架学习_第17张图片

好处: 开发者不需要手动操作DOM元素,来获取表单元素最新的值

MVVM 是vue实现数据驱动视图双向数据绑定的核心原理。MVVM指的是Model、View和ViewModel,它把每个HTML页面都拆分成这三个部分。

在MVVM的概念中:

  • Model表示当前页面渲染时所依赖的数据源
  • View 表示当前页面所渲染的DOM结构
  • ViewModel表示vue的实例,它是MVVM的核心

Web前端-Vue2.0框架学习_第18张图片

MVVM的工作原理: ViewModel作为MVVM的核心,是它把当前页面的数据源(Model)和页面的结构(View)连接在一起。

Web前端-Vue2.0框架学习_第19张图片

数据源发生变化时,会被ViewModel监听到,VM会根据最新的数据源自动更新页面的结构
表单元素的值发生变化时,也会被VM监听到,VM会把变化过后最新的值自动同步到Model数据源中

2.2 vue的基本使用

  • Vue的基本使用步骤:
    • 导入vue.js的script文件
    • 在页面中声明一个将要被vue所控制的DOM区域
    • 创建vm实例对象(vue的实例对象)

Web前端-Vue2.0框架学习_第20张图片

2.3 vue的调试工具

安装vue-devtoools的调试工具:vue官方提供的vue-devtools调试工具,能够方便开始者对vue项目进行调试与开发。

关于vue-devtools的安装过程这里不过多描述

配置Chrome浏览器中的vue-devtools:

点击Chrome浏览器上角的...按钮,选择更多工具 -> 扩展程序 -> Vue.js devtools详细信息,并勾选如下两个选项:

Web前端-Vue2.0框架学习_第21张图片

2.4 vue的指令

指令(Directives): 是vue为开发者提供的模版语法,用于辅助开发者渲染页面的基本结构
vue中的指令按照不同的用途可以分为如下六大类:

  1. 内容渲染指令
  2. 属性绑定指令
  3. 事件绑定指令
  4. 双向绑定指令
  5. 条件渲染指令
  6. 列表渲染指令

2.4.1 内容渲染指令

内容渲染指令用来辅助开发者渲染DOM元素的文本内容。常用的内容渲染指令有如下3个:

  • v-text :把对应数据中的值渲染到标签中。注意:渲染值会覆盖标签中的默认值
  • {{}} :只是内容的占位符,专门用来解决v-text会覆盖默认文本内容的问题,这种{{}}语法的专业名称是插值表达式(Mustache)
  • v-html : v-text插值表达式只能渲染纯文本内容。如果要把包含HTML标签字符串渲染为页面的HTML元素,则需要用到v-html这个指令

Web前端-Vue2.0框架学习_第22张图片

2.4.2 属性绑定指令

属性绑定指令:如果需要元素的属性动态绑定属性值,则需要用到v-bind属性绑定指令。示例代码如下:

Web前端-Vue2.0框架学习_第23张图片

注意: 插值表达式只能在元素中的内容节点中,不能用在元素的属性节点中

  • 在Vue中,可以使用v:bind:指令,为元素的属性动态绑定值,也可以简写为英文的:
  • 在使用v-bind:属性绑定期间,如果绑定内容需要进行动态拼接,则字符串的外面应该包括单引号,例如:
    Web前端-Vue2.0框架学习_第24张图片

    2.4.3 事件绑定

    vue提供了v-on事件绑定指令,用来辅助程序员为DOM元素绑定事件监听。

    Web前端-Vue2.0框架学习_第25张图片
    注意: v-on:click 可以简写为 @click(推荐使用)

    方法传参:绑定事件的同时可以在()内传参

    • 如果没有传递参数, 在绑定事件方法,有默认的事件对象event作为参数
    • 如果传递了参数, 传递的参数会覆盖默认的事件对象event,如果需要使用默认事件对象event,那需要在多传递一个参数,使用$event固定写法表示事件对象

    Web前端-Vue2.0框架学习_第26张图片

    注意: 原生DOM对象有onClick、oninput、onkeyup等原生事件,替换为vue的事件绑定形式后,分别为v-on:click、v-on:input、v-on:keyup

    2.4.4 事件/按键 修饰符

    事件修饰符:在事件处理函数中调用event.preventDefault() (组织默认点击跳转行为)event.stopPropagation() (阻止冒泡)是非常常见的需求。因此vue提供了事件修饰符的概念,来辅助程序员更方便的对事件的触发行为进行控制。常用的5个修饰符如下:
    Web前端-Vue2.0框架学习_第27张图片
    Web前端-Vue2.0框架学习_第28张图片

    注意:@click.prevent;既为a标签绑定了click事件,同时取消了a标签的默认跳转行为

    按键修饰符: 在监听键盘事件时,我们经常需要判断详细的按键。此时,可以为键盘相关的事件添加按键修饰符

    Web前端-Vue2.0框架学习_第29张图片

    2.4.5 双向绑定

    vue提供了v-model双向数据绑定指令,用来辅助开发者不操作DOM的前提下,快去获取表单的数据

    Web前端-Vue2.0框架学习_第30张图片

    • v-model: 双向绑定,能和表单元素、下拉菜单元素组合使用, 但是和只展示的标签组合是没有意义的
    • v-bind:单项绑定,当数据发生变化时,会通知页面;但是在页面修改数据,是不会同步修改数据源的

    为了方便对用户输入的内容进行处理,vue位v-model指令提供了3个修饰符,分别是:

    Web前端-Vue2.0框架学习_第31张图片

    用法如下:
    Web前端-Vue2.0框架学习_第32张图片

    2.4.6 条件渲染指令

    条件渲染指令用来辅助开发者按需控制DOM的显示和隐藏。条件渲染指令有如下两个分别是:

    • v-if
    • v-show

    Web前端-Vue2.0框架学习_第33张图片

    • v-show的原理是:动态为元素添加或移除display:none样式,来实现元素的显示和隐藏,如果要频繁的切换元素的显示状态,用v-show性能会更好
    • v-if的原理是:每次动态创建或移除元素,实现元素的显示和隐藏,如果刚进入页面的时候,某些元素默认不需要被展示,而后期这个元素很可能也不需要被展示出来,此时v-if性能更好

    v-if指令还可以与v-else-ifv-else指令使用,相当于if {} else if{} esle {}, v-else、v-else-if必须与v-if组合一起使用,不能单独使用,单独使用时不被识别

    Web前端-Vue2.0框架学习_第34张图片

    2.4.7 列表渲染指令

    vue提供了v-for列表渲染指令,用来辅助开发者基于一个数组来循环渲染一个列表结构。v-for指令需要使用item in items形式的特殊语法,其中:

    • items 是待循环的数组
    • item 是被循环的每一项

    Web前端-Vue2.0框架学习_第35张图片

    v-for指令还支持一个可选的第二个参数,即当前项的索引,语法格式:(item, index)in list:
    Web前端-Vue2.0框架学习_第36张图片

    注意: v-for指令中的item项和index索引都是形参,可以更具需要进行重命名。 例如(user, i)in list

    官方建议:只要使用到了v-for指令,那么一定要绑定一个:key属性, 而且这里建议尽量把id作为key的值,并且官方对key的值是由要求的:字符串或数字类型。 这里需要注意的是key的值是千万不能重复的,否则会终端报错 Dulicate keys detected

    • key的注意事项:
      • key的值只能是字符串数字类型
      • key的值必须具备唯一性(即:key的值不能重复,唯一性指的是key和数据具有唯一绑定性)
      • 建议把数据项id属性的值作为key的值(因为id属性的值具有唯一性)
      • 使用index的值当做key的值没有任何意义(因为index的值不具有唯一性)
      • 建议使用v-for指令时一定要指定key的值(既能提升性能、又防止列表状态紊乱)

    2.5 品牌列表案例

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>品牌列表案例</title>
      <link rel="stylesheet" href="../../lib/bootstrap.css">
      <link rel="stylesheet" href="./css/brandlist.css">
      <script src="../../lib/vue-2.6.12.js"></script>
    </head>
    
    <body>
    
      <div id="app">
        <!-- 卡片区域 -->
        <div class="card">
          <div class="card-header">
            添加品牌
          </div>
          <div class="card-body">
            <!-- 添加品牌的表单区域 -->
            <form @submit.prevent="add">
              <div class="form-row align-items-center">
                <div class="col-auto">
                  <div class="input-group mb-2">
                    <div class="input-group-prepend">
                      <div class="input-group-text">品牌名称</div>
                    </div>
                    <input type="text" class="form-control" placeholder="请输入品牌名称" v-model.trim="name">
                  </div>
                </div>
                <div class="col-auto">
                  <button type="submit" class="btn btn-primary mb-2">添加</button>
                </div>
              </div>
            </form>
          </div>
        </div>
    
        <!-- 表格区域 -->
        <table class="table table-bordered table-hover table-striped">
          <thead>
            <tr>
              <th scope="col">#</th>
              <th scope="col">品牌名称</th>
              <th scope="col">状态</th>
              <th scope="col">创建时间</th>
              <th scope="col">操作</th>
            </tr>
          </thead>
          <tbody>
            <tr v-for="item in list" :key="item.id">
              <td>{{ item.id }}</td>
              <td>{{ item.name }}</td>
              <td>
                <div class="custom-control custom-switch">
                  <input type="checkbox" class="custom-control-input" :id="'customSwitch' + item.id" v-model="item.status">
                  <label class="custom-control-label" :for="'customSwitch' + item.id">{{ item.status ? '已启用' : '已禁用' }}</label>
                </div>
              </td>
              <td>{{ item.time }}</td>
              <td>
                <a href="javascript:;" @click="remove(item.id)">删除</a>
              </td>
            </tr>
          </tbody>
        </table>
      </div>
    
      <script>
        const vm = new Vue({
          el:'#app',
          data: {
            name:'',
            list:[
              {id: 1, name: '宝马', status: false, time: new Date()},
              {id: 2, name: '奔驰', status: true, time: new Date()},
              {id: 3, name: '奥迪', status: false, time: new Date()}
            ]
          },
          methods: {
            remove(id) {
              // 根据id来删除数据
              // filter :  把不符合条件的元素过滤掉
              this.list = this.list.filter( item => item.id != id)
            },
            add() {
              if (this.name === '') return alert('请输入品牌名称')
    
              // 如果不为空则 执行添加逻辑
              const obj = {
                id: this.list.length + 1,
                name: this.name,
                status: true,
                time: new Date()
              }
    
              this.list.push(obj)
    
              this.name = ''
    
    
            }
          }
        })
      </script>
    </body>
    
    </html>
    

    Web前端-Vue2.0框架学习_第37张图片

    2.6 过滤器

    过滤器(Filters)是vue为开发者提供的功能,常用与文本的格式化。过滤器可以用在两个地方:插值表达式、v-bind属性绑定。过滤器应该被提那家在JavaScript表达式的尾部,由管道符进行调用.但是在Vue3.0中已经不支持过滤器了, 官方建议使用计算属性和方法来代替

    Web前端-Vue2.0框架学习_第38张图片

    • 过滤器的注意点:
      • 要定义在filters节点下,本质上是一个函数
      • 在过滤器函数中,一定要有return值
      • 在过滤器的形参中,就可以获取到“管道符”前面待处理的那个值

    私有过滤器和全局过滤器: 在filters节点下定义的过滤器,成为私有过滤器,因为它只能在vm实例所控制的el区域内使用。如果希望在多个vue实力之间共享过滤器,则可以按照如下的格式定义全局过滤器:

     // 全局过滤器, 独立于每个vm实例之外
            // Vue.filter()方法接受两个参数: 第一个参数: 全局过滤器的名称  第二个参数:全局过滤器的处理函数
            Vue.filter('capitalize', (str) => {
                return str.charAt(0).toUpperCase() + str.slice(1) + '~~~'
            })
    
    

    注意:如果全局过滤器函数和私有过滤器名字一致,此时按照就近原则,调用的是私有过滤器

    我们也可以连续调用过个过滤器:
    Web前端-Vue2.0框架学习_第39张图片

    过滤器的本质JavaScript函数,因此可以接受参数,格式如下:

    Web前端-Vue2.0框架学习_第40张图片

    2.7 侦听器

    watch侦听器允许开发者见识数据的变化,从而针对数据的变化做特定的操作
    Web前端-Vue2.0框架学习_第41张图片

    immediate: 默认值false,其作用是控制侦听器是否自动触发一次
    有时候我们会有需求,在界面初始化时,就自动触发触发一次监听器,监听属性的变化, 这时候我们可以做如下实现:

    Web前端-Vue2.0框架学习_第42张图片

    deep: 开启深度监听,只要对象中任何一个属性变化,都会触发“对象的监听器”, 有时候我们监听的是一个对象, 如果想要对象中的每个属性的变化都会引起对象的变化,那么使用deep关键字。但是只是想要监听对象中某一个属性的变化, 可以之间监听子属性

     const vm = new Vue({
                el: '#app',
                data: {
                    info:{
                        username: 'zs',
                        age: 20
                    }
                },
                
                watch: {
                    // 定义对象格式的侦听器
                    info: {
                        handler(newVal) {
                            console.log('触发侦听器-------',newVal);
                        },
                        // 开启深度监听,只要对象中的任何一个属性变化了,都会触发 对象的侦听器
                        deep: true
                    },
    
                    // 上述监听,是只要对象中的属性发生变化,都会触发监听器, 
                    // 但是有时候我们只需要监听某个属性的变化,所以我们可以监听对象单个舒心改变
                    // 如果要侦听的是对象的子属性的变化,则必须包裹一层单引号
                    'info.username'(newVal) {
                        console.log(newVal);
                    }
                }
            })
    

    侦听器的格式:

    • 方法格式的侦听器:
      • 缺点1: 无法在刚进入页面的时候,自动触发
      • 缺点2: 如果侦听的是一个对象,如果对象中的属性发生了变化, 不会触发侦听器!!!
    • 对象格式的侦听器:
      • 好处1:可以通过immediate选项,让侦听器自动触发!!!
      • 好处2: 可以通过deep选项,让侦听器深度监听对象中的每个属性变化!!!

    2.8 计算属性

    计算属性指的是通过一系列运算之后,最终得到的一个值。这个动态计算出来的属性值可以被模版结构或methods方法使用。

    Web前端-Vue2.0框架学习_第43张图片

    • 计算属性:
      • 特点: 定义的时候,要被定义成方法;在使用计算属性的时候,当普通的属性使用即可
      • 好处: 实现了代码的复用;只要计算属性中依赖的数据源变化了,则计算属性会自动重新求值

    2.9 axios

    axios:是前端最火的、专注于数据请求的库。

    相关文当网站:http://www.axios-js.com/zh-cn/docs/、https://www.axios-http.cn

    axios的基础语法:
    Web前端-Vue2.0框架学习_第44张图片
    返回的数据:
    Web前端-Vue2.0框架学习_第45张图片

    发起 GET 请求:

    axios({
      // 请求方式
      method: 'GET',
      // 请求的地址
      url: 'http://www.liulongbin.top:3006/api/getbooks',
      // URL 中的查询参数
      params: {
        id: 1
      }
    }).then(function (result) {
      console.log(result)
    })
    

    发起 POST 请求:

    document.querySelector('#btnPost').addEventListener('click', async function () {
      // 如果调用某个方法的返回值是 Promise 实例,则前面可以添加 await!
      // await 只能用在被 async “修饰”的方法中
      const { data: res } = await axios({
        method: 'POST', 
        url: 'http://www.liulongbin.top:3006/api/post',
        data: {
          name: 'zs',
          age: 20
        }
      })
    
      console.log(res)
    })
    

    注意:关于axios这里不做过多介绍, 更多用法请参考官方文档

    每次使用axios时,在临时导入, 这样如果多个地方使用,那每个地方都使用,非常麻烦, 我们可以把axios挂在到Vue上。我们知道每一个组件都是一个Vue的实例

    Web前端-Vue2.0框架学习_第46张图片

    Web前端-Vue2.0框架学习_第47张图片
    那今后要在那个组件调用axios发起请求, 直接使用this.$http.xxx发起请求,但是这样做不利于API接口的复用。

    2.10 vue-cli

    什么是vue-cli?

    vue-cli是Vue.js开发的标准工具。它简化了程序员基于webpack创建工程化的Vue项目的过程。中文官方地址:https://cli.vuejs.org/zh/

    Vue-cli的安装和使用

    vue-cli是npm上的一个全局包使用npm install命令,即可方便的把它安装到自己的电脑上:npm install -g @vue/cli ,基于vue-cli快速生成工程化的Vue项目:vue create 项目的名称

    执行vue create xxx 的项目创建过程

    1. 选择配置: 这里我们选择手动选择配置
      Web前端-Vue2.0框架学习_第48张图片

    2. 看自己项目的需求,选择相应的配置:
      Web前端-Vue2.0框架学习_第49张图片

    3. 选择Vue的版本: 这里选择的是Vue2.0
      Web前端-Vue2.0框架学习_第50张图片

    4. 选择CSS的编写方式:这里选择less方式:
      Web前端-Vue2.0框架学习_第51张图片

    5. 选择把babel、eslint等插件的配置项,放到独立的配置文件中还是放到package.json配置文件中
      Web前端-Vue2.0框架学习_第52张图片

    6. 是否把当前选择的配置保存起来, 方便下次创建新的项目时直接使用: 这里选择 保存
      Web前端-Vue2.0框架学习_第53张图片

    创建完之后,项目的结构目录如下:

    Web前端-Vue2.0框架学习_第54张图片

    • vue中src目录的构成:

      • assets文件件: 存放项目中用到的静态资源,例如:css样式表、图片资源
      • components文件夹:程序员封装的、可复用性的组件,都要放到components目录下
      • main.js是项目的入口文件。整个项目的运行,要先执行main.js
      • App.vue是项目的根组件
    • 在工程化的项目中,vue要做的事情很单纯: 通过main.jsApp.vue渲染到index.html的指定区域中。

      • App.vue 用来编写待渲染的模版结构
      • index.html中需要预留一个el区域
      • main.js 把App.vue渲染到了index.html所预留的区域中
    // 创建vue的实例对象
    new Vue({
      // 把render 函数指定的组件,渲染到HTML页面中 (直接渲染到#app区域,直接替换#app区域)
      render: h => h(App),
    }).$mount('#app')
    // vue 中$mount()方法,作用和 el 属性完全一样
    
    

    2.11 vue组件

    什么是组件化开发?

    组件化开发指的是:根据封装的思想,把页面上可重用的UI结构封装为组件,从而方便项目的开发和维护。

    vue是一个支持组件化开发的前端框架。vue中规定:组件的后缀名.vue。之前接触到的App.vue文件本质上就是一个vue组件。

    每个.vue组件都由三部分构成,分别是:

    1. template : 组件的模版结构
    2. script:组件的JavaScript行为
    3. style:组件的样式

    其中每个组件中必须包含template模版结构,而script行为style样式可选的组成部分

    2.11.1组件的基本使用

    vue规定:每个组件对应的模版结构,需要定义到