目錄
1.全局安裝
2.建立項目
3.Vue2和Vue3的差別
4.引入 Vue Router 4
安裝Vue Router
初始化Vue Router
對一個元件操作,實作另一個元件的出現和消失。實作功能的切換(出現或消失)。
路由切換後關閉"目錄"
路由嵌套
5. Switch 元件(隻寫出個人筆記,具體内容看GitHub代碼)
總結
6. Button 元件
7.Dialog 元件
8.Tabs 元件
9.事不過三,優化代碼。
10.部署官網的過程
11.Vue3官方文檔學習
1.全局安裝
create-vite-appyarn global add [email protected] 或者
npm i -g [email protected]
2.建立項目
cva danjiamu-ui-1
cd danjiamu-ui-1
yarn
yarn dev
3.Vue2和Vue3的差別
- Vue 3 的 Template 支援多個根标簽,Vue 2 不支援
- Vue 3 有 createApp(),而 Vue 2 的是 new Vue()
- createApp(元件),new Vue({template, render})
4.引入 Vue Router 4
安裝Vue Router
yarn add [email protected]
初始化Vue Router
main.ts檔案:
import {createRouter, createWebHashHistory} from 'vue-router'
const history = createWebHashHistory()//建立history
const router = createRouter( //建立router
{
history:history,
routes:[
{path:'/',component:Frank},
{path:'/xxx',component:Frank2}
]
}
)
const app = createApp(App)
app.use(router) //使用router
app.mount('#app')
//主要代碼是這些
app.vue檔案:
<template>
<div>導航欄| <router-link to="/">Frank</router-link> | <router-link to="/xxx">Frank2</router-link></div> //選中前往路徑
<hr>
<router-view/> //渲染元件
</template>
<script >
export default {
name: 'App',
}
</script>
對一個元件操作,實作另一個元件的出現和消失。實作功能的切換(出現或消失)。
App.vue:
import { createRouter, createWebHashHistory } from "vue-router";
import Home from "./views/Home.vue";
import Doc from "./views/Doc.vue";
import SwitchDemo from "./components/SwitchDemo.vue";
import ButtonDemo from "./components/ButtonDemo.vue";
import DialogDemo from "./components/DialogDemo.vue";
import TabsDemo from "./components/TabsDemo.vue";
import DocDemo from "./components/DocDemo.vue";
const history = createWebHashHistory();
export const router = createRouter({
history: history,
routes: [
{ path: "/", component: Home },
{
path: "/doc",
component: Doc,
children: [
{ path: "", component: DocDemo },
{ path: "switch", component: SwitchDemo },
{ path: "button", component: ButtonDemo },
{ path: "dialog", component: DialogDemo },
{ path: "tabs", component: TabsDemo },
],
},
],
});
Doc.vue:
<script >
import { inject, Ref } from "vue";
import Topnav from "../components/Topnav.vue";
export default {
components: { Topnav },
setup() {
const menuVisible = inject<Ref<boolean>>("menuVisible");
return { menuVisible };
},
};
</script>
Topnay.vue:
<template>
<div class="topnav">
<div class="logo" @click="toggleMenu">LOGO</div>
<ul class="menu">
<li>菜單1</li>
<li>菜單2</li>
</ul>
</div>
</template>
<script >
import { inject, Ref } from "vue";
export default {
setup() {
const menuVisible = inject<Ref<boolean>>("menuVisible"); // get
const toggleMenu = () => {
menuVisible.value = !menuVisible.value;
};
return { toggleMenu };
},
};
</script>
路由切換後關閉"目錄"
router.afterEach(() => {
if (width <= 500) {
menuVisible.value = false;
}
}
路由嵌套
import { createRouter, createWebHashHistory } from "vue-router";
import Home from "./views/Home.vue";
import Doc from "./views/Doc.vue";
import SwitchDemo from "./components/SwitchDemo.vue";
import ButtonDemo from "./components/ButtonDemo.vue";
import DialogDemo from "./components/DialogDemo.vue";
import TabsDemo from "./components/TabsDemo.vue";
import DocDemo from "./components/DocDemo.vue";
const history = createWebHashHistory();
export const router = createRouter({
history: history,
routes: [
{ path: "/", component: Home },
{
path: "/doc",
component: Doc,
children: [ //路由嵌套
{ path: "", component: DocDemo },
{ path: "switch", component: SwitchDemo },
{ path: "button", component: ButtonDemo },
{ path: "dialog", component: DialogDemo },
{ path: "tabs", component: TabsDemo },
],
},
],
});
至此,整個官網架構基本完成。
5. Switch 元件(隻寫出個人筆記,具體内容看GitHub代碼)
1. css中 $h2:白色圓圈得寬度;
left:calc(100%-#{h2}) 效果如下圖👇
2. $event 的值是 emit 的第二個參數 emit(事件名, 事件參數)
//SwitchDemo.vue
<template>
<Switch :value="y" @update:value="y = $event" />
//上邊可以寫為<Switch v-model:value="y" /> 使用v-model的簡寫
</template>
<script >
import { ref } from "vue";
import Switch from "../lib/Switch.vue";
export default {
components: { Switch },
setup() {
const y = ref(false);
return { y };
},
};
</script>
----------------------------------------------------------------------------------------
//Switch.vue
<template>
<button @click="toggle" :class="{ checked: value }"><span></span></button>
</template>
<script >
import { ref } from "vue";
export default {
props:{ //接受外部資料value
value:Boolean
},
setup(props,context) {
const toggle = () => {
context.emit('update:value',!props.value) //emit将 input 事件 的新值傳給 $event
}
return { toggle }
},
};
</script>
總結
- value="true" 和 :value="true" 的差別
- 使用 CSS transition 添加過渡動畫
- 使用 ref 建立内部資料
- 使用 :value 和 @input 讓父子元件進行交流(元件通信)
- 使用 $event
- 使用 v-model
- 架構就是把你框起來:不準改 props
•Vue 2 和 Vue 3 的差別
- 新 v-model 代替以前的 v-model 和 .sync
- 新增 context.emit,與 this.$emit 作用相同
6. Button 元件
- 預設所有屬性都綁定到根元素
- 使用 inheritAttrs: false 可以取消預設綁定
- 使用 $attrs 或者 context.attrs 擷取所有屬性
- 使用 v-bind="$attrs" 批量綁定屬性
- 使用 const {size, level, ...xxx} = context.attrs 将屬性分開
<template>
<div :size="size">
<button v-bind="rest">
<slot />
</button>
</div>
</template>
<script >
export default {
inheritAttrs: false, //取消預設綁定
setup(props, context) {
const { size, ...rest } = context.attrs; //擷取所有屬性
return { size, rest }; //rest為剩餘屬性
},
};
</script>
7.Dialog 元件
visible屬性 表示是否可見
// DialogDemo.vue
<template>
<div>DialogDemo 的文檔</div>
<h1>示例1</h1>
<Button @click="toggle">toggle</Button>
<Dialog
v-model:visible="x"
:closeOnClickOverlay="false"
:ok="f1"
:cancel="f2"
></Dialog>
</template>
<script >
import Dialog from "../lib/Dialog.vue";
import Button from "../lib/Button.vue";
import { ref } from "vue";
export default {
components: { Dialog, Button },
setup(props) {
const x = ref(false);
const toggle = () => {
x.value = !x.value;
};
const f1 = () => {
return false;
};
const f2 = () => {};
return { x, toggle, f1, f2 };
},
};
</script>
----------------------------------------------------------------------------------------
//Dialog.vue
<template>
<template v-if="visible">
<div class="djm-dialog-overlay" @click="onClickOverlay"></div>
<div class="djm-dialog-wrapper">
<div class="djm-dialog">
<header>
标題
<span @click="close" class="djm-dialog-close"></span>
</header>
<main>
<p>第一行字</p>
<p>第二行字</p>
</main>
<footer>
<Button level="main" @click="ok">OK</Button>
<Button @click="cancel">Cancel</Button>
</footer>
</div>
</div>
</template>
</template>
<script >
import Button from "./Button.vue";
export default {
props: {
visible: {
type: Boolean,
default: false,
},
closeOnClickOverlay: {
type: Boolean,
default: true,
},
ok: {
type: Function,
},
cancel: {
type: Function,
},
},
components: {
Button,
},
setup(props, context) {
const close = () => {
context.emit("update:visible", false);
};
const onClickOverlay = () => {
if (props.closeOnClickOverlay) {
close();
}
};
const ok = () => {
if (props.ok?.() !== false) {
close();
}
};
const cancel = () => {
context.emit("cancel");
close();
};
return {
close,
onClickOverlay,
ok,
cancel,
};
},
};
</script>
8.Tabs 元件
- 如何在運作時确認子元件的類型:檢查 context.slots.default() 數組
- 用 JS 擷取插槽内容:const defaults = context.slots.default()
- onMounted / onUpdated / watchEffect差別,自行查官方文檔
- TypeScript 泛型: const indicator = ref <HTMLDivElement> (null)
- 擷取寬高和位置: const { width, left } = el.getBoundingClientRect()
-
ES 6 析構指派的重命名文法
const { left: left1 } = x. getBoundingClientRect()
const { left: left2 } = y. getBoundingClientRect()
9.事不過三,優化代碼。
檢視源代碼
10.部署官網的過程
生成 dist:rm -rf dist; yarn build;
上傳 dist:cd dist 然後一堆 git 指令
cd dist
git init
git add .
git commit -m "first commit"
git branch -M master
git remote add origin 以git@開頭的倉庫位址
git push -f -u origin master
cd ..
預覽:打開 GitHub 提供的網址,有時還得重新整理幾次
11.Vue3官方文檔學習
- 如何更新 Vue 2 到 Vue 3
蔣群豪 - vue從業人員github---vue2更新到vue3工具
官方文檔學習連結