# Vue ## build a project by... `npm init vue@latest` `cd <your-project-name>` `npm install` `npm run dev` `npm run build` run `npm run serve` to open it up on browser(just like npm start) --- ## Basics #### <tag `v-on(@)` `v-bind(:)` `v-model` `v-once`> - **`v-on`** 監聽事件, can be used as: `@submit.prevent` prevent default(reload the page) `@click.right` 當按右鍵時觸發(default is .left) `@keyup.enter /.ctrl /.shift /.page-down` 當按特定鍵才輸入 - **`v-bind`** bind on values, ususally use on every value. - **`v-model`** = `v-bind:value` + `v-on:input` 2way-binding 聽+綁值 - `v-once` when content has dynamic output, but u want to lock the value(init value) ``` <p v-once>Starting from: {{counter}}</p> <p>Now: {{counter}}</p> ``` --- ##### <tag `v-if` `v-else` `v-else-if`> 要在相鄰tag時連著用 <tag `v-show`> 跟`v-if`功能一樣,方法不同 ; v-if會直接消失在DOM,v-show是用css藏起 #### <tag `v-for`="row in rows"> 跟react的map功能一樣~太神啦! `v-for`可map一到三個數值,value in sth;/ (value, idx) in sth;/ (v, key, idx) in sth --- #### `$event` `$ref` --- ## <script></script> ```javascript data(){ return{ } }, methods: { fn() { }; }, computed:{ fn() { return somthing (without brackets)} }, watch: { nameInData(oldValue, newValue){ } }, provide() { return{ topics: this.topics(值), selectTopic: this.fn(method) } }, inject: ['stringName'], emits: ['stringName'], ``` ### Slot ### Dynamic Component ```javascript <template> <div> <button @click="setSelectedComponent('active-goals')">Active Goals</button> <button @click="setSelectedComponent('manage-goals')">Manage Goals</button> <keep-alive> <component :is="selectedComponent"></component> </keep-alive> </div> </template> methods: { setSelectedComponent(cmp) { this.selectedComponent = cmp; }, }, ``` * #### feat: `<component></component>` switch between components render the component depends on binding value by using the keyword "**is**" `<component :is="">` * #### feat: `<keep-alive></keep-alive>` stores memories prevent losing input value when switching between components * #### feat: `<teleport to="body or #app"></teleport>` moves wrapped target to somewhere in DOM fix the structure at render DOM, just 4 your preference. move the waring alert tag to top of the DOM, etc. --- ### Router - use **name:** to pass through pages, keep the path: here in the page. 確保可以只改這頁url就好。 - `(.*)`為內建元素,抓取所有非我們建立的路徑。 ```javascript import { createRouter, createWebHistory } from 'vue-router'; import componentA from './componentA.vue'; import componentB from './componentB.vue'; const router = createRouter({ history: createWebHistory(), routes: [ { path: '/', redirect: '/main' }, { name: 'main', path: '/main', meta: { needsAuth: true }, components: { default: componentA, footer: componentAFooter }, children: [{ name: 'team-members', path: ':teamId', component: componentB, props: true } // /teams/t1 ] }, { path: '/:notFound(.*)', component: NotFound } ], ``` Register in **main.js** ```javascript import { createApp } from 'vue'; import App from './App.vue'; import router from './router.js'; const app = createApp(App); app.use(router); app.mount('#app'); ``` Apply `<router-view>` `<router-link>` in applied pages - `<router-view>` acts like `<component>`, shows the selected components. ```javascript <template> <router-link to="/users">Users</router-link> <main> <router-view></router-view> //here render the selected cmpnnt </main> <footer> <router-view name="footer"></router-view> </footer> </template> ``` --- # Composition API ```javascript <sript setup> //provide page provide('provideKey', provideData); //inject page const provideData = inject('provideKey'); //props const props = defineProps(['prop-keyword','second']); //emits const emit = defineEmits(['emit-keyword']); </script> ```