VUE3 + Vite + ts

VUE3 + Vite

vue3官网链接
Vite官网链接

安装 、 运行 、vscode插件

  • 安装、运行
    npm init vite@latest
    npm install
    npm run dev
    
  • vscode插件:
    • Vue Language Features
    • TypeScript Vue Plugin
  • 为什么 npm run dev 可以启动项目:
    • 查找可执行文件然后执行
    • 查找规则:先从本地的node_modules里找bin有没有vite可以执行的(.bin 目录里是一个个软链接),如果没有,就去npm install -g(全局包)里找,还没有就去环境变量里面找,如果还有没就报错。

模板语法

  • v- 开头都是vue 的指令
  • v-text :显示文本
  • v-html :展示富文本
  • v-if : 控制元素的显示隐藏(切换真假DOM)
  • v-show :控制元素的显示隐藏(display none block Css切换)
  • v-on :简写@ 用来给元素添加事件
  • v-bind 简写: 绑定元素的属性Attr
  • v-model : 双向绑定
  • v-for :遍历元素
  • v-once :性能优化只渲染一次
  • v-memo : 性能优化会有缓存

vue虚拟DOM 和 diff算法

  • 虚拟DOM就是通过JS来生成一个AST节点树
  • diff算法:
    • 无key: 替换、新增、删除
    • 有key:前序对比算法、尾序对比算法、新节点如果是多出来的就挂载、旧节点如果是多出来就卸载、特殊情况乱序(最长递增子序列算法)

Ref全家桶

  • ref():接受一个内部值并返回一个响应式且可变的 ref 对象
  • isRef(): 判断是不是一个ref对象
  • shallowRef: 创建一个跟踪自身 .value 变化的 ref,但不会使其值也变成响应式的;(只改变简单数据类型,不改变复杂数据类型)(不可以和ref一起使用)
  • triggerRef():强制更新页面DOM
  • customRef: 自定义ref ; 是个工厂函数要求我们返回一个对象 并且实现 get 和 set; 适合去做防抖之类的

Reactive全家桶

  • Reactive(object):用来绑定复杂的数据类型;返回一个对象的响应式代理。reactive 源码约束了我们的类型,只能传入object
  • readonly(): 拷贝一份proxy对象将其设置为只读
  • shallowReactive(): 只能对浅层的数据 如果是深层的数据只会改变值 不会改变视图

Ref 与 Reactive 区别

  • ref:支持所有的类型;reactive:只支持引用类型
  • ref:取值赋值都要加.value; reactive不需要

to全家桶

  • toRef: 如果原始对象是非响应式的就不会更新视图 数据是会变的;如果原始对象是响应式的是会更新视图并且改变数据的
  • toRefs:批量创建ref对象;用于解构;
  • toRaw:将响应式对象转化为普通对象

响应式原理

  • vue2: 使用Object.definedProperty实现
  • vue3: 使用Proxy

computed 计算属性

  • 计算属性就是当依赖的属性的值发生变化的时候,才会触发他的更改,如果依赖的值,不发生变化的时候,使用的是缓存中的属性值
  • 函数形式:只能取值不能修改
  • 对象形式:可以修改也可以取值(get、set)

watch 侦听器

  • 侦听一个或多个响应式数据源,并在数据源变化时调用所给的回调函数
  • watch(参数一,参数二,参数三)
    • 参数一:数据源; 可以是: ref 、 reactive 、 一个函数返回一个值、 以上类型的值组成的 数组 []
    • 参数二:回调函数;(新值,旧值)
    • 参数三:对象,options配置项;immediate:创建时立即触发回调;deep:深度遍历(reactive默认);

watchEffect()

  • 立即运行传入的一个函数,同时响应式地追踪其依赖,并在依赖更改时重新执行。
  • let 返回值 = watchEffect(参数一,参数二)
    • 第一个参数:运行的副作用函数;(用到几个监听几个 而且是非惰性 会默认调用一次)
    • 第二个参数:可选的选项,用来调整副作用的刷新时机或调试副作用的依赖;
      • flush : pre(组件更新前执行)、sync(强制效果始终同步触发) 、post(组件更新后执行)
      • 调试 watchEffect:onTrigger
    • 返回值:用来停止该副作用的函数

watch 和 watchEffect()区别

  • watch:懒执行副作用;能更明确知道是哪个依赖发生变化;可以访问当前值和旧值
  • watchEffect:非惰性;可以停止追踪;可以在调整副作用的刷新时机或调试副作用的依赖

computed 和 watch 区别

  • 是否有缓存: computed有,watch没有
  • 是否支持异步:computed不支持,watch支持

生命周期

  • 用Vue3 组合式API 是没有 beforeCreate 和 created 这两个生命周期的;setUp替代
  • onBeforeMount():读不到dom
  • onMounted():可以读取dom
  • onBeforeUpdate():获取更新之前的dom
  • onUpdated():获取更新之后的dom
  • onBeforeUnmount():组件卸载之前
  • onUnmounted():组件卸载之后
  • onErrorCaptured():在捕获了后代组件传递的错误时调用
  • onRenderTracked():调试钩子,当组件渲染过程中追踪到响应式依赖时调用
  • onRenderTriggered():调试钩子,当响应式依赖的变更触发了组件渲染时调用。

父子组件传值

父传子(defineProps)

  • 父组件通过v-bind绑定一个数据
  • 子组件通过 defineProps 接受传过来的值
    • ts: defineProps<{title:string,data:number[]}>()
    • 非ts: defineProps({title:{default:‘’,type:string},data:Array})
    • ts特有默认值方式: withDefaults(defineProps<{title:string,data:number[]}>(),{title:“xx”,data:() => [1,2,3]})

子传父 (defineEmits)

  • 子组件 是通过defineEmits派发一个事件
  • 父组件接收子组件的事件

子组件暴露给父组件内部属性 (defineExpose)

  • 子组件通过 defineExpose暴露
  • 父组件通过ref拿到

动态组件

  • 让多个组件使用同一个挂载点,并动态切换,这就是动态组件
  • 挂载点使用component标签,然后使用v-bind:is=“组件”
  • 场景:tab切换

插槽

  • 子组件中的提供给父组件使用的一个占位符 slot标签
  • 父组件可以在这个占位符中填充任何模板代码,填充的内容会替换子组件的标签
  • 匿名插槽:子: slot标签; 父:v-slot
  • 具名插槽:给插槽取个名字;一个子组件可以放多个插槽,而且可以放在不同的地方,而父组件填充内容时,可以根据这个名字把内容填充到对应插槽中
    • 简写 v-slot:xx 简写成 #xx
  • 动态插槽:插槽可以是一个变量名
    • #[xxx]

异步组件 & 代码分包 & suspense

  • 异步组件:在大型应用中,可能需要将应用分割成小一些的代码块 并且减少主包的体积,这时候就可以使用异步组件
  • 代码分包:父组件引用子组件 通过defineAsyncComponent加载异步配合import 函数模式便可以分包
  • suspense: 组件有两个插槽。它们都只接收一个直接子节点。default 插槽里的节点会尽可能展示出来。如果不能,则展示 fallback 插槽里的节点。
          <Suspense>
              <template #default>
                  <Dialog>
                      <template #default>
                          <div>我在哪儿</div>
                      </template>
                  </Dialog>
              </template>
    
              <template #fallback>
                  <div>loading...</div>
              </template>
          </Suspense>
    

Teleport传送组件

  • 将模板渲染到指定的dom节点,不受父级属性影响,但data、prop数据依旧能够使用
  • 类似 react 的 Portal
  • 使用方法:通过to 属性 插入指定元素位置;disabled动态控制teleport
     <teleport :disabled="true" to='body'>
         <A></A>
      </teleport
    

keep-alive缓存

  • 切换子组件的时候,将缓存数据下来,再次切换回来数据还在
      <keep-alive :include="" exclude=""  :max="">组件</keep-alive>
      <keep-alive :max="10">
         <component :is="view"></component>
       </keep-alive>
    
  • include:需要缓存的组件; exclude:不需要缓存的组件; max:最大缓存数据
  • 生命周期变化:
    • 初次进入:onMounted > onActivated
    • 退出:onDeactivated
    • 再次进入:onActivated

transition 动画组件

  • Vue 提供了 transition 的封装组件,在下列情形中,可以给任何元素和组件添加进入/离开过渡:
  • 条件渲染 、条件展示、动态组件、组件根节点
  • 自定义 transition 过度效果,name属性自定义
  • 过渡的类名:进入/离开过渡,有 6 个 class 切换
    • v-enter-from、v-enter-active、v-enter-to、v-leave-from、v-leave-active、v-leave-to
  • 自定义过度时间:duration
  • transition 生命周期8个:
    • @before-enter 、@enter、 @after-enter、 @enter-cancelled、@before-leave、@leave、@after-leave、@leave-cancelled
  • appear
    • 通过这个属性可以设置初始节点过度 就是页面加载完成就开始动画 对应三个状态
    • appear-active-class、appear-from-class、appear-to-class

依赖注入 Provide / Inject

  • 用于父组件向后代组件传递数据
  • 类似react的useContext 上下文
  • provide:可以在祖先组件中指定我们想要提供给后代组件的数据或方法; provide(key,传递的数据)
  • inject:后代组件通过inject来接收数据;inject(key)

Mitt

  • 用于兄弟组件之间传值
  • 安装: npm install mitt -S
  • .main.ts 初始化
  • 使用方法:通过emit派发, on 方法添加事件,off 方法移除,clear 清空所有
    • import { getCurrentInstance } from ‘vue’
    • const instance = getCurrentInstance()
    • emit派发: const emit = () => { instance?.proxy?.$Bus.emit(‘自定义事件名’,值)}
    • on监听: instance?.proxy?.$Bus.on(‘事件名’,(值) =>{})
    • 监听所有: instance?.proxy?.$Bus.on(‘事件名’,(*) =>{})
    • 移除监听事件:instance?.proxy?.$Bus.off(‘事件名’,Fn)
    • 清空所有监听:instance?.proxy?.$Bus.all.clear()

TSX

  • 安装插件:npm install @vitejs/plugin-vue-jsx -D
  • vite.config.ts 配置
    • import vueJsx from ‘@vitejs/plugin-vue-jsx’;
    • plugins: [vue(),vueJsx()]
  • 修改tsconfig.json 配置文件
    • “jsx”: “preserve”, “jsxFactory”: “h”,“jsxFragmentFactory”: “Fragment”

TSX使用

  • 返回一个渲染函数 ; optionsApi ; setUp 函数模式
  • 支持:v-model ; v-show ;
  • 不支持:v-if ; v-for ;
  • v-bind:变更为 直接赋值就可以使用;
  • v-on:变更为 所有事件有on开头、事件名称首字母大写
  • props: 变更为 类似reat
  • Emit派发: 第二个参数中获取xx xx.emt(‘自定义事件名’,值)

unplugin-auto-import

  • 配置完成之后使用ref reactive watch 等 无须import 导入 可以直接使用

深入V-model

  • v-model 其实是一个语法糖 通过props 和 emit组合而成的
  • prop:value -> modelValue (父组件:v-model=xxx 子组件:definedPropsmodelValue:类型())
  • emit: input -> update:modelValue; (父组件不要写啥,子组件:definedEmit([‘update:modelValue’]) emit(‘update:modelValue’,值))
  • 支持多个 v-model (父组件:v-model:nnn=xxx 子组件:definedPropsmodelValue:类型,nnn:类型() definedEmit([‘update:modelValue’,‘update:nnn’]) )

自定义指令 Directive

  • 引入 import type { Directive } from ‘vue’
  • 使用: let VXx:Directive<HTMLImageElement,string> = (el,binding) => {}
    • 标签中:v-xx = mm
  • 钩子函数(常用的):mounted 、update、unmounted
  • 参数:
    • el:当前绑定的DOM 元素
    • binding: instance:使用指令的组件实例;value:传递给指令的值;oldValue:先前的值;arg:传递给指令的参数;modifiers:包含修饰符

globEager 、glob

  • vite自带的导入图片
  • 使用:import.meta.glob(‘…/xxx/x/.’) import.meta.globEager(‘…/xxx/xx/.’)

IntersectionObserver

  • 异步观察目标元素与其祖先元素或顶级文档视口(viewport)交叉状态的方法
  • 可用于图片懒加载等
  • js 构造函数

globalProperties 定义全局函数和变量

  • 由于Vue3 没有Prototype 属性 , 使用 app.config.globalProperties 代替 然后去定义变量和函数
    const app = createApp({})
    app.config.globalProperties.$函数名 = () => {}
    app.config.globalProperties.$变量 = '值'
    
    组件中: 标签内:$变量  ts内: 从vue中引入getCurrentInstance  const app = getCurrentInstance  app?.proxy.$变量
    

过滤器

  • 在Vue3 移除了,可以使用全局函数代替Filters

编写vue3插件

  • 思路:
    • 在一个单独的文件中创建并导出它
    • 先定义一个.vue组件,将需要暴露的方法属性通过 definedExporse暴露出来
    • 定义一个相关的ts文件,把插件的方法和属性注册到全局
      • export default {install:(app:App) => {}}
      • 导入.vue组件,createVNode(组件) 创建虚拟dom; render(vnode,document.body)将虚拟dom渲染到页面中
      • app.config.globalProperties 将方法或属性挂载到全局
    • 在main.ts中进行注册
      • 导入app.use(组件)注册
      • TypeScript注册,必须要拓展ComponentCustomProperties类型才能获得类型提示
      • 使用: 通过 getCurrentInstance 去使用

详解 Scoped 和 :deep 样式穿透

  • Scoped: 通过在DOM结构以及css样式上加唯一不重复标记:data-v-hash 的方式,以确保唯一
  • scoped渲染规则:
    • 给HTML的DOM节点加一个不重复的 data 属性(如:data-v-123)来表示他的唯一性
    • 在每句选择器的末尾 (编译后生成的css语句) 加一个当前组件的data属性选择器(如[data-v-123])来私有化样式
    • 如果组件内部包含有其他组件,只会给其他组件的最外层标签加上当前组件的data属性
  • :deep 样式穿透 : 用来改变 属性选择器的位置
    • 例如改变el组件的样式时 在scoped中不能直接修改,原因是他在进行PostCss转化的时候把元素选择器默认放在了最后
    • :depp() 就是用来改变属性选择器的位置

css Style 完整特性 (slotted、globad)

  • 插槽选择器:slotted :slotted(类名){}
    • 使用场景:A组件中定义了 插槽,父组件中通过v-slot传入模板代码;A组件像修改插槽传入的样式时可以使用
  • 全局选择器:globad
    • 之前想加入全局样式,是通过style标签不加 scoped
    • 现在可以使用 :globad(xx){}
  • 动态css
    • 单文件组件的 style 标签可以通过 v-bind 这一 CSS 函数将 CSS 的值关联到动态的组件状态上;div{ color:v-bind(变量)}
    • 如果是对象 v-bind 加引号 v-bind(“变量.xx”)

nextTick

  • vue 更新dom是 异步 的,数据更新是 同步 的
  • 当需要操作dom的时候,可以使用nextTick
  • nextTick 就是创建一个异步任务,那么它自然要等到同步任务执行完成后才执行;可以在状态改变后立即使用,以等待 DOM 更新完成
  • 用法:
    1. 回调函数: nextTick(() => { xxx })
    1. async awit

unocss原子化

  • 减少了css体积,提高了css复用
  • 减少了起名的复杂度
  • 增加记忆成本
  • 最好用于vite,webpack属于阉割版功能很少

函数式编程,h函数

  • vue中写的template,经过一系列的编译最终生成VNode
  • h函数就是直接用来生成VNode的一个函数,省略了一系列的编译
  • h(参数一、参数二、参数三)
    • 参数一:必填项,字符串(可以是html标签名、一个组件、函数组件)
    • 参数二:可选的,对象(attribute、prop 、事件)
    • 参数三:可选的,字符串/数组/对象(children 子节点)
  • 例如 :h(“h2”, null, “Hello World”)

环境变量

  • 他的主要作用就是让开发者区分不同的运行环境,来实现 兼容开发和生产
  • npm run dev 就是开发环境 npm run build 就是生产环境
  • Vite 在一个特殊的 import.meta.env 对象上暴露环境变量
    • BASE_URL: 部署时的URL前缀
    • MODE: 运行模式
    • DEV:是否在dev环境
    • PROD:是否是build 环境
    • SSR:是否是SSR 服务端渲染模式
  • 配置额外的环境变量:
    • 在根目录新建env 文件、可以创建多个
      如:.env.development .env.production
    • 修改启动命令
      在 package json 配置 --mode env文件名称

Proxy跨域

  • 当一个请求url的 协议、域名、端口 三者之间任意一个与当前页面url不同即为跨域
  • 解决方法:
    • jsonp
    • cors :设置 CORS 允许跨域资源共享 需要后端设置
    • Vite proxy:代理
      vite.config.js/ts 进行配置

参考来源:https://blog.csdn.net/qq1195566313/category_11618172.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值