---
# System prepended metadata

title: Vue

---

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