VUE2从入门到精通(一)

****************************************************************************************************************************************************************************

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  developmentdevtool: '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  developmentdevtool: '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  developmentdevtool: '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 = falsenew 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})

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/830826.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

STM32 看门狗WDG

一、看门狗&#xff08;Watchdog&#xff09; 看门狗可以监控程序的运行状态&#xff0c;当程序因为设计漏洞、硬件故障、电磁干扰等原因&#xff0c;出现卡死或跑飞现象时&#xff0c;看门狗能及时复位程序&#xff0c;避免程序陷入长时间的罢工状态&#xff0c;保证系统的可靠…

Django后台项目开发实战一

开发环境使用 Anaconda, IDE 使用 pycharm 第一阶段 创建 Django 项目 在 Anaconda Prompt 中逐步输入下面的命令&#xff08;之后的所有命令都在这个&#xff09; 首先创建一个虚拟环境&#xff0c;名称自拟&#xff0c;python 版本我这里使用 3.9.18 关于 python 版本和…

PotatoPie 4.0 实验教程(28) —— FPGA实现sobel算子对摄像头图像进行边缘提取

什么是sobel算子&#xff1f; Sobel 算子是一种常用的边缘检测算子&#xff0c;用于在图像中检测边缘。它基于对图像进行梯度运算&#xff0c;可以帮助识别图像中灰度值变化较大的区域&#xff0c;从而找到图像中的边缘。 Sobel 算子通过计算图像的水平和垂直方向的一阶导数来…

Linux 虚拟主机切换php版本及参数

我使用的Hostease的Linux虚拟主机产品,由于网站程序需要支持高版本的PHP,程序已经上传到主机&#xff0c;但是没有找到切换PHP以及查看PHP有哪些版本的位置&#xff0c;因此咨询了Hostease的技术支持&#xff0c;寻求帮助了解到可以实现在cPanel面板上找到此切换PHP版本的按钮&…

2024 五一杯高校数学建模邀请赛(A题)|钢板最优切割路径问题|建模秘籍文章代码思路大全

铛铛&#xff01;小秘籍来咯&#xff01; 小秘籍团队独辟蹊径&#xff0c;运用Dijkstra算法&#xff0c;最优路径切割等强大工具&#xff0c;构建了这一题的详细解答哦&#xff01; 为大家量身打造创新解决方案。小秘籍团队&#xff0c;始终引领着建模问题求解的风潮。 抓紧小秘…

Stability AI 推出稳定音频 2.0:为创作者提供先进的 AI 生成音频

概述 Stability AI 的发布再次突破了创新的界限。这一尖端模型以其前身的成功为基础&#xff0c;引入了一系列突破性的功能&#xff0c;有望彻底改变艺术家和音乐家创建和操作音频内容的方式。 Stable Audio 2.0 代表了人工智能生成音频发展的一个重要里程碑&#xff0c;为质量…

Flask模版详解

Flask模版详解 概述Jinja2模板引擎渲染模版的步骤变量控制结构自定义错误页面链接静态文件 概述 模板是一个包含响应文本的文件&#xff0c;其中包含用占位变量表示的动态部分&#xff0c;其具体值只在请求的上下文中才能知道。使用真实值替换变量&#xff0c;再返回最终得到的…

Android4.4真机移植过程笔记(一)

1、RK源码编译 获取内核源码&#xff1a; git clone git172.28.1.172:rk3188_kernel -b xtc_ok1000 内核编译环境&#xff1a; 从172.28.1.132编译服务器的/data1/ZouZhiPing目录下拷贝toolchain.tar.gz&#xff08;交叉编译工具链&#xff09;并解压到与rk3188_kernel同级目…

Golang | Leetcode Golang题解之第59题螺旋矩阵II

题目&#xff1a; 题解&#xff1a; func generateMatrix(n int) [][]int {matrix : make([][]int, n)for i : range matrix {matrix[i] make([]int, n)}num : 1left, right, top, bottom : 0, n-1, 0, n-1for left < right && top < bottom {for column : lef…

前端发起网络请求的几种常见方式(XMLHttpRequest、FetchApi、jQueryAjax、Axios)

摘要 前端发起网络请求的几种常见方式包括&#xff1a; XMLHttpRequest (XHR)&#xff1a; 这是最传统和最常见的方式之一。它允许客户端与服务器进行异步通信。XHR API 提供了一个在后台发送 HTTP 请求和接收响应的机制&#xff0c;使得页面能够在不刷新的情况下更新部分内容…

【分享】如何将word格式文档转化为PDF格式

在日常的办公和学习中&#xff0c;我们经常需要将Word文档转换为PDF格式。PDF作为一种通用的文件格式&#xff0c;具有跨平台、易读性高等优点&#xff0c;因此在许多场合下都更为适用。那么&#xff0c;如何实现Word转PDF呢&#xff1f;本文将介绍几种常用的方法&#xff0c;帮…

光伏储能是什么意思?有什么好处?

随着全球能源需求的持续增长和对环保要求的不断提高&#xff0c;新能源技术的发展已成为全球的热门话题。光伏储能作为其中的一项重要技术&#xff0c;正在逐渐受到人们的关注。那么&#xff0c;光伏储能是什么意思&#xff1f;它又有哪些好处呢&#xff1f; 一、光伏储能的定义…

『FPGA通信接口』DDR(3)DDR3颗粒读写测试

文章目录 前言1.配套工程简介2.测试内容与策略3. 测试程序分析4.程序结果分析5.一个IP控制两颗DDR36.传送门 前言 以四颗MT41K512M16HA-125AIT颗粒为例&#xff0c;介绍如何在一块新制板卡上做关于DDR3的器件测试。前面两篇介绍了什么是DDR&#xff0c;并介绍了xilinx给出的FPG…

神经网络反向传播算法

今天我们来看一下神经网络中的反向传播算法&#xff0c;之前介绍了梯度下降与正向传播~ 神经网络的反向传播 专栏&#xff1a;&#x1f48e;实战PyTorch&#x1f48e; 反向传播算法&#xff08;Back Propagation&#xff0c;简称BP&#xff09;是一种用于训练神经网络的算…

品牌百度百科词条需要什么资料?

品牌百度百科词条是一个品牌的数字化名片&#xff0c;更是品牌历史、文化、实力的全面展现。 作为一个相当拿得出手的镀金名片&#xff0c;品牌百度百科词条创建需要什么资料&#xff0c;今天伯乐网络传媒就来给大家讲解一下。 一、品牌基本信息&#xff1a;品牌身份的明确 品…

【漏洞复现】科达 MTS转码服务器 任意文件读取漏洞

0x01 产品简介 科达 MTS转码服务器是一款专业的视频转码设备&#xff0c;采用了高性能的硬件配置和先进的转码技术&#xff0c;能够实现高效、高质量的视频转码。 0x02 漏洞概述 科达 MTS转码服务器存在任意文件读取漏洞&#xff0c;攻击可以通过该漏洞读取服务器任意敏感信…

FSD自动驾驶泛谈

特斯拉的FSD&#xff08;Full-Self Driving&#xff0c;全自动驾驶&#xff09;系统是特斯拉公司研发的一套完全自动驾驶系统。旨在最终实现车辆在多种驾驶环境下无需人类干预的自动驾驶能力。以下是对FSD系统的详细探讨&#xff1a; 系统概述 FSD是特斯拉的自动驾驶技术&…

宠物领养|基于SprinBoot+vue的宠物领养管理系统(源码+数据库+文档)

宠物领养目录 基于Spring Boot的宠物领养系统的设计与实现 一、前言 二、系统设计 三、系统功能设计 1前台 1.1 宠物领养 1.2 宠物认领 1.3 教学视频 2后台 2.1宠物领养管理 2.2 宠物领养审核管理 2.3 宠物认领管理 2.4 宠物认领审核管理 2.5 教学视频管理 四、…

零基础自学前端到达到什么水平才能找工作?

零基础自学前端到达到什么水平才能找工作&#xff1f; 零基础自学前端到达到什么水平才能找工作&#xff1f;从这个字眼的表面上来回答这个问题&#xff0c;但是是前端水平越高越好咯。前端技术人才只有不断通过学习、项目的事件来不断充实提高自己的技术&#xff0c;随之而来&…

【Jenkins】持续集成与交付 (四):修改Jenkins插件下载地址、汉化

🟣【Jenkins】持续集成与交付 (四):修改Jenkins插件下载地址、汉化 一、修改Jenkins插件下载地址二、汉化Jenkins三、关于Jenkins💖The Begin💖点点关注,收藏不迷路💖 一、修改Jenkins插件下载地址 由于Jenkins官方插件地址下载速度较慢,我们可以通过修改下载地址…