# 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>
```