复盘学习 2024

vue2+vue3

2024/3/21

v-model的三种修饰符:

lazy

lazy 修饰符:使模型绑定的数据只有在失去焦点或者是按下回车时才会更新

<input type="text" id="inp" v-model.lazy="message">
numer 

number 修饰符: 使输入框中输入的内容自动转换为数字类型

  <input type="text" name="" id="age" v-model.number="age">
trim 

trim 修饰符:

1.只去除两端空格

<el-input v-model.trim = "data"><el-input>

2.只要有空格就去除

<el-input v-model.trim = "data" @keyup.native="trim('data')"><el-input>
trim(v) {
      this[v] = this[v].replace(/\s+/g, '')
    },

或者

<el-input v-model = "data" oninput="value = value.replace(/\s/g, '')"><el-input>

v-on修饰符:prevent 、stop 

prevent:阻止a标签的默认行为  stop:阻止事件冒泡

<a href="https://www.baidu.com" @click.prevent.stop="fn">百度</a>

按键修饰符keyup、keydown

@keyup.enter  监听回车键

@keyup.esc   监听返回键

<input type="text" @keyup.enter="fn"><button>发送</button>

Tip:一般用keyup事件而不用keydown事件,因为keyup事件只触发一次,如果按住键盘不松开keydown事件就会一直触发

v-for中的key值

简单来说key是给每一个vnode的唯一id,同时也是diff的一种优化策略,可以根据key,更准确, 更快的找到对应的vnode节点

<div v-for="(item, index) in list" :key="index" >{{item.name}}</div>

2024/3/22

computed 计算属性 vs methods 方法

 计算属性完整写法

计算属性默认的简写,只能读取访问, 不能 "修改"
如果要 "修改" → 需要写计算属性的 完整写法
computed: {
    计算属性名: {
    get() {
        //一段代码逻辑(计算逻辑)
        return 结果
    },
    set(修改的值) {
        //一段代码逻辑(修改逻辑)
    }
  }
}

watch侦听器语法

简单写法
watch:{
    数据属性名(newValue,oldValue){
        一些业务逻辑或异步操作
    }
    '对象.属性名'(newValue,oldValue){
        一些业务逻辑或异步操作
    }
}

vue中watch监听对象中某个属性

例子:通过input输入框触发watch

<input v-model="currentParams.selOrgId" />
 
data(){
    return {
        currentParams: {
            selOrgId: '1',//声明不声明都可以触发watch
        },
    }
},
 
watch: {
     //使用 ''
    'currentParams.selOrgId': (newV, oldV) => {
        console.log("watch", newV, oldV)
    },
},
完整写法

添加配置项

  1. deep:true  对复杂类型深度监听
  2. immediate:true  初始化立刻执行一次handler方法
watch: {
           obj: {
                  deep: true, //深度监听
                  immediate: true, //立刻执行
                  handler(newValue) {
                  console.log('被修改了', newValue);
                 }
           }
                
      }

 防抖

延迟执行,一段时间内没有再次执行,才触发,触发了相当于重新计时

        clearTimeout(this.timer)
        this.timer = setTimeout(async() => {
            const res = await axios({
                url: '',
                params: {
                    words: newValue
                     }
                        })
                this.res = res.data.data
        }, 300);

reduce累加统计

 let total = this.list.reduce((sum, item) => sum + item.num, 0)

every判断全选

this.fruitList.every(item => item.isChecked)

2024/3/23

Vue生命周期

四个阶段:①创建  ②挂载  ③更新  ④销毁

 input初始化获取焦点

<input autofocus type="text" v-model="words" id="inp">

在vue中使用 

 document.querySelector('#inp').focus()

脚手架CLI

使用步骤
1. 全局安装 (一次) : yarn global add @vue/cli npm i @vue/cli -g
2. 查看 Vue 版本: vue --version
3. 创建项目架子: vue create project-name (项目名-不能用中文)
4. 启动项目: yarn serve npm run serve (找package.json)
脚手架目录文件介绍

main.js核心代码

让组件支持less

①style 标签, lang="less" 开启 less 功能
②装包 : yarn add less less-loader

组件注册使用

普通组件注册的两种方式
1.局部注册

①创建.vue文件(三个部分组成:结构 样式 行为)

②在使用的组件内导入,并局部注册 components:{组件名:组件对象}

2.全局注册

所有组件内部都能使用

①创建.vue文件

②main.js内导入,并进行全局注册 Vue.component(组件名,组件对象)

vscode配置trigger on tab

设置中搜索trigger on tab 并勾选

vscode所有都折叠

ctrl+k,ctrl+0

vscode所有都展开

ctrl+k,ctrl+j

2024/3/25

scoped解决组件的样式冲突

<style scoped>
/* 加上scoped属性的style样式,指挥作用于当前组件->局部样式 */ 
/* 
    默认情况:写在组件中的样式会 全局生效 → 因此很容易造成多个组件之间的样式冲突问题。
    1. 全局样式: 默认组件中的样式会作用到全局
    2. 局部样式: 可以给组件加上 scoped 属性, 可以让样式只作用于当前组件
  -----------------------------------------------------
  scoped原理:
  1. 当前组件内标签都被添加 data-v-hash值 的属性
  2. css选择器都被添加 [data-v-hash值] 的属性选择器
  最终效果: 必须是当前组件的元素, 才会有这个自定义属性, 才会被这个样式作用到
*/
</style>

组件通信

 两种组件关系分类 和 对应的组件通信方案
父子关系 → props & $emit

非父子关系 → provide & inject 或 eventbus

eventbus具体用法 :(是一个一对多的关系)

provide&inject具体用法 :(数据类型推荐使用复杂类型)

通用方案 → vuex

 使用步骤:

state状态

提供数据

// 创建仓库
const store = new Vuex.Store({
    // state 状态, 即数据, 类似于vue组件中的data
    // 区别:
    // 1. data 是组件自己的数据
    // 2. state 是所有组件共享的数据
    state: {
        count: 101
    }
})

 访问数据

模板中: {{ $store.state.xxx }}
组件逻辑中: this.$store.state.xxx
JS模块中: store.state.xxx
辅助函数 mapState
mapState是辅助函数,通过辅助函数(简化) , 帮助我们把 store中的数据 自动 映射到 组件的计算属性中

mutations
明确 vuex 同样遵循 单向数据流 组件中不能直接修改仓库的数据
通过 strict: true 可以开启严格模式
state数据的修改只能通过 mutations
基本语法

mutations传参语法

注意:提交的参数只能是一个, 如果有多个参数要传, 可以传递一个对象

mutations: {
    ...
    addCount (state, obj) {
        state.count += obj.count
    }
},
this.$store.commit('addCount', {
  count: 10
})
辅助函数 mapMutations
目标:掌握辅助函数 mapMutations,映射方法
mapMutations 和 mapState很像,它是把位于 mutations中的方法 提取了出来,映射到 组件methods

actions 
目标:明确 actions 的基本语法,处理异步操作。
说明: mutations 必须是同步的 (便于监测数据变化,记录调试)
需求: 一秒钟之后, 修改 state 的 count 成 666。

辅助函数 - mapActions
目标:掌握辅助函数 mapActions,映射方法
mapActions 是把位于 actions中的方法 提取了出来,映射到 组件methods

核心概念 - getters
说明:除了state之外,有时我们还需要从state中 派生出一些状态 ,这些状态是依赖state的,此时会用到getters
目标:掌握核心概念 getters 的基本语法 ( 类似于计算属性 )
例如:state中定义了list,为 1-10 的数组,组件中,需要显示所有大于5的数据
辅助函数 mapGetters
模块 module (进阶语法) 
由于 vuex 使用 单一状态树 ,应用的所有状态 会集中到一个比较大的对象 。当应用变得非常复杂时,
store 对象就有可能变得相当臃肿。(当项目变得越来越大的时候,Vuex会变得越来越难以维护)
 访问模块中的state 

 访问模块中的getters

访问模块中 mutation
目标:掌握模块中 mutation 的调用语法
注意:默认模块中的 mutation 和 actions 会被挂载到全局, 需要开启命名空间 ,才会挂载到子模块。

props校验

作用:为组件的 prop 指定验证要求,不符合要求,控制台就会有错误提示 → 帮助开发者,快速发现错误

①基础写法
props: {
校验的属性名: 类型 // Number String Boolean ...
},
②完整写法

对数据的类型、非空、默认值、自定义校验

props: {
校验的属性名: {
type: 类型, // Number String Boolean ...
required: true, // 是否必填
default: 默认值, // 默认值
validator (value) {
// 自定义校验逻辑
return 是否通过校验
}
}
},

console.error

向 Web 控制台输出一条错误消息。

 prop&data 

共同点:都可以给组件提供数据。
区别:
data 的数据是 自己 的 → 随便改
prop 的数据是 外部 的 → 不能直接改,要遵循 单向数据流

v-model原理

原理: v-model本质上是一个 语法糖 。例如应用在 输入框上,就是 value属性 input事件 的合写。
<template>
  <div class="app">
    <input v-model="msg1" type="text" />
    <br />
    <!-- v-model的底层其实就是:value和 @input的简写 -->
    <input :value="msg2" @input="msg2=$event.target.value" type="text" >
  </div>
</template>

表单类组件封装

通过v-model简化

.sync修饰符

作用: 可以实现 子组件 父组件数据 双向绑定 ,简化代码
特点: prop属性名,可以 自定义 ,非固定为 value
场景: 封装弹框类的基础组件, visible属性 true显示 false隐藏
本质: 就是 :属性名 @update:属性名 合写

ref和$refs 

作用: 利用 ref 和 $refs 可以用于 获取 dom 元素, 组件实例
特点: 查找范围 → 当前组件内 (更精确稳定)
①获取dom
<template>
  <!-- 1. 目标标签 – 添加 ref 属性 -->
  <div ref="mychart" class="base-chart-box">子组件</div>
</template>

<script>
export default {
  mounted() {
    // 2. 获取dom 通过 this.$refs.xxx, 获取目标标签
    console.log(this.$refs.mychart);
  },
};
</script>

②获取组件

<template>
  <div class="app">
    <!-- 1. 目标组件 – 添加 ref 属性 -->
    <BaseForm ref="baseForm"></BaseForm>
    <button @click="handleGet">获取数据</button>
    <button @click="handleReset">重置</button>
  </div>
</template>

<script>
import BaseForm from './components/BaseForm.vue'
export default {
  components: {
    BaseForm,
  },
  methods: {
   handleGet(){
  //  2. 通过 this.$refs.xxx, 获取目标组件,就可以调用组件对象里面的方法
   this.$refs.baseForm.getFormData()
   },
   handleReset(){
   this.$refs.baseForm.resetFormData()
   }
  }
}
</script>

Vue异步更新、$nextTick

$nextTick: 等 DOM 更新后 , 才会触发执行此方法里的函数体
语法: this.$nextTick(函数体)
this.$nextTick(() => {
        this.$refs.inp.focus()
      });

2023/3/26

自定义指令

自定义指令:自己定义的指令, 可以 封装一些 dom 操作 , 扩展额外功能
全局注册

在多个组件内使用

Vue.directive('指令名', {
    "inserted" (el) {
        // 可以对 el 标签,扩展额外功能
        el.focus()
    }
})
局部注册
只在当前内部组件使用
directives: {
    "指令名": {
        inserted () {
        // 可以对 el 标签,扩展额外功能
        el.focus()
        }
    }
}
指令的值(传值)
指令值的语法:
① v-指令名 = "指令值" ,通过 等号 可以绑定指令的值
<div v-color="color">我是内容</div>
② 通过 binding.value 可以拿到指令的值
③ 通过 update 钩子 ,可以监听指令值的变化,进行dom更新操作
注意:自定义指令数据变化后,视图不会自动更新
directives: {
    color: {
      //1. inserted 提供的是元素被添加到页面中时的逻辑
      inserted(el, binding) {
        el.style.color = binding.value;
      },
      // 2.update 指令的值修改的时候触发,提供值变化后,dom更新的逻辑
      update(el,binding) {
      // 指令的值修改了
      el.style.color=binding.value
      },
    },
  },
封装v-loading指令
场景:实际开发过程中,发送 请求需要时间 ,在请求的数据未回来时,页面会处于 空白状态 => 用户体验不好
(1) 准备类名 loading,通过伪元素提供遮罩层
/* 伪类 - 蒙层效果 */
.loading:before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  background: #fff url("./loading.gif") no-repeat center;
}

(2) 添加或移除类名,实现loading蒙层的添加移除

directives: {
//inserted 钩子中,binding.value 判断指令的值,设置默认状态
//update 钩子中,binding.value 判断指令的值,更新类名状态
    loading: {
      inserted(el, binding) {
        binding.value
          ? el.classList.add("loading")
          : el.classList.remove("loading");
      },
      update(el, binding) {
       binding.value
          ? el.classList.add("loading")
          : el.classList.remove("loading");
      },
    },
  },

(3) 利用指令语法,封装 v-loading 通用指令

<div class="box" v-loading="isLoading">

</div>

插槽

作用:让组件内部的一些 结构 支持 自定义

默认插槽
1. 先在组件内用 slot 占位
2. 使用组件时, 传入具体标签内容插入
插槽-后备内容 

给插槽设置 默认显示内容

具名插槽
需求:一个组件内有多处结构,需要外部传入标签,进行定制

作用域插槽 

是插槽的一个传参语法,定义 slot 插槽的同时, 是可以传值的。

作用:给 插槽 上可以 绑定数据,将来 使用组件时可以用

使用步骤:

(1) 给 slot 标签, 以 添加属性的方式传值
<slot :row="item" msg="测试文本"></slot>
(2)所有属性都会被收集到一个对象中
{
    "row": {
        "id": 1,
        "name": "张小花",
        "age": 18
    },
    msg: "测试文本"
},
(3) template中, 通过 ` #插槽名= "obj" ` 接收
<template>
  <div>
    <MyTable :data="list">
      <template #default="obj">
        <button @click="del(obj.row.id)">删除</button>
      </template>
    </MyTable>
    <MyTable :data="list2">
      <template #default="{ row }">
        <button @click="show(row)">查看</button>
      </template>
    </MyTable>
  </div>
</template>

单页应用程序

所有功能在一个html页面上实现 

优点:按需更新性能高,开发效率高,用户体验好(页面按需更新)

缺点:学习成本,首屏加载慢,不利于SEO

 路由

VueRouter 的 介绍
Vue中路由:路径 和 组件 映射 关系
根据路由就能知道不同路径的,应该匹配渲染哪个组件
VueRouter 的 使用 (5 + 2)

Vue2   VueRouter3.x   Vue3.x

Vue3   VueRouter4.x   Vue4.x

5个基础步骤 (固定)

① 下载: 下载 VueRouter 模块到当前工程,版本3.6.5

yarn add vue-router@3.6.5
② 引入
import VueRouter from 'vue-router'

③安装注册

Vue.use(VueRouter)

④创建路由对象

const router = new VueRouter()

注入,将路由对象注入到new Vue实例中,建立关联

new Vue({
    render: h => h(App),
    router
}).$mount('#app')
2 个核心步骤
创建需要的组件 (views目录) ,配置路由规则
配置导航,配置路由出口(路径匹配的组件显示的位 置)

 组件存放目录问题

2024/3/27

路由的封装抽离

main.js

import Vue from 'vue'
import App from './App.vue'
import router from './router/index'

Vue.config.productionTip = false

new Vue({
    render: h => h(App),
    router
}).$mount('#app')

index.js

import Find from '@/views/Find'
import My from '@/views/My'
import Friend from '@/views/Friend'

import Vue from 'vue'
import VueRouter from 'vue-router'

Vue.use(VueRouter)
const router = new VueRouter({

    routes: [
        { path: '/find', component: Find },
        { path: '/my', component: My },
        { path: '/friend', component: Friend },
    ]
})
export default router

声明式导航

router-link
两个类名

a.router-link-active {
  background-color: purple;
}
定制高亮类名
const router = new VueRouter({
    routes: [...],
    linkActiveClass: "类名1",
    linkExactActiveClass: "类名2"
})

路由传参

1.查询参数传参(比较适合传多个参数)

① 跳转:to="/path ?参数名=值&参数名2=值 "
② 获取:$route.query.参数名

2.动态路由传参(优雅简洁,传单个参数比较方便)

① 配置动态路由:path: "/path/参数名"
const router = new VueRouter({
routes: [
...,
{
path: '/search/:words',
component: Search
}
]
})
② 跳转:to="/path /参数值 "
③ 获取:$route.params.参数名
动态路由参数可选符
问题: 配了路由 path: "/search/:words" 为什么按下面步骤操作,会未匹配到组件,显示空白?
原因: /search/:words 表示,必须要传参数。如果不传参数,也希望匹配,可以加个可选符 "?

const router = new VueRouter({
routes: [
{ path: '/', redirect: '/home' },
{ path: '/home', component: Home },
{ path: '/search/:words?', component: Search }
]
})
路由重定向
问题: 网页打开, url 默认是 / 路径,未匹配到组件时,会出现空白
说明: 重定向 → 匹配path后, 强制跳转path路径
语法: { path: 匹配路径, redirect: 重定向到的路径 }
const router = new VueRouter({
routes: [
{ path: '/', redirect: '/home'},
{ path: '/home', component: Home },
{ path: '/search/:words', component: Search }
]
})
配置404页面
作用: 当路径找不到匹配时,给个提示页面
位置: 配在路由最后
语法: path: "*" (任意路径) – 前面不匹配就命中最后这个
import NotFind from '@/views/NotFind'
const router = new VueRouter({
routes: [
{ path: '/', redirect: '/home' },
{ path: '/home', component: Home },
{ path: '/search/:words?', component: Search },
{ path: '*', component: NotFind }
]
})
Vue路由 - 模式设置
问题: 路由的路径看起来不自然, 有#,能否切成真正路径形式?
hash路由( 默认 ) 例如: http://localhost:8080/#/home (底层基于a标签 锚链接跳转)
history路由(常用) 例如: http://localhost:8080/home (以后上线需要服务器端支持)(底层基于html5 hisrotyAPI实现) 需要后台配置访问规则
const router=new VueRouter({
    routes,
    mode:"history"
})
路由跳转方式
① path 路径跳转 (简易方便)
this.$router.push('路由路径')
this.$router.push({
path: '路由路径'
})
② name 命名路由跳转 (适合 path 路径长的场景)
this.$router.push({
name: '路由名'
})
{ name: '路由名', path: '/path/xxx', component: XXX },
跳转传参
1. path 路径跳转

2. name 命名路由跳转

 

组件缓存 keep-alive 
1. keep-alive是什么
keep-alive 是 Vue 的 内置组件 ,当它包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。
keep-alive 是一个抽象组件:它自身不会渲染成一个 DOM 元素,也不会出现在父组件链中。
2. keep-alive的优点
在组件切换过程中 把切换出去的组件保留在内存中 ,防止重复渲染DOM,
减少加载时间及性能消耗,提高用户体验性
keep-alive的 三个属性
① include : 组件名 数组,只有匹配的组件会被缓存(一般推荐)
② exclude : 组件名 数组,任何匹配的组件都不会被缓存
max : 最多可以缓存多少组件实例
<template>
    <div class="h5-wrapper" :include="['LayoutPage']>
    <keep-alive >
        <router-view></router-view>
    </keep-alive>
    </div>
</template>
keep-alive的使用会触发两个生命周期函数
activated 当组件 被激活(使用) 的时候触发 → 进入这个页面的时候触发
deactivated 当组件 不被使用 的时候触发 → 离开这个页面的时候触发
组件缓存后就不会执行组件的created, mounted, destroyed 等钩子了
所以其提供了 actived deactived 钩子,帮我们实现业务需求。
activated () {
console.log('actived 激活 → 进入页面');
},
deactivated() {
console.log('deactived 失活 → 离开页面');
}

  • 19
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值