vue3 + vite + ts 从无到有 造轮子
一、创建项目
1 2
| npm init vite-app <project> npm install & npm run dev
|
安装VSCODE插件
Snippets
定义vue解析文件
1 2 3 4 5 6
| declare module '*.vue' { import {ComponentOptions} from 'vue' const component : ComponentOptions export default component }
|
vue-router@4
yarn add vue-router@4.0.0-beta3
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| import { createApp } from 'vue' import App from './App.vue' import '../assets/css/index.css' import {createWebHashHistory,createRouter} from 'vue-router' import Frank from '../components/Frank.vue' const history = createWebHashHistory() const router = createRouter({ history, routes:[ { path:'/', component:Frank } ] }) const app = createApp(App) app.use(router) app.mount('#app')
|
sass
yarn add sass@1.26.10 -D
二、2和3的一些小知识
- 90%的写法一致
- 3支持template支持多个根标签 2不支持
- 3有createApp(组件) 2是new Vue({template,render})
- 新v-model代替以前的v-model 和.sync
- 新增context.emit
三、组件轮子相关
通信 Provide Inject
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| import { ref, provide} from 'vue' export default { setup(){ const menu = ref(false) provide('xxx',menu) } }
import {inject,Ref} from 'vue' export default { setup(){ const menu = inject<Ref<boolean>>('xxx') console.log(menu) } }
|
通信$event 和 context.emit
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <Switch :value="y" v-model:value="y"></Switch>
//子 props: { value: Boolean }, setup(props,context) {// 初始化 const toggle = () =>{ // 重点vue3改变 update:value context.emit('update:value',!props.value) } return {toggle} }
|
使用REF创建内部数据
1 2 3 4 5 6 7
| import {ref} from 'vue' export default { setup(){ const menu = ref(false) console.log(menu) } }
|
四、属性绑定
- 默认属性都绑定到根元素
- 使用inheritAttrs:false可取消默认绑定
- 使用$attrs或者 context.attrs获取所有属性
- 使用v-bind=“$attr”批量绑定属性
- 使用const {size,…rest} = context.attrs 将属性分开
props vs attrs
- props要先声明才能取值,attrs不用
- props不包含事件,attrs包含
- props支持string以外的类型,attrs只有string类型
可以将proxy转对象来打印 console.log({…props})
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <template> <div :size="size"> <button v-bind="rest"> <slot /> </button> </div> </template> <script lang="ts"> export default { inheritAttrs:false, setup(props,context){ const {size,...rest} = context.attrs return {size,rest} } } </script>
|
库 CSS 的两个注意事项
- 不能使用scoped
- 因为data-v-xxx中xx每次不同
- 必须输出稳定不变的class选择器,方便使用者覆盖
- 必须加前缀
- .button .gulu-button 前者更容易比后者被使用者覆盖
- .theme-link .gulu-theme-link 前者更容易比后者被使用者覆盖
CSS最小影响原则
1 2 3 4
| [class^="gulu-"],[class*=" gulu-"]{ // ^= 属性以什么开着 第二个第三个值*=含有 margin:0;padding:0;box-sizing:border-box; }
|
组件的小思路
1 2 3 4 5 6 7 8 9 10
| <Button @click="onClick" @focus="onClick" @mouseover="onClick" size="small normal big" theme="button link text" level="main normal minor" disabled loading />
|
五、插槽
1
| <template v-slot:header></template>
|
六、Teleport
Teleport(以前称为Portal)是将子节点渲染到DOM谱系之外的DOM节点中的安全通道,例如弹出窗口甚至是模式。在此之前,使用CSS通常会遇到很多麻烦,现在Vue允许您使用在模板部分中进行处理。
1 2 3 4 5 6 7 8 9 10 11 12
| <teleport to="#modals"> <div>A</div> </teleport> <teleport to="#modals"> <div>B</div> </teleport>
<div id="modals"> <div>A</div> <div>B</div> </div>
|
七、Suspense
1 2 3 4 5 6 7 8
| <Suspense> <template> <Suspended-component /> </template> <template #fallback> Loading... </template> </Suspense>
|
八、小技巧
函数?表达式用法
1 2
| if(props.ok?.() !==false){}
|
样式设置
1 2
| :class={selected: key ==='1'} <div class="selected"></div>
|
REF
1 2 3 4 5 6
| // ref <div :ref="ref =>{ if(el) navItems[index] }"/> const navItems = ref([]) onMounted(()=>{ navItems.value })
|
获取宽高和位置
const { width , left } = el.getBoundingClientRect()
// 重命名
const { left:left1 } = el.getBoundingClientRect()
钩子的含义
onMounted onUpdated watchEffect
watchEffect() 会在挂载前就会执行,因为 有时候放到onMouned再执行
1 2 3 4 5
| onMounted(()=>{ watchEffect(()=>{ }) })
|
TS泛型
const indicator = ref(null)
九、如何判断子组件的对象类型 用JS获取插槽内容
1 2 3 4 5 6 7 8 9 10 11 12 13
| import Tab from './Tab.vue' setup(props,context){ const defaults = const.slots.default() console.log(defaults[0].type === Tab) defaults.forEach((tag)=>{ if(tag.type !== Tab){ throw new Error('Tabs的子标签必须是Tab') } }) return{ defaults } }
|
十、一键部署SH
1 2 3 4 5 6 7 8 9 10 11
| rm -rf dist yarn build cd dist git init git add. git commit -m "update" git brach -M master git remote add origin git@github.com:name/x.git git push -f -u origin master cd - echo http://...
|
十二、VUE2 = > VUE3
1、官方中文文档 https://v3.cn.vuejs.org/
2、工具 vue-codemode
十三、相关报错解决
sass报错
- 打开 package.json
- 把 dependencies 里的 sass 这一行,移到 devDependencies
- 重新运行 yarn install 或者 npm install 即可
报 vue/valid-template-root 错误
这个错是因为 VSCode 的 Vetur 插件还没支持 Vue 3,解决办法是在 VSCode 配置里添加一行 “vetur.validation.template”: false, 来关闭检查。
报 ‘X.vue’ is not a module. Vetur(2306) 错误
解决方法是在 X.vue 中添加一个