简介
Vue是前端优秀框架,是一套用于构建用户界面的渐进式框架
模板语法
- 文本
- 原始HTML
- 属性Attribute
想要属性能动态变化,就需要v-bind:
。当然,只是静态属性就没必要使用v-bind
。
v-bind:
可以简写成:
- 条件渲染
v-if
-
v-show
主要用于设置控件的可见性,也就是CSS属性中的display。下图中元素h1不可见,但检查可以看到元素。
注意:v-if
和v-show
都是指令,只作用于元素
- 使用JavaScript表达式
vue中&&
和||
的用法
date{
autoAdd : false,
doJob: false
}
methods:{
xxx(){
// 1.如果autoAdd 为 true真时,则将doJob 设置为true
this.autoAdd && (this.doJob= true);
// 2.如果autoAdd 为 false假时,则将doJob 设置为true
this.autoAdd || (this.doJob= true);
}
}
列表渲染
注意:v-for
和v-if
都可以放置到<template>
中,用于操作多个元素。比如<template>
内层包裹<template>
,内层的<template>
就可以用于上述操作。
- 用
v-for
把一个数组映射为一组元素
- 维护状态
当Vue正在更新使用
v-for
渲染的元素列表时,它默认使用“就地更新”的策略。如果数据项的顺序被改变,Vue将不会移动DOM元素来匹配数据项的顺序,而是就地更新每个元素,并且保证它们在每个索引位置正确渲染。(人话:如果新增了元素,只渲染新增的,原来的不用渲染,节省性能)
实在没有id,传入index也行
注意:当v-for
和v-if
同时存在于一个节点上时,v-if
比v-for
的优先级更高。这意味着v-if
的条件将无法访问到v-for
作用域内定义的变量别名:
<!--
这会抛出一个错误,因为属性 todo 此时
没有在该实例上定义
-->
<li v-for="todo in todos" v-if="!todo.isComplete">
{{ todo.name }}
</li>
在外新包装一层 <template>
再在其上使用 v-for
可以解决这个问题 (这也更加明显易读):
<template v-for="todo in todos">
<li v-if="!todo.isComplete">
{{ todo.name }}
</li>
</template>
事件处理
- 监听事件
我们可以使用v-on
指令(通常缩写为@
符号)来监听DOM事件,并在触发事件时执行一些JavaScript。用法为v-on:click="methodName"
或使用快捷方式@click="methodName"
- 事件处理方法
- 内联处理器中的方法——事件传递参数
事件修饰符
在事件处理程序中调用
event.preventDefault()
或event.stopPropagation()
是非常常见的需求。尽管我们可以在方法中轻易实现这点,但更好的方法是:方法只有纯粹的数据逻辑,而不是去处理Dom事件细节。
<!-- 阻止单击事件继续传播 -->
<a v-on:click.stop="doThis"></a>
<!-- 提交事件不再重载页面 -->
<form v-on:submit.prevent="onSubmit"></form>
<!-- 修饰符可以串联 -->
<a v-on:click.stop.prevent="doThat"></a>
<!-- 只有修饰符 -->
<form v-on:submit.prevent></form>
<!-- 添加事件监听器时使用事件捕获模式 -->
<!-- 即内部元素触发的事件先在此处理,然后才交由内部元素进行处理 -->
<div v-on:click.capture="doThis">...</div>
<!-- 只当在 event.target 是当前元素自身时触发处理函数 -->
<!-- 即事件不是从内部元素触发的 -->
<div v-on:click.self="doThat">...</div>
<!-- 点击事件将只会触发一次 -->
<a v-on:click.once="doThis"></a>
注意:使用修饰符时,顺序很重要;相应的代码会以同样的顺序产生。因此,用@click.prevent.self
会阻止所有点击,而@click.self.prevent
只会阻止元素自身的点击
Vue 还对应 addEventListener
中的 passive
选项提供了 .passive
修饰符。
<!-- 滚动事件的默认行为 (即滚动行为) 将会立即触发 -->
<!-- 而不会等待 `onScroll` 完成 -->
<!-- 这其中包含 `event.preventDefault()` 的情况 -->
<div v-on:scroll.passive="onScroll">...</div>
注意:不要把 .passive
和 .prevent
一起使用,因为.prevent
将会被忽略,同时浏览器可能会向你展示一个警告。请记住,.passive
会告诉浏览器你不想阻止事件的默认行为。
表单输入绑定
你可以使用v-model
指令在表单<input>
,<textarea>
,<select>
元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。尽管有些神奇,但v-model
本质上不过是语法糖。它负责监听用户的输入事件来更新数据,并在某种极端场景下进行一些特殊处理。
- 修饰符
.lazy
,.trim
Vue生命周期
- beforeCreate
实例创建之前,在数据观测,初始化事件还未开始 - created
实例创建完成,完成数据观测,属性和方法的运算,初始化事件,此时$el还没显示出来,可以访问到data,computed,methods,watch - beforeMount
在挂载之前被调用,相关的render函数首次被调用。编译模板,把data里面的数据和模板生成html,还没有挂载到Dom上 - mounted
el被新创建的vm.$el
替换,并挂载到实例上后调用。实例挂载到Dom上,此时可以通过Dom的api获取dom节点,$el可以被访问 - beforeUpdate
相应数据更新时调用,发生在虚拟dom打补丁之前 - updated
虚拟dom重新渲染或者打补丁之后调用,dom已经更新,可以进行依赖于dom的操作 - beforeDestroy
实例销毁之前调用,此时组件完全可用,可以通过this获取实例 - destroyed
实例销毁后调用
计算属性与watch
模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的。对于任何复杂逻辑,你应当使用计算属性
computed
。
- 计算属性一般有两方面用途:
1、 Vuex(见后面)
2、 复杂逻辑运算
以下皆是来自官方的例子:
- 计算属性的优点:
1、 可以像绑定普通property一样在模板中绑定计算属性(上述例子中Vue 知道 vm.reversedMessage 依赖于 vm.message,因此当 vm.message 发生改变时,所有依赖 vm.reversedMessage 的绑定也会更新。)
2、 计算属性是基于它们的响应式以来进行缓存的。即如果绑定的依赖没变,方法不会被再次执行。
3、 计算属性 vs 监听属性:Vue提供了一种更通用的方式来观察和响应Vue实例上的数据变动:监听属性。当你有一些数据需要随着其他数据变动而变动时,你很容易滥用watch
,然而通常更好的做法是使用计算属性而不是命令式的watch
回调。
-
watch
的作用:
当需要在数据变化时执行异步或开销大的操作,watch
是最常用的。
Class与Style绑定
-
绑定HTML Class
- 绑定内联样式
Vue中的常用属性
- $refs
一般来说,获取DOM元素,需要使用
document.querySelector('#input1')
方法去获取dom节点,然后再获取input1的值。
但是使用了ref绑定之后,我们就不需要再获取dom节点了,可以直接在上面的input上绑定input1,然后$refs
里面调用就行。
在JS里面通过this.$refs.input1
去调用,这样的做法实际上是访问VUE虚拟出来的DOM,可以有效减少获取/操作DOM节点的性能消耗。
这里的$refs
可以看作是ref
的选择器,这个$refs
是对象,通过key可以获取到其中存放的对象。
当然了,既然是对象,也可以使用方括号运算符去访问,具体是this.$refs[input1]
组件基础
- scoped:如果在style中添加此属性,就代表着当前样式只在当前组件中生效
Props组件交互
Prop
是你可以在组件上注册的一些自定义attribute
如果是数组
注意:数据类型为数组或者对象的时候,默认值是需要返回工厂模式(用函数进行返回)
自定义事件组件交互
- 将上述传递过程反向,从component中传递数据给App.vue
Vue引入第三方
- swiper
1、 开源、免费、强大的触摸滑动插件(轮播图)
2、 纯JavaScript打造的滑动特效插件,面向手机、平板电脑等移动终端
3、 能实现触屏焦点、触屏Tab切换、触屏轮播图切换等效果
官方文档:https://swiperjs.com/vue
npm install --save swiper:安装swiper插件,如果需要指定版本最后改为swiper@8.1.6
注意:以下适用版本是swiper8.1.6
- 添加指示器
Axios网络请求
Axios是基于promise的网络请求
- 安装
Axios的应用是需要单独安装的npm install --save axios
- 引入
组件中引入:import axios from "axios"
全局引用:
在main.js中
mounted()
:主控件已经渲染完成调用,可以理解为Android中的onCreated()
post请求参数需要querystring进行转换,直接npm install --save querystring安装就行
全局引用时:
Axios请求封装
一般项目中的网络请求会很多,此时一般采取的方案是将网络请求封装起来
在src
目录下创建文件utils
,并创建文件request
,用来存储网络请求对象axios
提供接口
网络请求跨域解决方案
JS采用的是同源策略
同源策略是浏览器的一项安全策略,浏览器只允许JS代码请求和当前服务器所在域名、端口、协议相同的数据接口上的数据,这就是同源策略。
也就是说,当协议、域名、端口任意一个不相同时,都会产生跨域问题,所以应该如何解决跨域问题呢
- 跨域错误提示信息
提示:解决完跨域配置后,需要重启服务器
Vue引入路由配置
熟悉Android开发的都知道,路由负责跨组件页面之间的跳转
在Vue中,我们可以通过vue-router
路由管理页面之间的关系
Vue Rounter是Vue.js的官方路由。它与Vue.js核心深度集成,让用Vue.js构建单页应用变得轻而易举
- 在Vue中引入路由
安装Router的第一种:在创建项目时选择Router选项,自动帮我们引入
第二种:
1、 安装路由npm install --save vue-router
2、 配置独立的路由文件 创建router文件->index.js
createWebHashHistory
与createWebHistory
:
异步加载方式:跳转时才加载,节约资源,性能更优
3、 引入路由到项目
4、 指定路由显示入口<router-view>
5、 指定路由跳转
路由传递参数
嵌套路由配置
即导航下还有二级导航
注意:二级目录的path不要加/
设置默认加载页面->重定向
Vue状态管理(Vuex)
Vuex是一个专为Vue.js应用程序开发的状态管理模式 + 库。它采用集中式存储管理应用的所有组件的状态并以相应的规则保证以一种可预测的方式发生变化。
简单来说,状态管理可以理解为更方便的管理组件之间的数据交互,提供了一个集中式的管理方案,任何组件都可以按照指定的方式进行读取和改变数据
个人理解:类似于Android中的Application,所有模块共享数据
- 引入Vuex的步骤(和Router一样可以一步到位,创建项目时就选择Vuex)
1、 安装Vuexnpm install --save vuex
2、 配置Vuex文件
3、 在主文件中引入Vuex
4、 在组件中读取状态
另一种读取方式
Vue状态管理核心(Vuex)
最常用的核心概念包括:State
(上一章已讲)、Getter
、Mutation
、Action
- Getter
对Vuex中的数据进行过滤
也是两种读取方式:
- Mutation
更改Vuex的store中的状态的唯一方法是提交mutation。Vuex中的mutation非常类似于事件:每个mutation都有一个字符串的事件类型(type)和一个回调函数(handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受state作为第一个参数。
注意:...mapMutations
添加的位置是在methods:
中
-
Action
Action类似于Mutation,不同在于:
1、 Action提交的是mutation,而不是直接变更状态
2、 Action可以包含任意异步操作(即Action存在的意义就是异步操作)
使用方式相同
Vue3的新特性1
- ref或者reactive(一般用于对象类型)
在2.x中通过组件data的方法来定义一些当前组件的数据
值得一提的是ref可以持有任何类型的值,包括深层嵌套的对象、数组或者JavaScript内置的数据结构,比如Map
。
ref会使它的值具有深层响应性。这意味着即使改变改变嵌套对象或者数组时,变化也会被检测到:
import { ref } from 'vue'
const obj = ref({
nested: { count: 0 },
arr: ['foo', 'bar']
})
function mutateDeeply() {
// 以下都会按照期望工作
obj.value.nested.count++
obj.value.arr.push('baz')
}
非原始值将通过reactive()
转换为响应式代理。
- reactive的局限性
由于这些限制,建议使用 ref() 作为声明响应式状态的主要 API。
- methods中定义的方法写在setup()
- setup()中使用props和context
在2.x中,组件的方法中可以通过this获取到当前组件的实例,并执行data变量的修改,方法的调用,组件的通信等等,但是在3.x中,setup()在beforeCreate和created时机就已调用,无法使用和2.x一样的this,但是可以通过接收setup(props,ctx)的方法,获取到当前组件的实例和props
- 在setup()中使用生命周期函数
你可以通过在生命周期钩子前面加上“on”来访问组件的生命周期钩子。
下表包含如何在setup()内部调用生命周期钩子
- Provide/Inject
1、 provide()和inject()可以实现嵌套组件之间的数据传递。
2、 这两个函数只能在setup()函数中使用。
3、 父级组件中使用provide()函数向下传递数据。
4、 子级组件中使用inject()获取上层传递过来的数据。
5、 不限层级
- Fragment
vue3.x之前要求必须存在一个根节点,比如div
Vue3加载Element-plus
- 控件
1、 安装element-plus
npm install --save element-plus
完全引用
按需导入
一些控件需要声明变量来使用,比如开关类按钮需要Boolean类型值
- 字体图标
Elements-plus
不仅仅是提供了各种组件,同时还提供了一整套的字体图标方便开发者使用
1、 安装icons
字体图标
npm install @element-plus/icons-vue
2、 全局注册
3、 引入文件
4、 使用方式
更多的使用参考文档:element-plus