01 自定义Hook
正常的组件:<template><div><img id="img" src="./assets/images/01.png" width="300" height="300"></img></div></template><script>// 导入hook组件 并传递一个参数import userBase64 from './hooks'userBase64({el:'#img'}).then(res=>{console.log(res,'base64图片的地址')}) </script>Hook组件:import {onMounted} from 'vue'type Options = {el:string}export default function (el:OPtions):Promise<{naseUrl:string}> {return new Promise(resolve=>{onMounted(()=>{let img:HTMLImgElement = document.querySelector(options.el)img.onload = ()=>{resoleve({naseUrl:base64(img)})}})const base64 = (el:HTMLImageElement)=>{const canvas = document.createElement('canvas')const ctx = canvas.getContext('2d')canvas.height = el.heightcanvas.width = el.widthctx?.drawImage(el,0,0,canvas.width,canvas.height)return canvas.toDataURL('image/png')}})}
02 实现一个函数同时支持hook和自定义指令,去监听DOM宽高的变化
// interSectionObserver 主要监听元素是否在视口内// MutationObserver 主要监听子集的变化 属性的变化 以及增删改查// ResizeObserver 主要监听元素宽高的变化、、 创建hook函数function useResize (el:HTMLElement,callback:Function){let resize = new ResizeObserver((entries)=>{console.log(entries) // 监听所有元素 是一个数组callback(entries[0].contentRect) // 元素变化后的宽高都传递给这个函数})resize.observe (el) // 监听的元素}、、 创建自定义指令import type {App} from 'vue'const install = (app:App)=>{app.directive('resize',{mounted(el,binding){useResize(el,binding.value)}})
}useResize.install = install
03 定义全局的变量或者函数并使用
定义全局的变量或者函数在main.ts文件中const app = createApp(app)app.config.globalProperties.$env = 'dev'使用的方法:在组件中直接使用就可以模板中直接使用 <div>{{$env}}</div>script中使用: const app = getCurrentInstance()console.log(app.proxy.$env)
04 css完整的特性:
01 插槽选择器:插槽组件:<template><div>我是插槽组件</div><div> <slot></slot> </div></template>父组件:<template><son><div class="a">传递给插槽的数据</div></son></template>出现的问题 : 在父组件定义插槽的内容 div类名为a的标签 如果想在插槽组件修改样式我无法修改的解决的办法 : 在插槽组件中使用插槽选择器 :slotted(.a){color:'red'} 就可以修改样式了02 全局选择器:如果在一个组件内想要给所有的div属性都绑定一个样式的话可以使用全局选择器<style scoped>:global(div){color:'red'
}</style>03 动态的css<template><div class="div">动态css</div></template><script>const style = ref('pink')</script><style>.div{color:v-bind(style)}</style>04 模块块化的css<div :class=[$style.div,$style.border]></div><style module>.div {color:'red'}.border{border:1px soild #ccc}</style>
05 tailwind/css的使用:
第一步 :初始化一个vue的项目:npm init vue@latest第二步 :安装vscode插件 tailwind css intelliSense 安装并启动第三步 安装相关依赖:npm install -D tailwindcss@latest postcss@latest autoprefixer@latest第四步 生成配置文件npm tailwindcss init -p第五步 修改配置文件 tailwind.config,js2.6版本:
module.exports ={purge:['./index.html','./src/**/*.{vue,js,ts,jsx,tsx}'],theme:{extend:{},},plugins: [],}3.0版本module.exports={content:./index.html',"./src/**/*.{vue,js,ts,jsx,tsx}'],theme:{extend:{}},plugins:[],}第六步 创建一个index.css@tailwindbase;@tailwindcomponents;@tailwindutilities;第七步 在main.ts文件中引入上面的index.css第八步 组件内部的标签就可以直接使用了<div class="w-screen h-screenbg-red-600 flex justify-center items-center text-8xltext-slate-200"></div>
05 关于nextTick
vue更新数据是同步的,但是vue更新DOM是异步:案例: 添加内容,屏幕出现滚动条,让每次添加的内容屏幕滚动都在最下面。const send = async ()=>{messageList.push('xiaoman') // 追加内容box.value.scrollTop = 99999999 // 卷去头部让其滚动到最下面问题:无法实现因为是异步的操作 // 第一种解决办法nextTick(()=>{box.value.scrollTop = 99999999 }) // 第二种办法 await nextTick()box.value.scrollTop = 99999999}原理 把我们的代码放到一个promise里面去执行, 执行的是then方法 走的是一个微任务