---
# System prepended metadata

title: vue 3
tags: [Vue]

---

# vue 3
## 元件
![](https://i.imgur.com/6tUitRE.png)
https://segmentfault.com/a/1190000023462922

## 元件中 的simple component
![](https://i.imgur.com/KfJicB4.png)


## 開發工具介紹
https://www.youtube.com/watch?v=ZBkZ7apIA_Y
超酷一堆東西

## ref
https://blog.johnsonlu.org/vue-refs/

## 跟vue 2的差異
https://www.youtube.com/watch?v=Y4fgakCxxd8


data 變function  鉤子最後再掛
new 變createApp 變成moudle
![](https://i.imgur.com/7GjU2GA.png)


**component**差異
原本的
![](https://i.imgur.com/LaVFuV9.png)
多一個新的teleport
可以指定位置
不太懂
![](https://i.imgur.com/ghVL4yn.png)


建立方式也不同了
2是vue直接建立,但三是要vue實例去建立
![](https://i.imgur.com/QmwG7NS.png)

在模板方面
vue2 只能有一個html去包全部
向截圖那樣
左邊的template外面還包一個div

但vue3就不用這樣了

model in coponent
![](https://i.imgur.com/NrziwXq.png)



DOM差別
這是table下面要tr td之類的 如果用自訂會錯
左邊是vue2解決方法  右邊是vue3
![](https://i.imgur.com/yyt8DYl.png)
記得vue3是雙引號裡面還要包一個單引號喔
![](https://i.imgur.com/1tYUEsI.png)


component之間的溝通 自訂事件
以前的vue2
![](https://i.imgur.com/2XFiRkF.png)


vue3多了
vite






vue 2 if-else交互重複input的**KEY**
![](https://i.imgur.com/Ty0FQDB.png)
vue3 不用了 自動幫你加了
![](https://i.imgur.com/KCJnXKZ.png)

vue 2 **template**不可以綁定資料
![](https://i.imgur.com/Hi2cHLO.png)
vue 3可以直接綁在template上面了
![](https://i.imgur.com/MdjZuFB.png)
 

**data 的array方面**
原本不能這樣
![](https://i.imgur.com/DJKbiP0.png)
解決方法
![](https://i.imgur.com/jqhy47V.png)

vue 3就不用這麼麻煩了



**keycode**

veu 2
![](https://i.imgur.com/e2k8FJt.png)

vue 3不支援了
就直接.enter就好可看官網
![](https://i.imgur.com/Gcn9MnQ.png)

## 生命週期

簡單的可以看 udemy 4-3

## js表達式

![](https://i.imgur.com/qhuW7o2.png)
`{{}}` 大鬍子裡面只接受表達式(可以用涵式 typeof之類的)

## 提醒事項

第一
mount可用所有選擇器，但他只能指定一個，所以用css選擇器，然後有兩個class=app 會全部掛掉。

要多個請用兩個 Vue.createApp


第二

編譯會先`{{}}` 跑鬍子在閃一下，對於網路速度慢的人會有影響

測試
把速度調最低
然後按`ctrl + f5` 不會重整畫面，也會清除緩存
![](https://i.imgur.com/L9lNvd8.png)
解決方法
v-cloak加在元素上(但直接加在#app就好) 
然後css加
```
[v-cloak] {
  display: none;
}
```

##   构建工具(Builds)

vue 有兩個版本有builds 跟沒有

主在差在compiler，需不需要編譯回html的差別

沒有builds快30% 

但畫面要用render才能返回畫面
![](https://i.imgur.com/5u7xcMG.png)





## vm (proxy)(代理伺服器)(可看codepen)

```
const a = vue.createApp({
    data(){
        return{
            name:'Daniel'
        }
    }
})
```

$是proxy所有的屬性都會用$，vue的規範

**proxy原理是追蹤監督的資料有改就幫他改值，不用在querySelect，虛擬
dom樹的原理**


**Withour proxy**
`a.$data.name`

**with proxy**
`a.name`
![](https://i.imgur.com/Hv0Dv4o.png)






## 框架用於 關注點分離
畫面由框架來  
使用者專注於做資料處理
![](https://i.imgur.com/SQ9NvYE.png)
https://courses.hexschool.com/courses/vue-20211/lectures/30451586

## SFC：Single File Component
https://www.youtube.com/watch?v=Em3R5755xZI


![](https://i.imgur.com/DNYCFs8.png)

三個區域 cli格式



**html **

可以用lang='pug'
用pug語言




**script**


模塊寫法

**style**
lang=''
可以選擇自己的
sass 之類的

這要一些檔案
所以要cli才能用


### event Bus
父子傳來傳去太麻煩
進階版
每個人寫法不同
只要了解就好

**vue3不能用**
https://www.youtube.com/watch?v=zthc2csjPHg

### vue3(vu2也能用) 元件溝通使用 vueX
建議看官方
要用cli用近來喔
vue add vuex

https://www.youtube.com/watch?v=4rTUX7dNB2c


vueX是模塊概念
一樣可以data methods
然後use喔
![](https://i.imgur.com/nEdUUpx.png)


這四個是基本的

`state`
有點像data放資訊的狀態
**但不能更改喔**
跟data不一樣

`mutations`
更改state的值



**使用很簡單**
直接取出來
$tore這樣
因為他是vue預設的
你看在掛勾那邊有use
所以它是vue的預設
這邊是我的理解

`觸發`
$store.commit('方法名稱')

commit是
 提交一个 mutation



## 跟vue 2差別
這vue 3 cli npm都是用ESModul  npm 上面那個
但vue 2全部都是上面那個
![](https://i.imgur.com/m3stPF9.png)

還有很多 
重複的包在一起
要得在載入
ts增強

結論 別學vue 2了
## 解惑

Q：v-for 可以代物件？
A：可以






## ESModule
![](https://i.imgur.com/q91Po2m.png)



一般：
整包載入
ESModule： vuecli也是使用 ESM

單一模組
是分別獨立的一個一個方法，ex：createApp、ref、reactive
擇一使用，不會同時使用兩種載入方法，建議使用 ESModule 的載入方法。
 卡斯伯

```
<script type="module">
imoport { createApp } from 'url';
</script>
```
**ESM 如果沒有加 type="module" 使用 import/export 會報錯**
## el改成.mount()
![](https://i.imgur.com/srZ8sYk.png)



## data(function)(改成涵式 要return)

```
Vue.createApp({

   data(){
       return{
       
       }
   }
})
```
重點重點

data改成function 然後要 return{}




## methods(物件)(初始化用)
```
Vue.createApp({

   methods:{
       
   }
})
```
放ajax資料



## watch (最常用在異步)
如果你的某個變數是依賴其他變數⽽來（如範例：fullName會觀察firstName與LastName），這時候就適合使用computed

不然你要觀察data的某個變動用watch


基本上watch能夠在某個監聽值發生改變的時候進行異步的響應，有點類似JavaScript上的監聽器addEventListener()，不過他是對物件內的值做監聽
```
const vue = new Vue({
     el: #app
     data:{
         a: 'b';
     }
})
watch:{
    a : '涵式名稱'(method裡面)
}
```
![](https://i.imgur.com/ioQ5tdc.jpg)



```
const vm = new Vue({
  el:'#app',
  data:{
    msg:''
  },
  watch:{
    //被偵聽的資料名稱(新值,舊值){}
    msg(newMsg,oldMsg){
      console.log('newMsg',newMsg)
      console.log('oldMsg',oldMsg)
    }
  }
})
```
watch 裡的 msg代表的就是我們所偵聽的資料( data 裡 msg)，當偵聽的資料值發生變化時，就會去執行 watch 裡的 msg() ，而 msg(newMsg,oldMsg) 裡的參數一定是先新後舊。



```
const vm = new Vue({
  el:'#app',
  data:{
    cellPhone:{
      type:'apple',
      years:2
    }
  },
  watch:{
    cellPhone: {
      handler(newcellPhone,oldcellPhone){
        console.log(this.cellPhone)
      },
      immediate:true,
      // deep:true
    }
  },
  created(){
    this.cellPhone = {
      msg:'重新賦值可以被偵聽到',
      type:'Samsung',
      years:10
    }
  }
})
```

當修改 cellPhone.type 值時， watch 裡的 cellPhone{handler...} 並不會執行，這是因為 Vue 沒辦法偵聽到物件裡的屬性變化，而只能偵聽到物件的變化，像是重新賦值之類的。
如果要偵聽到物件裡的屬性變化，就必須加入 deep 屬性，這樣當 cellPhone 物件裡不管哪個屬性改變時，都會觸發 watch 裡的 cellPhone{handler...} 。

## computed 計算 (具有資料緩存)

**computed不會更改原始值
watch類似 computed 但會更動原始值**

**1 不修改原始數值 產生新值(此值為了渲染畫面而已)
2 雙倍運算 num
3 過濾列表 ex(filter)**

Vue將computed當作data所以**不用加括號**
為什麼需要這個
當你{{涵式}}或其他的基本上function會重新渲染
所以要減少計算

記住要如果是要用字串相加**返回畫面** 要return

`只要在計算裡面有用到，改變值就會跑，不是只有更動才算`
**為了讓畫面易於維護及理解，可以使用計算屬性來進行複雜邏輯運算的程式碼。**
**小提示**
雖然他們都是function,但{{ 顯示內容 }} 不同
```
a() method寫法，他要帶參數
b computed寫法，因為它不需要參數
```


**computed vs methods**

computed無法帶參數，methods可以
不確定每次都會更新，請用computed
確定每次都會更新，請用medtods

computed不用加括號，因為她是監聽value


![](https://i.imgur.com/mJ9Mdzw.jpg)



```
 <script>
  const vm = new Vue({
    el: '#example',
    data: {
    firstName: 'Jonh',
    lastName: 'Smith',
    },
    computed: {
      // 物件形式
      fullName: {
        // getter
        get:function () {
          return `${this.firstName} ${this.lastName}`
        },
        // setter
        set:function (newVal) {
          this.firstName = newVal.split(' ')[0]
          this.lastName = newVal.split(' ')[1]
        }
      }
    }
  })
  </script>
```

簡單的說， get 方法只有讀取的功能，而 set 方法才有寫入的功能。
當輸入 vm.fullName = 'Mark Spiderman' 後，會發現 fullName、firstName、lastName 的值都發生了變化，其實是因為我們賦予給 fullName 一個新值的時候，這個新值('Mark Spiderman')就會被代入到 fullName 的 set 方法的參數 newVal ，這個值會先執行 set 方法的程式碼，執行完後，才會去執行 get 方法，而 get 方法所得到的值才是 fullName 最後返回的值。

一般當我們寫 computed 時，僅會默認有 get 方法，而 get 方法也才可以返回依賴於響應式資料所取得值，所以如果要有 set 方法，一定要以物件形式呈現，另外在 get 方法及 set 方法如果使用箭頭函式的話，一定要注意 this 將指向 window ，而非 Vue 實例。


## template
用 template:` <div><div>`;
**會取代 el 會少一層**


## mounted(涵式)
**小提醒**
created:在模板渲染成html前调用，即通常初始化某些属性值，然后再渲染成视图。
mounted:在模板渲染成html后调用，通常是初始化页面完成后，再对html的dom节点进行一些需要的操作
```
Vue.createApp({

   mounted(){
       return{
       
       }
   }
})
```
## v-if
下上連續才能用if else
![](https://i.imgur.com/gmVrcqw.jpg)

## template vs render

render好 
第一他都是用js
第二 好像vite的關係 可以快三十趴，不懂可以看udemy的42


## Teleport
https://www.youtube.com/watch?v=PFa9sYILD8Q

雖然是元件
但可能裡面的東西希望非同步的概念
向bootrap的model要用button觸發
這樣放在同一個元件會不能觸發
teleport就是讓他有先後順序那樣

to的要實際位置
ex #app之類的
![](https://i.imgur.com/ys5gGAk.png)


###### tags: `Vue`