Vue React Angular 前端三大框架
组件(是对UI结构的复用)
一.Vue概述
1.什么是Vue
是一套用于构建用户界面的前端框架
(1)构建用户界面
用vue 往html 页面中填充数据
(2)框架
框架是一套现成的解决方案
程序员只能遵守框架的规范去编写自己的业务功能
2.Vue 的特性
(1)数据驱动视图
(2)双向数据绑定
数据就是指:ajax 从服务器请求回来的数据
1.数据驱动视图
vue 会监听数据的变化,从而自动重新渲染页面结构
-------------------------------------------------------
页面解构 <---(自动渲染) Vue监听数据的变化 <--- 页面所依赖的数据
-------------------------------------------------------
好处:
当页面数据发生变化时,页面会自动重新渲染
注意:
数据驱动视图是单向的数据绑定
2.双向数据绑定
在填写表单时,双向数据绑定可以在不操作DOM 的前提下,自动把用户填写的内容同步到数据源中
from 表单负责采集数据,Ajax 负责提交数据
js 数据的变化,会被自动渲染到页面上
页面上表单采集的数据发生变化的时候,会被vue 自动获取到,并更新到js 数据中
------------------------------------------------------
<- 自动渲染 <- 变化
页面解构 ----------- Vue ----------- 页面所依赖的数据
值发生变化 -> 自动同步 ->
------------------------------------------------------
好处:
开发者不再需要手动操作DOM 元素,来获取表单元素最新的值
3.MVVM
MVVM 是vue 实现数据驱动视图和双向数据绑定的核心原理
把每个HTML 页面都拆分成了这三个部分
MVVM 指的是Model、View、和ViewModel
Model:表示当前页面渲染时所依赖的数据源(如:用Ajax 拿到的数据)
具体指:data(){}
View:表示当前页面所渲染的DOM 结构
具体指:el:'#app'
ViewModel:表示vue 的实例,它是MVVM 的核心
具体指:const vm = new Vue(new 出来的vue 实例对象)
ViewModel:
ViewModel 是MVVM 的核心
是它把当前页面的数据源(Model)和页面解构(View)连接在了一起
-------------------------------------------------
<- 自动更新 <- 监听数据源变化
View --------------- ViewModel ---------------- Model
监听DOM 变化 -> 自动同步 ->
-------------------------------------------------
当数据源发生变化时,会被ViewModel 监听到,VM会根据最新的数据源自动更新页面的结构
当表单元素的值发生变化时,也会被VM 监听到,VM会把变化过后最新的值自动同步到Model 数据源中
二.Vue 的基本使用
示例:
<body>
<!-- 希望vue 可以控制下面这个div,把数据填充到div 中 -->
<div id="app">{{ username }}</div>
<!-- 1. 导入vue 的库文件 -->
<script src="../js/vue.js"></script>
<!-- 在window 全局就有了Vue 这个构造函数 -->
<!-- 2. 创建vue 的实例对象 -->
<script>
// 创建vue 的实例对象
const vm = new Vue({
// el 属性是固定的写法,表示当前vm 实例要控制页面上的哪个区域 接收的值是一个选择器
el: '#app',
// data 对象就是要渲染到页面上的数据
data: {
username: 'zhangsan'
}
})
</script>
</body>
三.Vue 的调试工具
1.安装vue-devtools 调试工具
Chrome 浏览器在线安装vue-devtools:
http://chrome.google.com/webstore/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhbledajbpd
FireFox 浏览器在线安装vue-devtools:
http://addons.mozilla.org/zh-CN/firefox/addon/vue-js-devtools/
四.Vue 指令
指令是vue 提供的模板语法,用于辅助开发者渲染页面的基本结构
按照不同的用途分为6类:
(1)内容渲染指令
(2)属性绑定指令
(3)事件绑定指令
(4)双向绑定指令
(5)条件渲染指令
(6)列表渲染指令
在vue 提供的模板渲染语法中,除了支持绑定简单的数据之外,还支持Javascript 表达式的运算
示例:
{{number + 1}}
{{ok? 'Yes':'No'}}
{{message.split('').reverse().join('')}}
<div v-bind:id="'list-' + id"></div>
1.内容渲染指令
用来渲染DOM 元素的文本内容
(1)v-text
示例:
<div v-text="username">姓名</div> // 输出结果: zhangsan // 没有姓名俩字
// 把username 的值渲染到p 标签内部
data: {
username: 'zhangsan',
}
缺点:会覆盖元素内部原有的内容
(2){{}}
又叫插值表达式,专门用来解决v-text 覆盖默认文本内容的问题
是内容的占位符,不会覆盖原有的内容
示例:
<div>姓名:{{username}}</div>
data: {
username: 'zhangsan',
}
注意:
插值表达式只能用在元素的内容节点中,不能用在元素的属性节点中
(3)v-html
由于v-text 和插值表达式只能渲染纯文本内容
v-html 可以渲染带有HTML 标签的字符串为真正的HTML 内容
示例:
<div v-html="info"></div>
data: {
info: '<h4 style="color: red;font-weight: bold">嗯嗯嗯</h4>'
}
2.属性绑定指令
v-bind:
为元素的属性动态绑定属性值
简写为: :
示例:
<input type="text" v-bind:placeholder="tips">
data: {
tips: '请输入用户名'
}
注意:
在使用v-bind 属性绑定期间,如果绑定内容需要进行动态拼接,则字符串的外面应该包裹单引号
示例:
<div v-bind:id="'list-' + id"></div>
data{
id: 3
}
3.事件绑定指令
1. v-on:
为DOM元素绑定事件监听
简写为: @
语法:
v-on:事件名称="事件处理函数名称"
示例:
<button @click="add(2)">+2</button>
// data 对象就是要渲染到页面上的数据
data: {
count: 0
},
// methods 的作用,就是定义事件的处理函数
methods: {
// add: function(){
// console.log('ok');
// }
// 简写为:
add(n){
console.log('ok');
this.count += n;
}
}
// 如果在方法中要修改data 中的数据,可以通过this 访问到
2. 事件对象 $event
vue 提供了内置变量 $event, 它就是原生DOM 的事件对象e
示例:
1.无参数时
add() // 默认e 指向$event,不需要手动声明
2.有参数时
add(1,$event) -> add(n,e){} // $event 用e 接收
e.target 指向当前对象
3. 事件修饰符
如:
原生DOM中:event.preventDefault() (阻止事件默认行为)和 event.stopPropagation() (阻止事件冒泡)
五个事件修饰符:
----------------------------------------------------
.prevent 阻止默认行为(例如:阻止a链接的跳转、阻止表单的提交等)
.stop 阻止事件冒泡
.capture 以捕获模式触发当前的事件处理函数
.once 绑定的事件只触发一次
.self 只有在event.target 是当前元素自身时触发事件处理函数
示例:
.prevent:
<a href="http://www.baidu.com" @click.prevent="show">跳转到百度</a>
.stop:
<button @click.stop="btnHandler">按钮</button>
4.按键修饰符
1.只有在'key' 是 'Esc' 时调用'vm.clearInput()'
<input type="text" @keyup.esc="clearInput">
2.只有在'key' 是 'Enter' 时调用'vm.commitAjax()'
<input type="text" @keyup.enter="commitAjax">
4.双向绑定指令
1.v-model
双向数据绑定指令,用来在不操作DOM 的前提下,获取表单的数据
示例:
双向数据绑定:v-model
<input type="text" v-model="username">
// data -> view & view -> data
数据驱动视图:v-bind:
<input type="text" :value="username">
// data -> view
注意:
v-model 指令只能修饰表单控件
如:
1.input
type="radio"
type="checkbox"
...
2.textarea
3.select
2.v-model 指令的修饰符
.number 自动将用户的输入值转换为数值类型 <input v-model.number="age">
.trim 自动过滤用户输入的首尾空白字符 <input v-model.trim="msg">
.lazy 在"change"时而非"input"时更新 <input v-model.lazy="msg"
示例:
<input type="text" v-model.number="n1">
5.条件渲染指令
条件渲染指令用来按需控制DOM 的显示与隐藏
1.v-if
原理:
每次动态创建或移除元素,实现元素的显示和隐藏
v-else:
v-else 指令必须配合v-if 指令一起使用,否则不被识别
v-else-if:
v-else-if 指令必须配合v-if 指令一起使用,否则不被识别
2.v-show
原理:
动态为元素添加或移除 display:none; 样式,来实现元素的显示和隐藏
注意:
如果要频繁切换元素的显示状态,用v-show 性能会更好
如果刚进入页面的时候,某些元素默认不需要被展示,而且后期这个元素很可能也不需要被展示出来,此时用v-if 性能更好
在实际开发中,绝大多数情况下,不用考虑性能问题,直接使用v-if 就好了
6.列表渲染指令
v-for 用来基于一个数组来循环渲染一个列表结构
语法格式: item in items
items 是待循环的数组
item 是被循环的每一项
v-for 指令还支持一个可选的第二个参数,即当前项的索引
语法格式: (item,index) in items
规定:
只要用到了v-for 指令,那么一定要绑定一个:key 属性,且尽量把id 作为key 的值
1.key 的值只能是 字符串 或 数字 类型
2.key 的值不能重复
3.建议把数据项id 属性的值作为key 的值(因为id 属性的值具有唯一性)
4.使用index 的值当做key 的值没有任何意义(因为index 的值不具有唯一性)
5.建议使用v-for 指令时一定要指定key 的值(既提升性能,又放置列表状态紊乱)
示例:
<tr v-for="(item,index) in list" :key="item.id" :title="item.name + index">
品牌列表案例:
1. // 点击链接删除对应的商品
remove(id){
this.list = this.list.filter(item => item.id !== id)
}
五.过滤器
Vue 3 中已删除过滤器的使用
1.过滤器的基本使用
过滤器(Filters)常用于文本的格式化
过滤器用在两个地方:插值表达式 和 v-bind 属性绑定
过滤器本质上是个函数
过滤器应该被添加在JavaScript 表达式的底部,由管道符进行调用
管道符: | 管道符作用:表示要调用过滤器函数
过滤器的作用: 将 | 前面的值 传给 | 后面的过滤器函数,并返回过滤后的值
示例:
1.在双花括号中通过“管道符” 调用capitalize 过滤器,对message 的值进行格式化
<p>{{ message | capitalize}}</p>
2.在 v-bind 中通过“管道符” 调用formatId 过滤器,对rawId 的值进行格式化
<div v-bind:id="rawId | formatId"></div>
注意:
1.过滤器要定义到filters 节点下,本质是一个函数
2.在过滤器函数中,一定要有return 值
3.在过滤器的形参中,就可以获取到管道符前面待处理的那个值
2.使用Vue.filter 定义全局过滤器
1.私有过滤器
定义到Vue 实例中的filters 节点下的过滤器都是私有过滤器
2.全局过滤器
语法:
Vue.filter('capitailize',(str) => {
return str.charAt(0).toUpperCase() + str.slice(1) + '~~'
})
参数:
第一个参数:是全局过滤器的'名字'
第二个参数:是全局过滤器的'处理函数'
形参 str 接收 | 前的实参
注意:
如果全局过滤器和私有过滤器名字一致,按照就近原则,调用私有过滤器
3.连续调用多个过滤器
{{ message | filterA | filterB}}
4.为过滤器传递参数
{{ message | filterA(arg1,arg2)}}
Vur.filter('filterA',(msg,arg1,arg2) => {})
注意:
第一个参数永远是“管道符”前面待处理的值
第二个参数开始,才是调用过滤器时传递过来的arg1 和 arg2 参数
六.侦听器
watch 侦听器:监视数据的变化,从而针对数据的变化做特定的操作
语法:
data: { username: '' },
watch: {
// 监听username 的值的变化
// newVal 是“变化之后的新值”,oldVal 是“变化之前的旧值”
username(newVal,oldVal){
console.log(newVal,oldVal)
}
}
侦听器的格式:
1.方法格式的侦听器:
缺点:
1.无法在刚进入页面的时候,自动触发
2.如果侦听的是一个对象,当对象中的属性发生了变化,不会触发侦听器
2.对象格式的侦听器:
好处:
1.可以通过 immediate 选项,在刚进页面的时候,让侦听器自动触发一次
2.可以通过 deep 选项,让侦听器深度监听对象中每个属性的变化
七.计算属性
计算属性指的是通过一系列运算之后,最终得到的一个属性值
这个动态计算出来的属性值可以被模板结构或methods 方法使用
所有的计算属性都要定义到computed 节点之下
特点:
1.计算属性在定义的时候,要定义成“方法格式”
2.在使用计算属性的时候,当普通的属性使用即可
好处:
1.实现了代码复用
2.只要计算属性中依赖的数据源变化了,则计算属性会自动重新求值
八.vue-cli
vue-cli 是Vue.js 开发的标准工具,简化了webpack 创建工程化的Vue 项目的过程
中文官网:https://cli.vuejs.org/zh/
安装:
npm install -g @vue/cli
使用:
1.vue create 项目的名称
2.Manually select features (手动选择要安装的功能)
3.CSS Pre-processors (css 预处理器 less) 不装Linter
4. 2.x
5.Less
6.In dedicated config files (把Babel、Eslint 等插件的配置项,放到自己独立的配置文件中)
7.n (不存已选项)
vue 项目中src 目录的构成:
1.assets 文件夹:存放项目中用到的静态资源文件
例如:css 样式表、图片资源
2.components 文件夹:程序员封装的、可复用的组件,都要放到components 目录下
3.main.js :是项目的入口文件,整个项目的运行,要先执行main.js
4.App.vue :是项目的根组件
vue 项目的运行流程:
通过main.js 把App.js 渲染到index.html 的指定区域中
其中:
1.App.vue 用来编写待渲染的模板结构
2.index.html 中需要预留一个el 区域
3.main.js 把App.vue 渲染到了index.html 所预留的区域中
九.vue 组件
1.什么是组件化开发
组件化开发:根据封装的思想,把页面上可重用的UI解构封装为组件,从而方便项目的开发和维护
(是对UI结构的封装和复用)
2.vue 中的组件化开发
组件的后缀名 .vue
3.vue 组件的三个组成部分
1. template -> 组件的模板结构
2. script -> 组件的JavaScript 行为
3. style -> 组件的样式
4.组件之间的父子关系
如:在App.vue 中使用Left.vue 组件
步骤1.使用import 语法导入需要的组件( @表示src 文件夹 )
import Left from '@/components/Left.vue'
步骤2.使用components 节点注册组件
export default {
components: {
Left
}
}
步骤3.以标签形式使用刚才注册的组件
<div class="box">
<left></left>
</div>
注意:
通过components 注册的是私有子组件
5.注册全局组件:
在vue 项目的main.js 入口文件中,通过vue.components() 方法,可以注册全局组件
示例:
// 导入需要全局注册的组件
import Count from '@/components/Count.vue'
// 参数1:字符串格式,表示是组件的“注册名称”
// 参数2:需要被全局注册的那个组件
Vue.component('MyCount',Count)
6.组件的props
提高组件的复用性
1.props 组件的自定义属性
props 是组件的自定义属性,在封装通用组件时,使用props 可以提高组件的复用性
注意:
props 的自定义属性值是只读的,不能直接修改props 的值
示例:
props:['自定义属性名'],
<MyCount :init="9"></MyCount>
<!-- init="6" 字符串的6 -->
<!-- :init="6" 数值型的6 -->
2.props 中的default 默认值
// 如果外界使用Count 组件的时候,没有传递init 属性,则默认值生效
export default{
props: {
init: {
// 用default 属性定义属性的默认值
default: 0
}
}
}
3.props 的type值类型
在声明自定义属性时,可以通过type 来定义属性的值类型:
示例:
export default{
props: {
init:{
// 用default 属性定义属性的默认值
default: 0,
// 用type 属性定义属性的值类型
// 如果传递过来的值不符合此类型,则会在终端报错
type: Number
// Boolean、Array、String、Object
}
}
}
4.props 的required 必填项校验
props: {
init: {
// 用default 属性定义属性的默认值
default: 0,
// init 的值类型必须是Number 数字
type: Number,
// 必填项校验
required: true
}
},
7.组件之间的样式冲突问题
默认情况下,写在.vue 组件中的样式会全局生效,容易造成组件之间的样式冲突问题
原因:
1.单页面应用程序中,所有组件的DOM 结构,都是基于唯一的index.html 页面呈现的
2.每个组件中的样式,都会影响index.html 页面中的DOM 元素
如何解决样式冲突问题:
<style lang="less" scoped></style>
scoped 属性可以为当前组件添加特有属性,来区分不同的组件
在父组件中修改子组件中的样式:
/deep/ h5{ color:red }
// 当使用第三方组件库的时候,如果有修改第三方组件默认样式的需求,需要用到/deep/
十.组件的生命周期
生命周期:是指一个组件从创建 -> 运行 -> 销毁的整个阶段,强调的是一个时间段
生命周期函数:是由vue 框架提供的内置函数,会伴随着组件的声明周期,自动按次序执行
vue 实例的生命周期 (vue 组件的生命周期)
(1)组件创建阶段:
执行次数:只有1次
new Vue()
beforeCreate
created:
初始化好了props、data、methods
在这个阶段,发起Ajax 请求,去拿数据,组件的模板结构尚未生成,不能操作dom
beforeMount
mounted:
第一次dom 结构渲染好
在这里可以最早去操作dom元素
(2)组件运行阶段:
执行次数:[0,n)
beforeUpdate
updated
(3)组件销毁阶段:
执行次数:只有1次
beforeDestroy
destroyed
webpack -> main.js -> App.vue -> Left.vue Right.vue -> Count.vue
<MyCount></MyCount> 用这个组件 就相当于new 了个vue 实例
十一.组件之间的数据共享
1.组件之间的最常见的关系
父子关系、兄弟关系
2.父组件向子组件共享数据
父组件向子组件共享数据需要使用自定义属性:
示例:
// 父组件
<Son :msg="message" :user="userinfo"></Son>
data(){
return{
message: 'hello vue.js',
userinfo: { name:'zs', age: 20 }
}
}
// 子组件
<template>
<div>
<h5>Son 组件</h5>
<p>父组件传递过来的 msg 的值是: {{ msg }}</p>
<p>父组件传递过来的 user 的值是: {{ user }}</p>
</div>
</template>
props:['msg','user']
3.子组件向父组件传值
子组件向父组件共享数据要使用自定义事件
示例:
// 父组件
<Son @numchange="getNewCount"></Son>
export default{
data(){
return {
countFromSon: 0
}
}
},
methods{
getNewCount(val){
this.countFromSon = val
}
}
// 子组件
export default{
data(){
return{
count: 0
}
},
methods: {
add(){
this.count += 1
// 修改数据时,通过$emit() 触发自定义事件
this.$emit('numchange',this.count)
}
}
}
4.兄弟组件之间的数据共享
在vue2.x 中,兄弟组件之间通过 EventBus 进行数据共享
步骤:
1.创建eventBus.js 模板,向外共享一个Vue 的实例对象
2.在数据发送方,调用bus.$emit('事件名称',要发送的数据) 方法触发自定义事件
3.在数据接收方,调用bus.$on('事件名称',事件处理函数)方法注册一个自定义事件
示例:
// eventBus.js
import Vue from 'vue'
// 向外共享Vue 的实例
export default new Vue()
// 兄弟组件A (数据发送方)
import bus from './eventBus.js'
export default{
data(){
return {
msg: 'hello vue.js'
}
},
methods: {
sendMsg(){
bus.$emit('share',this.msg)
}
}
}
// 兄弟组件B (数据接收方)
import bus from './eventBus.js'
export default{
data(){
return{
msgFromLeft: ''
}
},
created(){
bus.$on('share',val => {
this.msgFromLeft = val
})
}
}
vue 基础总结
1.内容渲染指令:
v-text 缺点: 覆盖元素中的默认内容
{{}} 插值只能在元素的内容节点,无法用在属性节点
v-html 用处:把带有HTML 标签的字符串,渲染为真正的DOM 元素
2.属性绑定指令:
v-bind: 简写为 :
3.事件绑定指令:
v-on: 简写为 @
@click="show" 和 @click="show(参数)"
内置的变量: $event @click="show(3,$event)"
事件修饰符:prevent、stop
按键修饰符:.esc、.enter
4.双向数据绑定指令:
v-model 只能用在表单元素上
修饰符:.number、.trim、.lazy
5.循环渲染指令:
v-for v-for="(item,index) in 数组"
:key="item.id"
拿索引当key 没有意义
6.条件渲染指令:
v-if 动态创建和移除元素
v-else-if
v-else
v-show 动态添加和移除 display: none; 样式
7.过滤器
全局过滤器 Vue.filter('名字',function(过滤器前面的值){
return 结果
})
私有过滤器 定义到组件的filters 节点下
{{ message | dataFormat}}
8.侦听器
watch 方法格式(简单) username(newVal,oldVal){}
对象格式 username: { handler(newVal,oldVal){}, deep:true, immediate:true }
9.计算属性
computed 在定义的时候要定义为function
在使用的时候,当做普通属性使用即可(在template 模板结构中使用、 在methods 方法中使用 this.计算属性的名字)
要return 一个计算的结果
只要任何一个依赖的数据项发生了变化,计算属性就会重新渲染
10.vue-cli
全局安装:npm install @vue/cli -g
创建项目:vue create 项目的名称
组件的构成:template(只能有唯一的节点)
script(export default{} .vue中的data 必须是方法)
style(启用less 语法:lang="less" 防止组件之间样式冲突:scoped, /deep/ 深度选择器在需要覆盖第三方组件样式的时候会用到)
11.自定义属性
props 提高组件的复用性
格式:
数组格式: props:['init']
对虾干格式: props:{ init: { type: Number, default: 0, required: true }}
props 是只读的,因此在项目开发中,不要直接修改它的值
把props 的值转存到data 中,就可以进行读写操作
12.生命周期
概念:每个组件从创建 -> 运行 -> 销毁的整个阶段,强调的是一个时间段
生命周期函数:在生命周期的不同阶段,会按次序依次执行的函数,强调的是时间点
生命周期的三个阶段:
1.创建阶段
beforeCreate
created
发起Ajax最早的时机,请求数据
beforeMount
mounted
组件第一次被渲染到浏览器中
操作DOM 的最早的时机
2.运行阶段
beforeUpdate
updated
能够操作到最新的DOM 元素
3.销毁阶段
beforeDestroy
destroyed
13.组件之间的数据共享
父 -> 子:自定义属性
子组件中:通过props 来定义属性
父组件中:负责把数据,通过v-bind: 绑定给子组件
子 -> 父:自定义事件
子组件中:调用this.$emit() 来触发自定义事件
参数1:字符串格式,表示自定义事件的名称
参数2:值,要发送给父组件的数据
父组件中:通过@ 来绑定自定义事件,并提供一个事件处理函数,通过事件处理函数的形参,接收到子组件传递过来的数据
兄弟组件之间的数据共享:eventBus
数据发送方:
导入eventBus.js: import bus from './eventBus.js'
bus.$emit('要触发的事件的名字',要发送的数据)
EventBus.js 模块:
创建vue 的实例对象: new Vue()
向外导出Vue 的实例对象: export default new Vue()
数据接收方:
导入eventBus.js: import bus from './eventBus.js'
bus.$on('要声明的自定义事件的名字',事件的处理函数)
通过事件处理函数的形参,可以接收到发送过来的数据
在数据接收方的created 生命周期函数中,调用bus.$on() 方法
十二.ref 引用
ref 用来在不依赖于jQuery 的情况下,获取DOM 元素或组件的引用
示例:
<h3 ref="myh1">App 根组件</h3>
<button @click="showThis">打印this</button>
methods: {
showThis(){
// 当前this 是App 组件的实例对象
console.log(this.$refs.myh1);
this.$refs.myh1.style.color="red"
}
}
示例:
<input type="text" v-if="inputVisible" @blur="showButton" ref="iptRef">
<button v-else @click="showInput">展示输入框</button>
showInput(){
this.inputVisible = true // 数据更新
console.log(this.$refs.iptRef);
// 由于数据更新之后无法立即渲染dom
// 此时 this.$refs.iptRef 的值为undefined
},
this.$nextTick(cb) 方法
组件的$nextTick(cb) 方法,会把cb 回调推迟到下一个DOM 更新周期之后执行
示例:
this.$nextTick(() => {
this.$refs.iptRef.focus()
})
十三.购物车案例
一.数组中的方法
1.forEach()
forEach 循环一旦开始,就无法在中间被停止,即从头循环到尾,效率较低
const arr = ['小红','小黄','小绿']
arr.forEach( (item,index) => {
if(item === '小绿'){
console.log(index);
}
})
2.some()
从数组中找元素,用some 比较合适
在找到对应的项之后,可以通过return true 固定的语法,来终止some 循环
const arr = ['小红','小黄','小绿']
arr.some( (item,index) => {
if( item === '小绿'){
console.log(index);
return true
}
})
3.every()
数组中每一项都满足要求,则返回true
const arr = [
{id: 1,name: '西瓜',state: true},
{id: 2,name: '榴莲',state: true},
{id: 3,name: '草莓',state: true},
]
// 判断数组中水果是否全部被选中
const result = arr.every( item => item.state);
console.log(result); // true
4.filter()
// 需求,把购物车数组中已经勾选的水果总价累加起来
const arr = [
{ id: 1, name: '西瓜', state: true , price: 10, count: 1},
{ id: 2, name: '榴莲', state: false , price: 80, count: 2},
{ id: 3, name: '草莓', state: true , price: 20, count: 3},
]
let amt = 0 // 总价
arr.filter(item => item.state).forEach(item => {
amt += item.price * item.count
})
console.log(amt);
5.reduce()
// arr.filter(item => item.state).reduce((累加的结果,当前循环项) => {},初始值)
const arr = [
{ id: 1, name: '西瓜', state: true, price: 10, count: 1 },
{ id: 2, name: '榴莲', state: false, price: 80, count: 2 },
{ id: 3, name: '草莓', state: true, price: 20, count: 3 },
]
const result = arr.filter(item => item.state).reduce((amt,item) => {
return amt += item.price * item.count
},0)
// const result = arr.filter(item => item.state).reduce((amt,item) => amt += item.price * item.count,0)
console.log(result);
二. 安装与使用
npm i axios -S
import axios from 'axios'
1.安装并在App 中导入axios
2.在methods 方法中,定义initCartList 函数请求列表数据
3.在created 生命周期函数中,调用步骤2 封装的initCartList 函数
只要请求回来的数据,在页面渲染期间要用到,必须转存到data 中
三.装包
npm install
npm i
十四.动态组件
1.动态组件
动态组件指的是动态切换组件的显示与隐藏
vue 提供了内置的<component> 组件,专门用来实现动态组件的渲染
语法:
<keep-alive>
<component :is="comName" ></component>
</keep-alive>
data() {
return {
// comName 表示要展示的组件的名字
comName: 'Left'
}
},
注意:
1.component 标签是vue 内置的,作用:组件的占位符
2.is 属性的值,表示要渲染的组件的名字
3.is 属性的值,应该是组件在components 节点下的注册名称
4.<keep-alive> 可以把内部的组件进行缓存,而不是销毁组件
2.keep-alive
keep-alive 对应的生命周期函数
1.当组件被缓存时,会自动触发组件的 deactivated 生命周期函数
2.当组件被激活时,会自动触发组件的 activated 生命周期函数
3.当组件第一次被创建的时候,既会执行created 生命周期,也会执行activated 生命周期
4.当组件被重新激活的时候,只会执行activated 生命周期,不会再触发created ,因为组件没有重新创建
kepp-alive 的include 属性:
<keep-alive include="Left,Right">
<component :is="comName" ></component>
</keep-alive>
kepp-alive 的exclude 属性:
<keep-alive exclude="Right">
<component :is="comName" ></component>
</keep-alive>
注意:
1.keep-alive 可以把内部的组件进行缓存,而不是销毁组件
2.在使用keep-alive 的时候,可以通过include 指定哪些组件需要被缓存
3.或者,通过exclude 属性指定哪些组件不需要被缓存
4.但是,不能同时使用 include 和 exclude 这两个属性
3.组件的名称
如果在声明组件的时候,没有为组件指定name 名称,则组件的名称默认就是注册时候的名称
对比:
1.组件的“注册名称“ 的主要应用场景: 以标签的形式,把注册好的组件渲染和使用到页面结构之中
2.组件声明时候的 "name " 名称的主要应用场景,结合<keep-alive> 标签实现组件缓存功能,
以及在调试工具看到组件的 name 名称
十五.插槽
<template v-slot: default>
<p>Left 组件里面的插槽</p>
</template>
<slot name="default"></slot>
注意:
1.每个slot 插槽都有一个name 属性,来定义插槽名称,不写默认为 name="default"
2.默认情况下,在使用组件的时候,提供的内容都会被填充到名字为default 的插槽中
3.如果要把内容填充到指定名称的插槽中,需要使用v-slot: 这个指令
4.v-slot: 后面要跟上插槽的名字
5.v-slot: 只能用在<template>标签 或者是 组件标签上
6.<template> 标签是一个虚拟的标签,只起到包裹的作用,不会被渲染为html 元素
7.v-slot: 简写是 #
十六.自定义指令
1.私有自定义指令
directives: {
// 定义名为color 的自定义指令 指向一个配置对象
color: {
// 当指令第一次被绑定到元素上的时候,会立即出发bind 函数
// 形参中的el 表示当前指令所绑定到的那个dom 对象
bind(el,binding){
el.style.color = binding.value
},
// dom 更新的时候会触发update
update(el,binding){
el.style.color = binding.value
},
}
}
当color 和 update 中的代码一致时,可以简写为:
directives: {
color(el,binding){
el.style.color = binding.value
}
}
2.全局自定义指令
在main.js 中声明:
Vue.directive('color',function(el,binding){
el.style.color = binding.value
})
一.axios
axios 是专注于数据请求的库
中文官网:http://www.axios-js.com
英文官网:http://www.npmjs.com/package/axios
语法:
axios({
method: '请求的类型',
url: '请求的url 地址',
// URL 中的查询参数
params: {},
// 请求体参数
data: {}
}).then((result) => {
// .then 用来指定请求成功之后的回调函数
// 形参中的 result 是请求成功之后的结果
})
注意:
调用axios 方法得到的返回值是 Promise 对象
如果调用某个方法的返回值是Promise 实例,则前面可以添加await
await 只能用在被async 修饰的方法中
示例:
一、通过axios 发起get 和 post 请求
1.发起GET 请求
document.querySelector('#btnGet').addEventListener('click',async function(){
// 解构赋值的时候,使用: 进行重命名
// 1.调用完axios 之后,使用async/await 进行简化
// 2.使用解构赋值,从axios 封装的大对象中,把data 属性解构出来
// 3.把解构出来的data 属性,使用: 进行重命名,一般都重命名为 { data: res }
const {data: res} = await axios({
method: 'GET',
url: 'http://www.liulongbin.top:3006/api/getbooks',
})
console.log(res);
})
2.发起POST 请求
document.querySelector('#btnPost').addEventListener('click',async function(){
// 如果调用某个方法的返回值是Promise 实例,则前面可以添加await
// await 只能用在被async 修饰的方法中
const { data } = await axios({
method: 'POST',
url: 'http://www.liulongbin.top:3006/api/post',
data: {
name: 'zz',
age: 10
}
})
console.log(data);
})
二、直接使用get 和 post 发起请求
1.发起get 请求
<button id="btnGet">GET</button>
document.querySelector('#btnGet').addEventListener('click',async function(){
const { data: res } = await axios.get('http://www.liulongbin.top:3006/api/getbooks',{
params: { id: 1 }
})
console.log(res.data);
})
2.发起post 请求
<button id="btnPost">POST</button>
document.querySelector('#btnPost').addEventListener('click',async function(){
const { data: res } = await axios.post('http://www.liulongbin.top:3006/api/post',
{name: 'zs',gender: '女'}
)
})
一.vue 组件库:
element-ui
vant
一.Eslint
格式化代码