vue是一个用于 构建用户界面 的 渐进式 框架。
1.vue指令
v-前缀,Vue会根据不同的指令实现不同的功能
-
v-html:设置元素的innerHTML
-
v-if和v-show:控制元素显示隐藏
区别:v-show是控制display:none来实现显示隐藏的,适合频繁切换显示隐藏的场景
-
v-if是创建/删除DOM元素来实现显示隐藏的,适合初始状态就确定显示隐藏的场景
-
v-else和v-else-if:v-if的多分支结构,v-else必须紧贴着v-if或v-else-if,中间不能间隔其他元素,注释除外
-
v-on(简写 @):绑定事件
内联语句
绑定事件处理函数
-
v-bind(简写 :):动态设置HTML属性
-
v-for:
循环渲染标签元素 v-for="(item, index) in list"
key属性:唯一标识 :key="item.id"
-
v-model:主要用于表单元素的双向数据绑定 v-model="vue 变量"
2.指令修饰符
-
按键修饰符:
键盘事件 @keyup @keydown
.enter表示按下enter键
<input @keyup.enter="login" v-model="username" type="text"> methods:{ login() {} } -
v-model修饰符:
<input v-model.trim ="username" type="text"> <input v-model.number ="username" type="text"> -
事件修饰符:
@事件名.stop 阻止冒泡
@事件名.prevent 阻止默认行为
3.动态class
-
设置对象:是否应用该类名
:class="{class1:true/false}" -
设置数组:一次性设置多个类名
:class="[class1,class2]"
4.动态style
:style="{css属性名:css属性值}"
5.v-model用于其他表单元素
文本框:value
复选框:绑定数据是boolean--checked,绑定的数据是数组--将value添加到数组
单选框:value
下拉框:value
文本域:value
6.computed计算属性
依赖现有数据进行计算得出结果,必须同步计算结果,因为计算属性必须要有返回值
特性:带缓存,在第一次使用该属性时进行计算,计算后将结果缓存起来,后面如果还有其他地方用到,会直接从缓存中取值,不会再次计算。如果依赖的数据更新,也会重新计算,然后重复上述操作。
简单写法:
computed:{
计算属性名(){
一段代码逻辑(计算逻辑)
return 结果
}
}
完整写法:
computed:{
计算属性名: {
//get方法就是简单写法的函数
get() {
一段代码逻辑(计算逻辑)
return 结果
},
//设置,当修改这个计算属性时,set函数会自动执行,并将新值作为参数传递过来
set(修改的值) {
一段代码逻辑(修改逻辑)
}
}
}
7.watch侦听器
监视数据变化,执行一些 业务逻辑 或 异步操作
简单写法:
-
监视数据:
watch:{ 数据名(newValue,oldValue) { //函数会在数据被修改自动执行 } -
监视对象的属性:
watch:{ 'obj.属性名'(newValue,oldValue) { //函数会在数据被修改自动执行 }
完整写法:
watch: {
对象名: {
deep:true,//开启深度侦听
immediate:true,//立即执行一次
handler(newValue,oldValue){
//函数会在数据被修改自动执行
}
}
}
8.生命周期
-
概念:Vue实例从创建到销毁的过程
-
钩子函数:
(1)创建:
beforeCreat
created:发请求,初始化渲染
(2)挂载:
beforeMount
mounted:操作DOM
(3)更新:
beforeUpdate
updated
(4)销毁:
beforeDestory
destoryed
9.工程化开发
-
脚手架
重要文件:
main.js:引入App.vue,基于App.vue创建元素,将元素挂载到#app盒子中
App.vue:根组件
index.html:项目唯一网页
-
组件化:便于复用和维护
组件的使用:
局部注册:
创建组件:创建一个.vue文件
引入组件:import 变量名 from ‘路径’
注册组件:compontents:{ 组件名:组件对象 }
使用组件:<组件名></组件名>
全局注册
创建组件:创建一个.vue文件
引入组件:import 变量名 from ‘路径’
注册组件:在main.js中 Vue.compontents('组件名':组件对象)
使用组件:<组件名></组件名>
10.组件通信
props和emit
11.v-model原理
v-model 可以实现数据的双向绑定,它的本质是一个语法糖,也就是v-bind和v-on的结合使用,v-bind负责将数据传递给表单控件,而v-on则监听控件的输入事件,以确保数据可以实时反映在Vue实例上。
-
v-model局限性:
据名必须叫value
2.事件名必须叫input 3.一个标签只能使用一次v-model -
解决v-model的局限性
使用.sync修饰符 本质就是:属性名和@update:属性名的合写
12.组件封装使用
Element-ui: 组件 | Element
$ref.name 获取名为name的dom元素
$nextTick 是将回调函数延迟在下一次dom更新数据后调用,简单的理解是:当数据更新了,在dom中渲染后,自动执行该函数
13.自定义指令
(自定义指令也是一种封装思想的体现,将一段DOM操作封装到自定义指令中)
- bind:指令第一次绑定到元素时,仅执行一次;
- inserted:指令绑定元素并插入到父节点时,执行一次;
- update:指令所在的组件更新时,可能会执行多次;
- componentUpdated:指令所在的组件和它的子组件更新时,可能会执行多次;
- unbind:指令和元素解绑时,仅执行一次。
-
全局注册
语法:
Vue.directive('指令名',{ inserted(el) { el.focus() } }) -
局部注册
directives: { color: { //inserted 会在元素插入到 DOM 时执行 //1.参数1,指定绑定的元素对象 //2.参数2,指令相关的值 inserted(el, binding) { el.style.color = binding.value } } }
14.插槽
当组件内某一部分结构不确定,需要自定义时使用插槽技术。
-
默认插槽使用方法:
- 在子组件使用slot标签占位
- 在使用组件时,传入具体标签内容插入
-
插槽的默认值:默认值(后备内容)
. 具名插槽 :
- slot占位,给name属性起名字来区分
- template配合v-slot:插槽名 分发内容
v-slot:name <====> #name
-
作用域插槽:
作用:可以给插槽上绑定数据,供将来使用组件时使用
步骤:
- 给slot标签,以添加属性的方式传值
- 所有属性都会被收集到一个对象中
- template中,通过‘#插槽名=“obj”’接受
15.路由
概念:
-
单页应用程序--SPA(Single Page Application):将所有功能在一个HTML页面中实现 (1)优点:性能高,用户体验好,开发效率高
(2)缺点:首页加载慢,学习成本高,不利于SEO
-
路由:路径和组件的映射关系
16.声明式导航
router-link本质是a标签
作用:
- 可以实现跳转并自动添加#
- 实现导航高亮,会自动添加类名
导航高亮:
- router-link-active 模糊匹配
- router-link-exact-active 精确匹配
自定义高亮类名:在创建VueRouter对象时传入配置
- linkActiveClass
- linkExactActiveClass
*传参:
-
query传参
<router-link to="/路径?参数名1=参数值1&参数名2=参数值2"></router-link>接收
$route.query.参数名 -
动态路由传参(配置路由参数)
{ path:'/路径/:参数名', component: 组件对象 }<router-link to="/路径/参数值"></router-link>接收
$route.params.参数名
重定向:{ path: '/', redirect: '/home' }
404页面:{ path: '*', component: 组件对象 }
路由模式(在创建VueRouter对象时传入配置):
- hash:默认模式,路径有#
- history:路径没有#,但需要后端支持
17.编程式导航
使用js进行路由跳转
-
path跳转语法:
this.$router.push('路径') this.$router.push({path:'路径'})
-
name跳转语法:
先给路由加上name:'name',再
this.$router.push({ name:'name' })
路由传参:
-
path
(1) path + query 传参
(手动拼接)
this.$router.push('路径?参数名=参数值')(官方的API传参)
this.$router.push({ path:'/path', query:{ 参数名=参数值 } })使用
this.$route.query.参数名接收(2) path + 动态路由传参(先配置路由参数)
this.$router.push(`/path/${this.words}`)使用
this.$route.params.参数名接收 -
name(需要提前配置name)
(1) name + query 传参
(手动拼接)
this.$router.push('路径?参数名=参数值')(官方的API传参)
this.$router.push({ name:'name', query:{ 参数名=参数值 } })使用
this.$route.query.参数名接收(2) name + 动态路由传参(先配置路由参数)
this.$router.push({ name:'name', params:{ 参数名=参数值 } })使用
this.$route.params.参数名接收
18.Vuex
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
-
核心成员1: state
作用: 存放数据
-
data 是组件内的数据
-
state 是 Vuex 的数据, 供所有组件访问
访问方式: 方式1: 直接访问 store 对象 1.1 组件内: this.$store.state.count 1.2 非组件内: 先引入当前的 store 对象, store.state.count 方式2: 使用辅助函数 mapState 2.1 按需导入 mapState 2.2 调用 mapState 传入想映射的数据, 在 computed 中展开结果
const store = new Vuex.Store({ strict: true,//严格模式 state: { count: 100, title: '大标题', list: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] }, -
-
核心成员2: mutations
作用: 唯一操作 state 的途径,不能操作异步任务
用法: mutations 就是一个对象, 里面可以定义很多函数, 在函数内操作 state
- 定义 mutations 函数
- 在组件中使用 this.$store.commit('函数名',变量)
mutations: { // 所有的 mutations 函数第一个参数永远都是 state // 第二个参数永远都是 payload (载荷), commit 提交时携带的参数 // mutations 的函数只有这两个参数, 如果需要携带多个参数怎么办? 传对象或数组 addCount (state, n) { state.count += n }, setCount (state, count) { state.count = count } }, -
核心成员3: actions
作用: 专做异步任务,主要用于响应组件中的动作,通过commit()来触发mutation中函数的调用,间接更新state,不是必须存在的。
在组件中使用 this.$store.dispatch('函数名',变量)
actions: { // actions 函数的第一个参数永远都是 context 对象, 简化版的 store 对象, 它里面也有 commit 方法 // 同样也有载荷 payload, 用法同 mutations setCountAsync (context, n) { setTimeout(() => { context.commit('setCount', n) }, 2000) } },
-
核心成员4: getters
作用: Vuex 里的计算属性, 供所有组件访问的计算属性
getters: { // 所有的 getters 第一个参数永远都是 state // 必须要有返回值 filterList (state) { return state.list.filter(item => item > 5) } }
19.核心成员5: modules
-
为什么要使用modules ?
*答:Vuex 是单一状态树,所有的数据都会存在一个 state 中,将来项目业务越来越多,store 的内容会越来越重,导致无法维护,所以最好的办法就是按照业务拆分成不同的模块来分别维护管理,每个模块都有自己的 state/mutations/actions/getters。
*1.建子模块的文件,默认导出一个对象,对象中需要具备 state/mutations/actions/getters 成员 *2.在 store/index.js 中使用 modules:{ 模块名:模块对象 } 注册子模块 *问题:默认情况下子模块所有 mutations/actions/getters 中的函数都挂载到全局,依然没有起到隔离的作用 *解决:开启命名空间namespaced:true *开启命名空间后,四个核心成员的使用方式发生了变化:
-
state
-
直接访问(不方便):this.$store.state.user.userInfo.name
-
辅助函数(推荐):
按需引入辅助函数 import { mapstate } from 'vuex' 在 computed 中调用并展开结果 ...mapstate('模块名',['要映射的数据’])
-
-
mutations
-
直接调用:this.$store.commit('模块名/函数名')
-
辅助函数
按需引入辅助函数 import { mapMutations } from 'vuex 在 methods 中调用并展开结果 ...mapMutations('模块名',['要映射的函数'])
-
-
actions
-
直接调用:this.$store.dispatch('模块名/函数名')
-
辅助函数
按需引入辅助函数 import { mapActions } from 'vuex 在 methods 中调用并展开结果 ...mapActions('模块名',['要映射的函数’])
-
-
getters
-
直接访间(不方便):this.$store.getters['模块名/getter名']
-
辅助函数(推荐):
按需引入辅助函数 import { mapGetters } from 'vuex
在 computed 中调用并展开结果...mapGetters('模块名',['要映射的数据'])
-