****************************************************************************************************************************************************************************
1、课程概述 【1】前置储备:HTML+CSS+JS、WebAPI、Ajax、Node.js 【2】1天:前端工程化+Webpack。2天:vue的使用步骤、指令、调试工具。3天:过滤器、监听器、计算属性、axios、vue-cli。 4天:组件与生命周期。5天:ref+购物车案例。6天:vue组件的高级用法、动态组件、插槽的使用。7天:路由。8天:黑马头条.
****************************************************************************************************************************************************************************
2、前端工程化 【1】模块化、组件化、规范化、自动化。 【2】前端工程化:在企业级的前端项目开发中,把前端相关的技术规划化、标准化。 【3】主流的工程化方案:webpack 网址:https://www.webpackjs.com
****************************************************************************************************************************************************************************
3、webpack的基本使用 【1】它提供了友好的前端开发支持,以及代码混淆、处理浏览器js的兼容性、性能优化等强大功能。 【2】程序员放心的写高级代码,webpack负责转换成低版本浏览器也能跑,就完事了。
****************************************************************************************************************************************************************************
4、webpack正式使用 【1】列表隔行变色需求的实现。 npm init -y ****************************************** 新建src文件+index.html+index.js ****************************************** npm install jquery -S (-S 就是记录参数到package.json里去 就是--save的缩写,开发和上线都需要的包) ****************************************** 通过es6导入jQuery 【2】Uncaught SyntaxError: Cannot use import statement outside a module 语法错误 【3】报错的解决 npm install webpack@5.42.1 webpack-cli@4.7.2 -D (-D是说明记录到package.json,但是它是记录到devDependencies节点,只在开发阶段会用到的包, 上线不需要--save-dev的简写) ******************************************安装后配置 在项目跟目录下,创建webpack.config.js文件。并初始化基本配置: module.exports = { mode: 'development' // 用来指定构建模式 } ******************************************在package.json的scripts节点,新增dev脚本 "scripts":{ "dev": "webpack" // 通过npm run dev运行的就是这个脚本webpack } ******************************************终端运行命令 npm run dev ******************************************然后在dist下面生成了main.js文件,这个文件就是对index.js的兼容性升级,引入后 最后访问index.html就能成功使用了!!!!!!!!!!!!! 【4】大小压缩 // 使用nodejs导出一个webpack对象 module.exports = { mode: 'production' // production(小,慢,上线的时候用) development(大,快,开发的时候用) } ******************************************* asset main.js 88.5 KiB 大小变小了4倍多。
****************************************************************************************************************************************************************************
8、webpack.config.js执行过程 【1】在执行npm run dev之前就会被读取,然后根据配置运行webpack 【2】默认约定是打包src下面的index.js,输出是dist下面的main.js 【3】通过个性化配置可以改变输出路径。entry指定打包的路径,output可以指定打包输出路径。 【4】每次修改index.js 都需要重新打包webpack,再访问才能生效... 【5】通过插件来解决,使用webpack-dev-server npm i webpack-cli -D(注意版本之间的兼容性) npm install webpack-dev-server@3.11.2 -D ******************************************修改脚本命令内容 "scripts":{ "dev": "webpack serve" } ******************************************执行命令 npm run dev ******************************************访问发现可以访问,但是修改代码颜色没有变化 webpack output is served from / 根据这个提示改配置。 <!--这里使用的是内存里的main.js--> <script src="/main.js"></script> ******************************************就解决了修改代码,颜色不变化的问题 牛批呀!!!!!!!!!!!!!
****************************************************************************************************************************************************************************
11、安装配置html-webpack 【1】优化不点击src就能看到index的页面 【2】安装html-webpack-plugin npm i html-webpack-plugin@5.3.2 -D 【3】配置 // 使用nodejs导出一个webpack对象 // 1.导入html-webpack-plugin const HtmlPlugin = require("html-webpack-plugin"); // 2.new构造函数,创建实例对象 const htmlPlugin = new HtmlPlugin({ template: './src/index.html', // 被复制文件路径 filename: './index.html' // 复制的文件路径 }); module.exports = { mode: 'development', // production development // 插件的数组 webpack在运行时会加载并调用这些插件 plugins: [htmlPlugin] } 【4】重新运行,npm run dev 访问localhost:8080就会访问复制出来的index.html 它是存在内存中的。 【5】而且html-webpack-plugin会自动加载内存中的main.js,不用写加载代码也可以。 【6】自动打开浏览器访问,并指定端口号 module.exports = { mode: 'development', // production development // 插件的数组 webpack在运行时会加载并调用这些插件 plugins: [htmlPlugin], devServer: { open: true, // 自动打开浏览器 port: 80 } }
****************************************************************************************************************************************************************************
14、webpack里的loader 【1】如果不是.js文件,需要loader加载器进行正常的打包。 【2】比如不要li前面的点,需要引入css文件,如果用loader来处理? npm i style-loader -D ****************************************安装处理器 npm i css-loader -D ****************************************执行 npm run dev 【3】这样就成功实现了加载css文件的loader处理。 【4】会先转交给后一个loader,然后再给style-loader,再把处理结果转给webpack,webpack把处理结果合并到main.js module.exports = { mode: 'development', // production development // 插件的数组 webpack在运行时会加载并调用这些插件 plugins: [htmlPlugin], devServer: { open: true, // 自动打开浏览器 port: 80 }, module: { rules: [ // 定义了不同模块对应的loader {test: /.css$/, use: ['style-loader', 'css-loader']} ] } } 【5】打包less功能 npm i less-loader less -D ****************************************安装处理器 module.exports = { mode: 'development', // production development // 插件的数组 webpack在运行时会加载并调用这些插件 plugins: [htmlPlugin], devServer: { open: true, // 自动打开浏览器 port: 80 }, module: { rules: [ // 定义了不同模块对应的loader {test: /.less$/, use: ['style-loader', 'css-loader', 'less-loader']}, {test: /.css$/, use: ['style-loader', 'css-loader']} ] } }
****************************************************************************************************************************************************************************
17、webpack打包图片 【1】图片转成base64后展示,但是体积转换后可能变大点。所以大图片就不建议转了。 【2】用webpack打包图片的路径。 npm i url-loader file-loader -D **********************************************index.js import "./css/index.less" // 导入样式 在webpack中一切皆模块,都可以通过es6进行导入和使用 import "./css/index.css" // 就需要合适的loader来处理 // 1.导入图片 import logo from "./res/1.jpg" console.log(logo); // 2. 给img标签的src动态赋值 $(".box").attr("src", logo) // 使用es6导入语法 导入jquery import $ from 'jquery' // 定义jquery的入口函数 $(function () { // 实现行变色效果 $('li:odd').css('background-color', 'red'); $('li:even').css('background-color', 'yellow'); }) ************************************************webpack.config.js // 使用nodejs导出一个webpack对象 // 1.导入html-webpack-plugin const HtmlPlugin = require("html-webpack-plugin"); // 2.new构造函数,创建实例对象 const htmlPlugin = new HtmlPlugin({ template: './src/index.html', // 被复制文件路径 filename: './index.html' // 复制的文件路径 }); module.exports = { mode: 'development', // production development // 插件的数组 webpack在运行时会加载并调用这些插件 plugins: [htmlPlugin], devServer: { open: true, // 自动打开浏览器 port: 80 }, module: { rules: [ // 定义了不同模块对应的loader {test: /.less$/, use: ['style-loader', 'css-loader', 'less-loader']}, {test: /.css$/, use: ['style-loader', 'css-loader']}, {test: /.jpg|png|gif$/, use: 'url-loader?limit=22229'} ] } }
****************************************************************************************************************************************************************************
20、是否需要接收 【1】如果接收到的对象为undefined,这import .. from 的from就不用接收了,直接import就可以了。 【2】?limit=22229 文件的大小上限,不能大于22229字节,就是2.2M左右。
****************************************************************************************************************************************************************************
22、webpack如果打包高级语法 【1】就是如何打包一些架构的高级代码语法? npm i babel-loader @babel/core @babel/plugin-proposal-decorators -D *************************************************************************************安装装饰器 {test: /.js$/, use: 'babel-loader', exclude: /node_modules/} // 一定要排除node_modules,因为第三方包不需要你管 【2】在项目根目录下,创建名字为babel.config.js配置文件,定义配置如下: module.exports={ plugins:[['@babel/plugin-proposal-decorators',{legacy:true}]] }
****************************************************************************************************************************************************************************
23、发布上线 【1】加一个命令如下: "scripts": { "dev": "webpack serve", "build": "webpack --mode production" // 这里使用production发布,覆盖serve里那个development }, ***************************************************************** dist下就会生成对应的打包发布后的文件。
****************************************************************************************************************************************************************************
24、发布的资源分类存储 【1】js文件放到js文件夹下面,完整配置如下 // 使用nodejs导出一个webpack对象 const path = require("path"); // 首先我们在webpack.config.js中引入path模块 // 1.导入html-webpack-plugin const HtmlPlugin = require("html-webpack-plugin"); // 2.new构造函数,创建实例对象 const htmlPlugin = new HtmlPlugin({ template: './src/index.html', // 被复制文件路径 filename: './index.html' // 复制的文件路径 }); module.exports = { mode: 'development', // production development // 插件的数组 webpack在运行时会加载并调用这些插件 output: { path: path.join(__dirname, 'dist'), filename: "js/main.js" }, plugins: [htmlPlugin], devServer: { open: true, // 自动打开浏览器 port: 80 }, module: { rules: [ // 定义了不同模块对应的loader {test: /.less$/, use: ['style-loader', 'css-loader', 'less-loader']}, {test: /.css$/, use: ['style-loader', 'css-loader']}, {test: /.jpg|png|gif$/, use: 'url-loader?limit=22229&outputPath=images'}, // 处理高级语法 // {test: /.js$/, use: 'babel-loader', exclude: /node_modules/} ] } } 【2】图片放到images文件下面 ********************************************************* module: { rules: [ // 定义了不同模块对应的loader {test: /.less$/, use: ['style-loader', 'css-loader', 'less-loader']}, {test: /.css$/, use: ['style-loader', 'css-loader']}, {test: /.jpg|png|gif$/, use: 'url-loader?limit=22229&outputPath=images'}, // 处理高级语法 // {test: /.js$/, use: 'babel-loader', exclude: /node_modules/} ] }
****************************************************************************************************************************************************************************
25、每次打包发布自动删除原有文件 【1】安装插件 npm i clean-webpack-plugin -D 【2】新的配置 // 使用nodejs导出一个webpack对象 const path = require("path"); // 首先我们在webpack.config.js中引入path模块 // 1.导入html-webpack-plugin const HtmlPlugin = require("html-webpack-plugin"); // 2.new构造函数,创建实例对象 const htmlPlugin = new HtmlPlugin({ template: './src/index.html', // 被复制文件路径 filename: './index.html' // 复制的文件路径 }); const {CleanWebpackPlugin} = require("clean-webpack-plugin"); //!!!!!!!!!!!!!!!!!!!!!!!!! 解构赋值 module.exports = { mode: 'development', // production development // 插件的数组 webpack在运行时会加载并调用这些插件 output: { path: path.join(__dirname, 'dist'), filename: "js/main.js" }, plugins: [htmlPlugin, new CleanWebpackPlugin()], //!!!!!!!!!!!!!!!!!!!!!!!!! devServer: { open: true, // 自动打开浏览器 port: 80 }, module: { rules: [ // 定义了不同模块对应的loader {test: /.less$/, use: ['style-loader', 'css-loader', 'less-loader']}, {test: /.css$/, use: ['style-loader', 'css-loader']}, {test: /.jpg|png|gif$/, use: 'url-loader?limit=22229&outputPath=images'}, // 处理高级语法 // {test: /.js$/, use: 'babel-loader', exclude: /node_modules/} ] } }
****************************************************************************************************************************************************************************
27、Source Map 【1】记录原来的行号,方便程序员快速定位报错的行。 // 使用nodejs导出一个webpack对象 const path = require("path"); // 首先我们在webpack.config.js中引入path模块 // 1.导入html-webpack-plugin const HtmlPlugin = require("html-webpack-plugin"); // 2.new构造函数,创建实例对象 const htmlPlugin = new HtmlPlugin({ template: './src/index.html', // 被复制文件路径 filename: './index.html' // 复制的文件路径 }); const {CleanWebpackPlugin} = require("clean-webpack-plugin"); module.exports = { mode: 'development', // production development devtool: 'eval-source-map', // 看这里!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // 插件的数组 webpack在运行时会加载并调用这些插件 output: { path: path.join(__dirname, 'dist'), filename: "js/main.js" }, plugins: [htmlPlugin, new CleanWebpackPlugin()], devServer: { open: true, // 自动打开浏览器 port: 80 }, module: { rules: [ // 定义了不同模块对应的loader {test: /.less$/, use: ['style-loader', 'css-loader', 'less-loader']}, {test: /.css$/, use: ['style-loader', 'css-loader']}, {test: /.jpg|png|gif$/, use: 'url-loader?limit=22229&outputPath=images'}, // 处理高级语法 // {test: /.js$/, use: 'babel-loader', exclude: /node_modules/} ] } } 【2】生产环境需要注释掉devtool选项,这样才更安全!!!!!!!!!!!!!! 【3】或者生产环境只暴露行号,nosources-source-map使用这个值。这个非常好!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // 使用nodejs导出一个webpack对象 const path = require("path"); // 首先我们在webpack.config.js中引入path模块 // 1.导入html-webpack-plugin const HtmlPlugin = require("html-webpack-plugin"); // 2.new构造函数,创建实例对象 const htmlPlugin = new HtmlPlugin({ template: './src/index.html', // 被复制文件路径 filename: './index.html' // 复制的文件路径 }); const {CleanWebpackPlugin} = require("clean-webpack-plugin"); module.exports = { mode: 'development', // production development devtool: 'nosources-source-map', // 插件的数组 webpack在运行时会加载并调用这些插件 output: { path: path.join(__dirname, 'dist'), filename: "js/main.js" }, plugins: [htmlPlugin, new CleanWebpackPlugin()], devServer: { open: true, // 自动打开浏览器 port: 80 }, module: { rules: [ // 定义了不同模块对应的loader {test: /.less$/, use: ['style-loader', 'css-loader', 'less-loader']}, {test: /.css$/, use: ['style-loader', 'css-loader']}, {test: /.jpg|png|gif$/, use: 'url-loader?limit=22229&outputPath=images'}, // 处理高级语法 // {test: /.js$/, use: 'babel-loader', exclude: /node_modules/} ] } }
****************************************************************************************************************************************************************************
30、实际开发中需要自己配置webpack吗? 【1】不需要,都是默认配置好的... 【2】../../这种层级太多不方便理解,建议使用@表示src源代码目录,从外往里找,不要使用../从里往外找 // 使用nodejs导出一个webpack对象 const path = require("path"); // 首先我们在webpack.config.js中引入path模块 // 1.导入html-webpack-plugin const HtmlPlugin = require("html-webpack-plugin"); // 2.new构造函数,创建实例对象 const htmlPlugin = new HtmlPlugin({ template: './src/index.html', // 被复制文件路径 filename: './index.html' // 复制的文件路径 }); const {CleanWebpackPlugin} = require("clean-webpack-plugin"); module.exports = { mode: 'development', // production development devtool: 'nosources-source-map', // 插件的数组 webpack在运行时会加载并调用这些插件 output: { path: path.join(__dirname, 'dist'), filename: "js/main.js" }, plugins: [htmlPlugin, new CleanWebpackPlugin()], devServer: { open: true, // 自动打开浏览器 port: 80 }, module: { rules: [ // 定义了不同模块对应的loader {test: /.less$/, use: ['style-loader', 'css-loader', 'less-loader']}, {test: /.css$/, use: ['style-loader', 'css-loader']}, {test: /.jpg|png|gif$/, use: 'url-loader?limit=22229&outputPath=images'}, // 处理高级语法 // {test: /.js$/, use: 'babel-loader', exclude: /node_modules/} ] }, resolve: { alias: { // 告诉webpack @表示src这一层目录 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! '@': path.join(__dirname, './src/') } } }
****************************************************************************************************************************************************************************
32、vue概述(第2天的内容了) 【1】vue一套用于构建 用户界面 的前端 框架 【2】学习vue就是学习框架中规定的用法 【3】指令、组件、路由、Vuex,只有掌握所有内容,才有开发vue的能力 【4】数据驱动视图、双向数据绑定。 页面结构——(自动渲染)——vue监听数据变化——(变化)——页面所依赖的数据 ****************************************** 数据驱动视图,页面自动渲染。程序员只管数据就行了,不用操作dom了!!! ****************************************** 双向数据绑定,form表单采集数据,ajax负责提交数据。页面上表达采集的数据发生变化时,会被vue获取到,并更新到js数据中 ****************************************** M V VM 核心原理。Model(页面渲染时用的数据源) View(当前页面的DOM结构) ViewModel(vue的实例,它是m v vm的核心) View——(自动渲染)——ViewModel(vue)——(变化)——Model 【5】vue的版本 vue1被淘汰了,vue2 vue3两个版本在用。
****************************************************************************************************************************************************************************
35、基本使用 【1】基础项目 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>主页</title> </head> <body> <div id="app"> {{name}} </div> </body> <!--1.导入vue.js--> <script src="./src/lib/vue.js"></script> <!--2.创建vue实例--> <script> const vm = new Vue({ el: '#app', data: { name: '陈翔' } }) </script> </html>
****************************************************************************************************************************************************************************
37、内容渲染指令 【1】指令就是模板语法,辅助开发者渲染页面基本结构的。最常用、最基础、最简单的知识。 【2】六大类:内容渲染、属性绑定、事件绑定、双向绑定、条件渲染、列表渲染六大指令。 【3】v-text会覆盖元素内容原有的内容,用的不多。 {{}}胡子语法,解决内容覆盖问题的,使用频率高。 v-html,如果想保留富文本数据的格式。 <div id="app"> <p v-text="name"></p> <p>性别:{{age}}</p> <p v-html="info"></p> </div> ***************************************************************************** const vm = new Vue({ el: '#app', data: { name: '陈翔', age: 21, info: '<h1> 搞笑</h1>' } }) *****************************************************************************
****************************************************************************************************************************************************************************
39、属性绑定指令 【1】v-bind:属性,可以简写为:属性。对元素的属性进行动态绑定,用的非常多,非常多!!!所以建议简写为:属性。 <div id="app"> <input :placeholder="tips"/> </div> ****************************************************** const vm = new Vue({ el: '#app', data: { name: '陈翔', age: 21, tips: '请输入用户名称' } });
****************************************************************************************************************************************************************************
40、胡子函数与属性绑定可以写简单的运算 【1】{{age+2}}、反转运算等也可以 【2】:id="'list-'+id"
****************************************************************************************************************************************************************************
41、事件绑定 【1】v-on:click="addAge",简写为@click="addAge" <div id="app"> 年龄:{{age}} <br/><br/> <button v-on:click="addAge">过年+1</button> <button v-on:click="backAge">回忆-1</button> </div> **************************************************************************** const vm = new Vue({ el: '#app', data: { name: '陈翔', age: 21, }, methods: { addAge() { this.age = this.age + 1; }, backAge() { this.age = this.age - 1; } } });
****************************************************************************************************************************************************************************
44、绑定函数并传参 【1】传参需要加个小括号 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>主页</title> </head> <body> <div id="app"> 年龄:{{age}} <br/><br/> <button v-on:click="addAge(2)">过年+2</button> <button v-on:click="backAge(3)">回忆-3</button> </div> </body> <!--1.导入vue.js--> <script src="./src/lib/vue.js"></script> <!--2.创建vue实例--> <script> const vm = new Vue({ el: '#app', data: { name: '陈翔', age: 21, }, methods: { addAge(m) { this.age = this.age + m; }, backAge(n) { this.age = this.age - n; } } }); </script> </html> 【2】@click @input @keyup监听其他事件
****************************************************************************************************************************************************************************
46、事件绑定$event 【1】这个就是解决传参时获取原生事件而使用的。$event是固定写法 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>主页</title> </head> <body> <div id="app"> 年龄:{{age}} <br/><br/> <button v-on:click="addAge(2)">过年+2</button> <button v-on:click="backAge(3,$event)">回忆-3</button> </div> </body> <!--1.导入vue.js--> <script src="./src/lib/vue.js"></script> <!--2.创建vue实例--> <script> const vm = new Vue({ el: '#app', data: { name: '陈翔', age: 21, }, methods: { addAge(m) { this.age = this.age + m; }, backAge(n, e) { this.age = this.age - n; // 判断this.age的值是否为偶数 let button = e.target; if (this.age % 2 == 0) { button.style.backgroundColor = 'red'; } else { button.style.backgroundColor = 'green'; } } } }); </script> </html>
****************************************************************************************************************************************************************************
47、事件修饰符 【1】阻止默认跳转,@click.stop阻止事件冒泡 <a href="https://www.baidu.com" @click.prevent="jump">跳转到百度首页</a> methods: { jump() { console.log("点击了a链接") } } ************************************** <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>主页</title> </head> <body> <div id="app"> <a href="https://www.baidu.com" @click="jump">跳转到百度首页</a> </div> </body> <!--1.导入vue.js--> <script src="./src/lib/vue.js"></script> <!--2.创建vue实例--> <script> const vm = new Vue({ el: '#app', data: { name: '陈翔', age: 21, }, methods: { jump(e) { e.preventDefault(); console.log("点击了a链接") } } }); </script> </html>
****************************************************************************************************************************************************************************
49、事件绑定-按键修饰符 【1】@keyup.enter="submit" @keyup.esc="clear" <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>主页</title> </head> <body> <div id="app"> <input type="text" @keyup.esc="clear"/> </div> </body> <!--1.导入vue.js--> <script src="./src/lib/vue.js"></script> <!--2.创建vue实例--> <script> const vm = new Vue({ el: '#app', data: { name: '陈翔', age: 21, }, methods: { clear(e) { let input = e.target; input.value = ""; } } }); </script> </html>
****************************************************************************************************************************************************************************
50、双向绑定-v-model 【1】不操作dom的前提下,拿到表单提交的数据 :value="name"是单向绑定。而v-model="name"则是双向绑定了!!!!!!!!! 【2】只有表单元素使用v-model才有意义,不然其他的使用了就相当于:value,因为不能输入所以还是单向的。 【3】常见使用元素:input textarea select <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>主页</title> </head> <body> <div id="app"> <input type="text" v-model="name"/> <hr/> {{name}} <input type="text" :value="name"/> </div> </body> <!--1.导入vue.js--> <script src="./src/lib/vue.js"></script> <!--2.创建vue实例--> <script> const vm = new Vue({ el: '#app', data: { name: '陈翔', age: 21, } }); </script> </html>
****************************************************************************************************************************************************************************
51、v-model修饰符 【1】v-model.number。修饰符就是简单的过滤器。v-model.trim自动过滤用户输入的首尾空格字符。v-model.lazy 比如删除5个字符,只有在最后删除才同步。 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>主页</title> </head> <body> <div id="app"> <input type="text" v-model.number="dog"/>+ <input type="text" v-model.number="cat"/>=<span>{{dog+cat}}</span> </div> </body> <!--1.导入vue.js--> <script src="./src/lib/vue.js"></script> <!--2.创建vue实例--> <script> const vm = new Vue({ el: '#app', data: { name: '陈翔', dog: 2, cat: 1 } }); </script> </html>
****************************************************************************************************************************************************************************
52、条件渲染指令 【1】v-if每次都是真的删除或创建。 v-show是切换样式的(如果频繁的切换用这个) <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>主页</title> </head> <body> <div id="app"> <span v-if="flag">v-if</span> <hr/> <span v-show="flag">v-show</span> <hr/> <button @click="flag=!flag">点击我换一下</button> </div> </body> <!--1.导入vue.js--> <script src="./src/lib/vue.js"></script> <!--2.创建vue实例--> <script> const vm = new Vue({ el: '#app', data: { name: '陈翔', age: 20, flag: true } }); </script> </html>
****************************************************************************************************************************************************************************
53、v-if配套指令 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>主页</title> </head> <body> <div id="app"> <h1 v-if="flag">Vue is awesome!</h1> <h1 v-else>Oh no!!!</h1> <hr/> <button @click="flag=!flag">点我</button> </div> </body> <!--1.导入vue.js--> <script src="./src/lib/vue.js"></script> <!--2.创建vue实例--> <script> const vm = new Vue({ el: '#app', data: { name: '陈翔', age: 20, flag: false } }); </script> </html>
****************************************************************************************************************************************************************************
54、v-for基本用法 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>主页</title> </head> <body> <div id="app"> <table class="table table-bordered table-hover table-striped"> <thead> <tr> <td>索引</td> <td>ID</td> <td>姓名</td> </tr> </thead> <tbody> <tr v-for="(temp,index) in list"> <td>{{index}}</td> <td>{{temp.id}}</td> <td>{{temp.name}}</td> </tr> </tbody> </table> </div> </body> <link rel="stylesheet" href="./src/lib/bootstrap.css"> <!--1.导入vue.js--> <script src="./src/lib/vue.js"></script> <!--2.创建vue实例--> <script> const vm = new Vue({ el: '#app', data: { list: [ {id: 1, name: '陈翔'}, {id: 2, name: '球球'}, {id: 3, name: '米线'}, ] } }) ; </script> </html>
****************************************************************************************************************************************************************************
55、v-for循环中key 【1】用到了v-for,就要绑定一个:key,而且建议用id绑定。最好使用数值类型的。提升性能,又防止列表乱序。index当key没有意义,因为index会不断变化。 <tr v-for="(temp,index) in list" :key="temp.id">
****************************************************************************************************************************************************************************
57、练习案例 【1】启用、停用 <input text="checkbox" v-model="temp.status"> <lable v-if="flag">已启用</lable> <lable v-else>已禁用</lable> 【2】属性绑定 【3】删除单个商品 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>主页</title> </head> <body> <div id="app"> <table class="table table-bordered table-hover table-striped"> <thead> <tr> <td>索引</td> <td>ID</td> <td>姓名</td> <td>操作</td> </tr> </thead> <tbody> <tr v-for="(temp,index) in list" :key="temp.id"> <td>{{index}}</td> <td>{{temp.id}}</td> <td>{{temp.name}}</td> <td><a href="#" @click="remove(temp.id)">删除</a></td> </tr> </tbody> </table> </div> </body> <link rel="stylesheet" href="./src/lib/bootstrap.css"> <!--1.导入vue.js--> <script src="./src/lib/vue.js"></script> <!--2.创建vue实例--> <script> const vm = new Vue({ el: '#app', data: { list: [ {id: 1, name: '陈翔'}, {id: 2, name: '球球'}, {id: 3, name: '米线'}, ] }, methods: { remove(id) { this.list = this.list.filter(item => item.id !== id) } } }); </script> </html> 【4】添加的功能 <input type="text" v-model.trim="inputName" /> ***********************************************************************完整代码 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>主页</title> </head> <body> <div id="app"> <table class="table table-bordered table-hover table-striped"> <thead> <tr> <td>索引</td> <td>ID</td> <td>姓名</td> <td>操作 <a href="#" @click="add('新的')">新增</a></td> </tr> </thead> <tbody> <tr v-for="(temp,index) in list" :key="temp.id"> <td>{{index}}</td> <td>{{temp.id}}</td> <td>{{temp.name}}</td> <td><a href="#" @click="remove(temp.id)">删除</a></td> </tr> </tbody> </table> </div> </body> <link rel="stylesheet" href="./src/lib/bootstrap.css"> <!--1.导入vue.js--> <script src="./src/lib/vue.js"></script> <!--2.创建vue实例--> <script> const vm = new Vue({ el: '#app', data: { nextId: 4, list: [ {id: 1, name: '陈翔'}, {id: 2, name: '球球'}, {id: 3, name: '米线'}, ] }, methods: { remove(id) { this.list = this.list.filter(item => item.id !== id) }, add(name) { // 如果是空字符串则return出去 if (name === "") { console.log("品牌名称为空"); return } // 执行添加 let temp = {id: this.nextId, name: name}; this.list.push(temp); this.nextId++; } } }); </script> </html>
****************************************************************************************************************************************************************************
64、过滤器在vue3就不能用了 【1】简单了解即可。场景胡子表达式、v-bind属性绑定。 【2】管道符 |就能调用,过滤器本质上是一个函数。 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>主页</title> </head> <body> <div id="app"> <p>{{dog | myFilter}}</p> </div> </body> <link rel="stylesheet" href="./src/lib/bootstrap.css"> <!--1.导入vue.js--> <script src="./src/lib/vue.js"></script> <!--2.创建vue实例--> <script> const vm = new Vue({ el: '#app', data: { name: "陈翔", dog: "see" }, filters: { myFilter(val) { // 强调 过滤器中一定要有返回值 val是 | 前面的值 let tempChar = val.charAt(0).toUpperCase(); return val.replace(val.charAt(0), tempChar) + 'abc' } }, methods: {} }); </script> </html>
****************************************************************************************************************************************************************************
65、全局过滤器filter 【1】一般都是用全局过滤器 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>主页</title> </head> <body> <div id="app"> <p>{{dog | myFilter}}</p> </div> </body> <link rel="stylesheet" href="./src/lib/bootstrap.css"> <!--1.导入vue.js--> <script src="./src/lib/vue.js"></script> <!--2.创建vue实例--> <script> // 这里!!!!!!!!!!!!!!!!!!!!!!!!!!!! Vue.filter('myFilter', (str) => { // 强调 过滤器中一定要有返回值 val是 | 前面的值 let tempChar = str.charAt(0).toUpperCase(); return str.replace(str.charAt(0), tempChar) + 'abc' }) const vm = new Vue({ el: '#app', data: { name: "陈翔", dog: "see" } }); </script> </html>
****************************************************************************************************************************************************************************
67、过滤器的其他用法 【1】可以调用多个过滤器。{{name | myFilter1 | myFilter2 | myFilter3}} 【2】调用过滤器也可以传参{{name | myFilter1(arg1,arg2)}}。过滤器本质就是函数
****************************************************************************************************************************************************************************
68、vue侦听器watch 【1】监视数据变化的。监听谁,就把谁当做watch里的方法名。 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>主页</title> </head> <body> <div id="app"> <input type="text" v-model="name"/> </div> </body> <!--1.导入vue.js--> <script src="./src/lib/vue.js"></script> <!--2.创建vue实例--> <script> const vm = new Vue({ el: '#app', data: { name: "陈翔", age: 21 }, watch: { name(newV, oldV) { // 方法名和属性名保持一致需要 console.log(newV, oldV) } } }); </script> </html>
****************************************************************************************************************************************************************************
69、判断用户名是否被占用 【1】主要是属性变化时,和当前值进行比较。 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>主页</title> </head> <body> <div id="app"> <input type="text" v-model="name"/> </div> </body> <!--1.导入vue.js--> <script src="./src/lib/vue.js"></script> <!--2.创建vue实例--> <script> const vm = new Vue({ el: '#app', data: { name: "陈翔", age: 21 }, watch: { name(newV, oldV) { // 方法名和属性名保持一致需要 console.log(newV, oldV) let list = ['陈翔', '球球', '蘑菇头']; list = list.filter(item => item === newV) if (list.length > 0) { console.log("用户名已存在"); } } } }); </script> </html>
****************************************************************************************************************************************************************************
70、侦听器immediate选项 【1】函数形式的侦听器,刚进来不会被触发???? 【2】对象格式的侦听器。可以通过immediate自动触发一次。 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>主页</title> </head> <body> <div id="app"> <input type="text" v-model="name"/> </div> </body> <!--1.导入vue.js--> <script src="./src/lib/vue.js"></script> <!--2.创建vue实例--> <script> const vm = new Vue({ el: '#app', data: { name: "陈翔", age: 21 }, watch: { name: { // 对象形式的 handler(newV, oldV) { console.log(newV, oldV) let list = ['陈翔', '球球', '蘑菇头']; list = list.filter(item => item === newV) if (list.length > 0) { console.log("用户名已存在"); } }, immediate: true } } }); </script> </html>
****************************************************************************************************************************************************************************
71、侦听器 deep 【1】如果监听的是对象,对象里面的属性不会被监听。可以通过deep选项,让监听器深度监听。 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>主页</title> </head> <body> <div id="app"> <input type="text" v-model="info.name"/> </div> </body> <!--1.导入vue.js--> <script src="./src/lib/vue.js"></script> <!--2.创建vue实例--> <script> const vm = new Vue({ el: '#app', data: { info: { name: "陈翔" } }, watch: { info: { // 对象形式的 handler(newV, oldV) { console.log(newV, oldV) let list = ['陈翔', '球球', '蘑菇头']; list = list.filter(item => item === newV.name) if (list.length > 0) { console.log("用户名已存在"); } }, immediate: true, deep: true // 深度监视 } } }); </script> </html>
****************************************************************************************************************************************************************************
73、计算属性!!!! 【1】很重要。通过一些列运算之后,得到的一个属性值。这个属性值可以在模板或者methods中使用。 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>主页</title> </head> <body> <div id="app"> R: <input type="text" v-model="r"/><br/> G: <input type="text" v-model="g"/><br/> B: <input type="text" v-model="b"/> <hr/> <div :style="{backgroundColor:`rgb(${r},${g},${b})`}"> {{`rgb(${r},${g},${b})`}} </div> <button @click="">随机获取颜色</button> </div> </body> <link rel="stylesheet" href="./src/lib/bootstrap.css"> <!--1.导入vue.js--> <script src="./src/lib/vue.js"></script> <!--2.创建vue实例--> <script> const vm = new Vue({ el: '#app', data: { r: 0, g: 0, b: 0 } }); </script> </html> 【2】每次动态拼接值,很麻烦,怎么解决呢???
****************************************************************************************************************************************************************************
74、计算属性的使用 【1】定义的时候是普通方法。使用的时候当成普通属性使用。实现代码复用。自动求值(只要依赖的数据源变化,计算属性会自动重新求值) <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>主页</title> </head> <body> <div id="app"> R: <input type="text" v-model="r"/><br/> G: <input type="text" v-model="g"/><br/> B: <input type="text" v-model="b"/> <hr/> <div :style="{backgroundColor:rgb}"> {{rgb}} <!--这里是当做属性用--> </div> </div> </body> <link rel="stylesheet" href="./src/lib/bootstrap.css"> <!--1.导入vue.js--> <script src="./src/lib/vue.js"></script> <!--2.创建vue实例--> <script> const vm = new Vue({ el: '#app', data: { r: 0, g: 0, b: 0 }, // 计算属性,定义到这个节点下面 computed: { rgb() { // 返回的是rgb属性 return `rgb(${this.r},${this.g},${this.b})` // es6语法 } } }); </script> </html>
****************************************************************************************************************************************************************************
75、axios使用 【1】专注于网络请求的库。无论vue还是react都是用axios发送网络请求。 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>主页</title> </head> <body> <div id="app"> <button @click="myRequest">发送axios请求</button> </div> </body> <link rel="stylesheet" href="./src/lib/bootstrap.css"> <!--1.导入vue.js--> <script src="./src/lib/vue.js"></script> <script src="./src/lib/axios.js"></script> <!--2.创建vue实例--> <script> const vm = new Vue({ el: '#app', data: { name: "陈翔" }, methods: { myRequest() { const result = axios({ method: "POST", url: "http://localhost:8002/user/login", // URL中查询参数 params: {}, // 请求体 data: { "name": "admin", "password": "123456" } }) result.then(res => { console.log(res); }) } } }); </script> </html>
****************************************************************************************************************************************************************************
76、结合async与await调用 【1】只要某个方法的返回值是Promise实例,则前面可以添加async...await。这时候就不用使用then了 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>主页</title> </head> <body> <div id="app"> <button @click="myRequest">发送axios请求</button> </div> </body> <link rel="stylesheet" href="./src/lib/bootstrap.css"> <!--1.导入vue.js--> <script src="./src/lib/vue.js"></script> <script src="./src/lib/axios.js"></script> <!--2.创建vue实例--> <script> const vm = new Vue({ el: '#app', data: { name: "陈翔" }, methods: { async myRequest() { const result = await axios({ method: "POST", url: "http://localhost:8002/user/login", // 请求体 data: { "name": "admin", "password": "123456" } }) console.log(result) } } }); </script> </html> 【2】解构与赋值 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>主页</title> </head> <body> <div id="app"> <button @click="myRequest">发送axios请求</button> </div> </body> <link rel="stylesheet" href="./src/lib/bootstrap.css"> <!--1.导入vue.js--> <script src="./src/lib/vue.js"></script> <script src="./src/lib/axios.js"></script> <!--2.创建vue实例--> <script> const vm = new Vue({ el: '#app', data: { name: "陈翔" }, methods: { async myRequest() { const {data} = await axios({ //!!!!!!!!!!!!!!!!!!!!!!!!!!! method: "POST", url: "http://localhost:8002/user/login", // 请求体 data: { "name": "admin", "password": "123456" } }) console.log(data) } } }); </script> </html>
****************************************************************************************************************************************************************************
78、axios.get与axios.post 【1】主流post请求使用 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>主页</title> </head> <body> <div id="app"> <button @click="myRequest">发送axios请求</button> </div> </body> <link rel="stylesheet" href="./src/lib/bootstrap.css"> <!--1.导入vue.js--> <script src="./src/lib/vue.js"></script> <script src="./src/lib/axios.js"></script> <!--2.创建vue实例--> <script> const vm = new Vue({ el: '#app', data: { name: "陈翔" }, methods: { myRequest() { axios.post("http://localhost:8002/user/login", { name: "admin", password: "123456" }).then(res => { console.log(res.data); }) } } }); </script> </html>
****************************************************************************************************************************************************************************
79、vue-cli概述与安装 【1】单页面应用程序。麻雀虽小,五脏俱全。 【2】vue-cli是vue.js开发的标准工具。简化了程序员基于webpack创建工程化Vue项目的过程。程序员只需要专注写应用,而不必花几天去纠结webpack配置。 【3】安装和使用 npm i -g @vue/cli -force ************************************************** vue -V 查看是否安装成功 ************************************************** vue create day_app ************************************************** Manually select features选择这个 ************************************************** CSS Pre-processors通过空格选中 ************************************************** 2.x版本先选择 ************************************************** less选择后回车 ************************************************** In dedicated config files选择 ************************************************** y选择 ************************************************** HIT-2023
****************************************************************************************************************************************************************************
81、vue-cli创建项目的启动效果 【1】npm run serve 【2】访问localhost:8080
****************************************************************************************************************************************************************************
82、项目目录概述 【1】node_modules 第三方包。src源代码目录。 【2】assets静态资源。components 组件的集合,程序员封装的可复用的组件都要放在这下面。 【3】main.js是项目的入口文件。相当于index.js文件 【4】App.vue是项目的根组件
****************************************************************************************************************************************************************************
84、vue项目的运行过程 【1】很单纯,就是通过main.js把App.vue渲染到index.html的指定区域中。 ***************************************************** import Vue from 'vue' // 导入App.vue组件,将来要把App.vue中的结构渲染到HTML页面中 import App from './App.vue' Vue.config.productionTip = false new Vue({ // 通过render函数指定组件,渲染到HTML页面中 render: h => h(App), }).$mount('#app') 【2】$mount('#app') 就相当于 el:"#app"
****************************************************************************************************************************************************************************
86、vue组件的三个组成部分 【1】组件化就是对UI结构的封装与复用。 【2】组件的后缀名都是.vue。App组件。 【3】template 组件的模板结构。script 组件的js行为。style组件的样式。 <!--第1部分--> <template> <h1 class="box">App.vue组件---{{name}}</h1> </template> <!--第2部分--> <script> export default { data() { // 组件里的data不能指向对象,必须要写成方法 return { name: '陈翔', } }, } </script> <!--第3部分--> <style> .box { background-color: pink; } </style>
****************************************************************************************************************************************************************************
87、vue组件中定义方法 【1】属性只能以方法的形式定义。 <!--第1部分--> <template> <div> <h1 class="box">App.vue组件---{{name}}</h1> <button @click="changeName">修改姓名</button> </div> </template> <!--第2部分--> <script> export default { data() { // 组件里的data不能指向对象,必须要写成方法 return { name: '陈翔', } }, methods: { changeName() { this.name = "球球" } }, watch: {}, computed: {}, filters: {} } </script> <!--第3部分--> <style> .box { background-color: pink; } </style>
****************************************************************************************************************************************************************************
88、启用less语法以及唯一根节点 【1】template下面只能放一个唯一的div,外面必须有个最大的div 【2】<style> <!--第1部分--> <template> <div> <h1>App.vue组件---{{name}}</h1> <button @click="changeName">修改姓名</button> </div> </template> <!--第2部分--> <script> export default { data() { // 组件里的data不能指向对象,必须要写成方法 return { name: '陈翔', } }, methods: { changeName() { this.name = "球球" } }, watch: {}, computed: {}, filters: {} } </script> <!--第3部分!!!!!!!!!!!!!!!!!!!!!!--> <style> .box { background-color: pink; h1 { color: red; } } </style>
****************************************************************************************************************************************************************************
90、使用组件的三个步骤 【1】父子关系。组件封装好之后是彼此独立的。 【2】当App.vue使用了Left.vue与Right.vue之后,才形成了父子关系。 【3】分为下面三个步骤使用。 步骤1:import语法导入需要的组件 import Left from "@/components/Left"; ******************************************************************* 步骤2:使用components节点注册组件 components: { Left, Right }, data() { // 组件里的data不能指向对象,必须要写成方法 return { name: '陈翔', } }, ******************************************************************* 步骤3:以标签的形式使用注册后的组件 <Left></Left> <Right></Right> ******************************************************************* <!--第1部分--> <template> <div> <h1>App.vue组件---{{name}}</h1> <button @click="changeName">修改姓名</button> <Left></Left> <Right></Right> </div> </template> <!--第2部分--> <script> // 导入需要使用的组件 import Left from "@/components/Left"; import Right from "@/components/Right"; export default { components: { Left, Right }, data() { // 组件里的data不能指向对象,必须要写成方法 return { name: '陈翔', } }, methods: { changeName() { this.name = "球球" } }, watch: {}, computed: {}, filters: {} } </script> <!--第3部分--> <style> .box { background-color: pink; h1 { color: red; } } </style>
****************************************************************************************************************************************************************************
93、Vue.components的使用 【1】通过components注册的是私有子组件。如果在A的components注册了F,F只能在A中使用,不能用于其他组件。如果其他组件要使用,F也要在对应组件注册。 【2】如果某个组件被频繁的使用,则该组件可以注册为全局组件。在main.js注册为全局的组件。 // 导入App.vue组件,将来要把App.vue中的结构渲染到HTML页面中 import App from './App.vue' import Vue from 'vue' import Count from "@/components/Count"; // !!!!!!!!!!!! Vue.config.productionTip = false Vue.component("Count", Count) // !!!!!!!!!!!! new Vue({ // 通过render函数指定组件,渲染到HTML页面中 render: h => h(App), }).$mount('#app')
****************************************************************************************************************************************************************************
95、组件里的props 【1】如果两个组件都分别使用了Count.vue组件,如何给Count指定属性赋初始值。props就可以解决这个问题,极大的提高了组件的复用性。 <template> <div> 我是Count.vue组件 <p>count的值是{{init}}</p> <button @click="init=init+1">点击+1</button> </div> </template> <script> export default { name: "Count", props: ['init'], data() { return { count: 0 } } , methods: {} } </script> <style scoped> .box { background-color: gray; } </style> *************************************************************************** <template> <div> 我是Left.vue组件 <Count :init="1"></Count> </div> </template> <script> export default { name: "Left" } </script> <style scoped> .box { background-color: yellow; } </style> ***************************************************************************** <template> <div> 我是Right.vue组件 <Count :init="20"></Count> </div> </template> <script> export default { name: "Right" } </script> <style scoped> .box { background-color: green; } </style>
****************************************************************************************************************************************************************************
97、props是只读的。 【1】比如直接修改init在控制台console中会报错Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "init" 【2】说明props是只读的。所以初始值赋给count,然后count=count+1 <template> <div> 我是Count.vue组件 <p>count的值是{{count}}</p> <button @click="count=count+1">点击+1</button> </div> </template> <script> export default { name: "Count", props: ['init'], data() { return { count: this.init //!!!!!!!!!!!!!!!!!!!!!!!!!!!!! } }, methods: {} } </script> <style scoped> .box { background-color: gray; } </style>
****************************************************************************************************************************************************************************
98、props给默认值 【1】如果用户不传给默认值0。 props: { init: { default: 0 } }, data() { return { count: this.init } } 【2】type值类型,这样直接传就行了,不用额外加:init就能接收到数值类型。 props: { init: { default: 0, type: Number // !!!!!!!!! String Boolean } }
****************************************************************************************************************************************************************************
100、props-required必填项 【1】不传就会报错!!!!!!!! props: { init: { default: 0, type: Number, required: true } } ************************************************************************** vue.runtime.esm.js?c320:4605 [Vue warn]: Missing required prop: "init"
****************************************************************************************************************************************************************************
101、组件间的样式冲突 【1】就是父组件的样式,不应该覆盖子组件的样式。scoped <style scoped> .box { background-color: yellow; } </style>
****************************************************************************************************************************************************************************
102、样式穿透 【1】使用第三方组件库的时候,如果需要修改组件默认样式,需要用到/deep/ 来修改
****************************************************************************************************************************************************************************
103、vue组件的实例对象 【1】<Count :init="0"></Count>用标签的形式使用组件,该组件就被实例化了。Count使用的时候就被实例化了。
****************************************************************************************************************************************************************************
104、生命周期 【1】一个组件(比如Count.vue)从创建-运行-销毁的整个阶段,强调的是时间段。 【2】创建阶段:beforeCreate、created、beforeMount、mounted 【3】组件运行阶段:beforeUpdate、updated 【4】组件销毁阶段beforeDestroy、destroyed
****************************************************************************************************************************************************************************
105、组件创建 【1】main.js-App.vue-Left.vue/Right.vue-Count.vue 【2】注册组件Test到App中使用。 <template> <div> <h3>Test.vue组件</h3> </div> </template> <script> export default { name: "Test" } </script> <style scoped> .box { background-color: pink; height: 200px; } </style>
****************************************************************************************************************************************************************************
106、beforeCreated、created 【1】beforeCreated这个函数不重要,因为很多东西还做不了。下面做了演示。 <template> <div> <h3>Test.vue组件</h3> </div> </template> <script> export default { name: "Test", props: ['info'], data() { return { name: "陈翔" } }, methods: { show() { console.log("Test组件的show方法") } }, beforeCreate() { //console.log(this.info); //console.log(this.name); this.show(); } } </script> <style scoped> .box { background-color: pink; height: 200px; } </style> 【2】created用的多,props data methods都初始化完毕了。这个函数很重要,这个阶段可以发起axios请求去拿数据。
****************************************************************************************************************************************************************************
107、beforeMount、mounted 【1】created阶段不能操作dom。因为一些模板结构还没有生成。 【2】beforeMount只是在内存中有结构,页面上还没有dom结构。这个函数没有什么意义 【3】mounted这个阶段是真正的dom渲染阶段。所以ed的用的还是很多的。这个函数也非常重要!!!!!!!!!!! mounted() { let div = document.getElementsByClassName('box'); console.log(div); }
****************************************************************************************************************************************************************************
108、组件运行阶段生命周期 【1】beforeUpdate、updated 【2】数据改变时,才会触发beforeUpdate。 <button @click="change">追加后缀+</button>。dom结构还没重新渲染。 <template> <div> <h3>Test.vue组件-{{name}}</h3> <button @click="change">追加后缀+</button> </div> </template> <script> export default { name: "Test", props: ['info'], data() { return { name: "陈翔" } }, methods: { show() { console.log("Test组件的show方法") }, change() { this.name = this.name + "六点半"; } }, beforeCreate() { //console.log(this.info); //console.log(this.name); // this.show(); }, created() { console.log(this.info); console.log(this.name); this.show(); }, mounted() { let div = document.getElementsByClassName('box'); console.log(div); }, beforeUpdate() { console.log("beforeUpdate") } } </script> <style scoped> .box { background-color: pink; height: 200px; } </style> 【3】updated代表dom已经重新渲染完毕了。
****************************************************************************************************************************************************************************
109、销毁阶段的生命周期函数 【1】这个阶段极少用。了解下就行了。 <!--第1部分--> <template> <div> <h1>App.vue组件---{{name}}</h1> <button @click="changeName">修改姓名</button> <Left></Left> <Right></Right> <Test info="您好" v-if="flag"></Test> <button @click="flag=!flag">换下Test.vue的展示</button> </div> </template> <!--第2部分--> <script> // 导入需要使用的组件 import Left from "@/components/Left"; import Right from "@/components/Right"; import Test from "@/components/Test"; export default { components: { Left, Right, Test }, data() { // 组件里的data不能指向对象,必须要写成方法 return { name: '陈翔', flag: true } }, methods: { changeName() { this.name = "球球" } }, watch: {}, computed: {}, filters: {} } </script> <!--第3部分--> <style> .box { background-color: pink; border: 3px solid black; h1 { color: red; } } </style> **************************************************************** <template> <div> <h3>Test.vue组件-{{name}}</h3> <button @click="change">追加后缀+</button> </div> </template> <script> export default { name: "Test", props: ['info'], data() { return { name: "陈翔" } }, methods: { show() { console.log("Test组件的show方法") }, change() { this.name = this.name + "六点半"; } }, beforeCreate() { //console.log(this.info); //console.log(this.name); // this.show(); }, created() { console.log(this.info); console.log(this.name); this.show(); }, mounted() { let div = document.getElementsByClassName('box'); console.log(div); }, beforeUpdate() { console.log("beforeUpdate") }, destroyed() { console.log("Test.vue组件被销毁了"); } } </script> <style scoped> .box { background-color: pink; height: 200px; } </style> 【2】重要的函数都是以ed结尾的重要!!!
****************************************************************************************************************************************************************************
110、组件之间的数据共享 【1】组件之间最常见的关系是父子关系+兄弟关系。 【2】父->子传数据。App.vue 把 name: '陈翔' 传给Left.vue使用 <Left :name="name" :dog="dog"></Left> ************************************************************************** props: ['name', 'dog'] ************************************************************************** 父组件传过来的人名:{{name}} 父组件传过来的狗子:姓名{{dog.name}} 年龄:{{dog.age}}
****************************************************************************************************************************************************************************
111、父向子传值-演示 【1】父组件App.vue <!--第1部分--> <template> <div> <h1>App.vue组件</h1> <Left :group="group" :userInfo="userInfo"></Left> </div> </template> <!--第2部分--> <script> // 导入需要使用的组件 import Left from "@/components/Left"; export default { components: { Left, }, data() { // 组件里的data不能指向对象,必须要写成方法 return { group: '万达', userInfo: { name: "王思聪", age: 18 } } }, } </script> <!--第3部分--> <style> .box { background-color: pink; border: 3px solid black; h1 { color: red; } } </style> 【2】子组件Left.vue <template> <div> 我是Left.vue组件 父组件传过来的group值是{{group}} 父组件传过来的userInfo值是{{userInfo}} </div> </template> <script> export default { name: "Left", props: ['group', 'userInfo'] } </script> <style scoped> .box { background-color: yellow; } </style> 【3】实际开发中不要修改父组件传给子组件的值。属性需要子组件中用props:['name','list']声明。
****************************************************************************************************************************************************************************
113、子向父传值 【2】子-父组件。子组件向父组件传值,需要使用自定义事件。 <template> <div> 我是Left.vue子组件{{count}}<br/> <button @click="add">点击+1</button> </div> </template> <script> export default { name: "Left", data() { return { count: 0 } }, methods: { add() { this.count = this.count + 1 // 自定义事件 传值给父组件 this.$emit('giveValueToFather', this.count) // !!!!!!!!!!! } } } </script> <style scoped> .box { background-color: yellow; } </style> 【3】父组件接收 <!--第1部分--> <template> <div> <h1>App.vue父组件---{{countFromSon}}</h1> <Left @giveValueToFather="fatherGetMethod"></Left> <!--!!!!!!!!!!!!!!!!!!!!--> </div> </template> <!--第2部分--> <script> // 导入需要使用的组件 import Left from "@/components/Left"; export default { components: { Left, }, data() { return { // 定义从子组件传值的属性 countFromSon: 0 } }, methods: { fatherGetMethod(newVal) { // !!!!!!!!!!!!!!!!!!!!!! this.countFromSon = newVal; } } } </script> <!--第3部分--> <style> .box { background-color: pink; border: 3px solid black; h1 { color: red; } } </style>
****************************************************************************************************************************************************************************
114、兄弟组件之间的数据共享 【1】共享方案是EventBus。eventBus.js import Vue from 'vue' export default new Vue() 【2】 Left.vue <template> <div class="box"> 我是Left.vue子组件(兄弟A)<br/> <button @click="sendMsg">发送数据</button> </div> </template> <script> import eventBus from "@/components/eventBus"; // !!!!!!!!!!! export default { name: "Left", data() { return { msg: '黑云压城城欲摧,甲光向日金鳞开' } }, methods: { sendMsg() { // 通过eventBus发送数据 eventBus.$emit("sendMsgToBrotherRight", this.msg)// !!!!!!!!!!! } } } </script> <style scoped> .box { background-color: yellow; } </style> 【3】Right.vue <template> <div class="box"> 我是Right.vue子组件(兄弟B)---{{msgFromBrotherLeft}}<br/> </div> </template> <script> import eventBus from "@/components/eventBus"; export default { name: "Right", data() { return { msgFromBrotherLeft: '' } }, created() { eventBus.$on('sendMsgToBrotherRight', getVal => { // !!!!!!!!!!! this.msgFromBrotherLeft = getVal }) } } </script> <style scoped> .box { background-color: deepskyblue; } </style> 【4】其实这个也可以用于父子传,卧槽!!!!
****************************************************************************************************************************************************************************
117、组件之间的数据共享 【1】父-子传值:自定义属性。父组件绑定属性。子组件生命props接收,这种最简单。 【2】子-父传值:自定义事件。子组件定义属性,子组件this.$emit('giveValueToFather',this.属性)。父组件使用@giveValueToFather="getNewVal" 来更新数据到父组件属性 【3】兄弟组件之间的数据传递:eventBus.js 。 eventBus.$emit("sendMsgToBrotherRight", this.msg)。 *************************************************************************** eventBus.$on('sendMsgToBrotherRight', getVal => { this.msgFromBrotherLeft = getVal })