1. 程式人生 > >vue學習筆記(六) ----- vue元件

vue學習筆記(六) ----- vue元件

## 一、模組化與元件化 - 模組化的定義 >模組化在Node中是一個規範,定義一些模組的相關的規則,從程式碼角度上來說,方便做區別,如果不使用模組化,寫在js檔案中不利於後期維護和擴充套件,從程式碼的層面上就把相關的功能脫離出來,所以模組化從從程式碼的角度觸發,分析專案,把專案中一些功能型別的程式碼,單獨抽離為一個個的模組,那麼為了保證大家以相同的方式去封裝模組,於是我們就創造了CommentJS規範 - 模組化的優點 >在我們專案中,如果需要是實現相同的功能,就不需要再重寫,所以模組化從一定程度上提高我們的開發效率,有一些相關模組,直接呼叫就可以了,方便專案開發,和後期的維護與擴充套件 - 元件化: >把頁面中樣式差不多的東西抽為單獨的小元件,把需要經常複用的東西封裝為一個單獨的,今後需要用的時候直接拿就可以,不用再重寫,從ui的角度觸發去考慮問題,把頁面中程式碼結構類似的區域抽離出來,封裝成一個單獨的小元件 ;前端的元件化,方便UI元件的重用; - 元件化的優點: >隨著專案規模的發展,我們手中的元件會越來越多,我們今後一個頁面的ui,幾乎都可以從手中拿現成的元件拼接出來,方便專案的開發和維護 ## 二、建立全域性元件的方式 ### 1. 建立全域性元件的方式一 1. 先呼叫 `Vue.extend()`得到元件的建構函式 ```javascript var com1 = Vue.extend({ template: '

這是建立的第一個全域性元件

' // template 屬性,表示這個元件的 UI 程式碼解構 }) ``` 2. 通過`vue.component('元件的名稱',元件的建構函式)`來註冊全域性元件 ```javascript Vue.component('mycom1', com1) //com1就是元件的建構函式 ``` > 注意: 元件的名稱如果是駝峰命名,那麼引入的時候表名稱得加連字元 ` - ` 1.如果 Vue.component('myCom1','com1') 對應的元件標籤是 > 2. 如果是Vue.component('myCom1Test','com1') 對應元件標籤為:
>3. 如果Vue.component('my-com1','com1') 對應元件標籤為: 3. 把註冊好的元件名稱,以標籤的形式引入到vm例項區域的頁面中即可 ```html ``` **來吧展示:** ![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20201018105721348.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ1MTAzNjEy,size_16,color_FFFFFF,t_70#pic_center) ### 2. 建立全域性元件的方式二 1. 直接使用`vue.component('元件的名稱','元件物件')` ```javascript // Vue.component 的第二個引數,既接收 一個 元件的建構函式, 同時,也接受 一個物件 Vue.component('mycom2', { template:'

這是直接使用 Vue.component 創建出來的元件

' }) ``` 2. 把註冊好的元件名稱,以標籤的形式引入到vm例項區域的頁面中即可 ```html ``` **來吧展示:** ![在這裡插入圖片描述](https://img-blog.csdnimg.cn/2020101811205315.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ1MTAzNjEy,size_16,color_FFFFFF,t_70#pic_center) >注意: >1.template 屬性中,不能單獨放一段文字,必須用標籤包裹起來; >2. 如果在 template 屬性中,想要放多個元素了,那麼,在這些元素外,必須有唯一的一個根元素進行包裹; ```javascript Vue.component('mycom2', { template:'

嘿嘿嘿嘿嘿

這是直接使用 Vue.component 創建出來的元件

哈哈哈哈

' }) ``` ![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20201018112854179.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ1MTAzNjEy,size_16,color_FFFFFF,t_70#pic_center) ### 3. 建立全域性元件的方式三 1. 給`template`新增一個id選擇器 ```javascript Vue.component('mycom3', { template: '#tpl' }) ``` 2. 定義一個 template 標籤元素 使用 Vue 提供的 template 標籤,可以定義元件的UI模板解構 ```html ``` ![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20201018113520483.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ1MTAzNjEy,size_16,color_FFFFFF,t_70#pic_center) >注意: >template標籤中裡面也必須有唯一的一個根元素進行包裹 >也就是如果沒有根元素包裹,那麼下面程式碼是執行不出來了會報錯 ```html ``` **正確寫法:** ```html ``` ![在這裡插入圖片描述](https://img-blog.csdnimg.cn/2020101813511599.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ1MTAzNjEy,size_16,color_FFFFFF,t_70#pic_center) 既然是全域性元件,那麼就可以重複呼叫,**栗子:** ```html ``` ```html ``` ![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20201018135613452.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ1MTAzNjEy,size_16,color_FFFFFF,t_70#pic_center) ## 三、建立私有元件 建立一個私有元件 ```html ``` ```javascript var vm = new Vue({ el: '#app', data: {}, methods: {}, components: { // 定義例項中私有元件的 元件的名稱 和元件的 解構 'mycom4': { template: '
這是定義的私有元件
' } } }); ``` 建立多個私有元件: ```html ``` ```javascript components:{ mycom4:{ template:'

這是我定義的私有元件1

' }, mycom5:{ template:'

這是我定義的私有元件2

' } } ``` ![在這裡插入圖片描述](https://img-blog.csdnimg.cn/2020101814041346.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ1MTAzNjEy,size_16,color_FFFFFF,t_70#pic_center) ## 四、元件中相應資料和展示方法 ```javascript Vue.component('mycom', { template: '

這是自定義的全域性元件 ------ {{ msg }}

', data: function () { // // 在 元件中,可以有自己的私有資料 // 但是,元件的 data 必須是一個 function // 並且內部 return 一個 資料物件 return { msg: '我是元件的內部data' } }, methods: { // 嘗試定義元件的私有方法 show() { // console.log('出發了元件的私有show方法!') alert('我是元件內部的方法') } } }) ``` ![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20201018141432590.gif#pic_center) >思考: >為什麼要把 元件中的 data 定義為一個function呢? 因為這樣做的話,每當我們在頁面上引用一次元件,必然會先呼叫 這個 data function, 從而得到一個當前元件私有的 資料物件; ## 五、切換元件 #### 1. 結合flag識別符號和 `v-if` 與 `v-else` 實現元件的切換 ```html ``` ![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20201018143452229.gif#pic_center) #### 2. 切換多個元件 ```html ``` ```javascript Vue.component('com1', { template: '

我是第1個元件

' }) Vue.component('com2', { template: '

我是第2個元件

' }) Vue.component('com3', { template: '

我是第3個元件

' }) Vue.component('com4', { template: '

我是第4個元件

' }) ``` ![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20201018145254222.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ1MTAzNjEy,size_16,color_FFFFFF,t_70#pic_center) 進行多元件的切換 ```html 顯示元件1 顯示元件2 顯示元件3 顯示元件4 ``` ```javascript var vm = new Vue({ el: '#app', data:{ comname:'com1' }, //當vue解析檔案到component標籤時,如果有:is屬性就會解析後面的字串"comname" //然後去data中尋找這個變數 //comname:'com1' //正好是一個字串的變數的名稱,就會顯示名稱叫com1的元件 methods:{} }) ``` ![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20201018150020499.gif#pic_center) #### 3.為元件切換新增動畫 ```html ``` ```html ``` ![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20201018150950690.gif#pic_center) 如上圖效果顯示,有標準流的影響,所以要脫離標準流的影響,讓離開的元件脫離標準流 ```html ``` ![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20201018151405247.gif#pic_center) 如圖動畫效果是先進入再離開,如果想要實現先離開再進入,則只需要在`transition`中新增`mode="out-in"` ```html - ``` ![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20201018151659927.gif#pic_center) 如果想要實現離開往左走,進入往右走的效果,則: ```html ``` ![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20201018152218888.gif#pic_center) ## 六、父元件通過屬性綁定向子元件傳遞資料 1. 把要傳遞給子元件的資料,作為自定義屬性,通過`v-bind`繫結到子元件身上 ```html ``` 2. 在子元件中,不能直接使用父元件傳遞過來的資料,需要先用`props` 來接收一下 ```javascript props: ['sonmsg'] ``` 3. 在接收父元件傳遞過來的`props`的時候,一定要和父元件中傳遞過來的自定義屬性名稱保持一致 ```javascript template: '

我是子元件-----{{sonmsg}}

', ``` 具體程式碼如下: ```html ``` ![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20201018155858197.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ1MTAzNjEy,size_16,color_FFFFFF,t_70#pic_center) ## 七、父元件向子元件傳遞物件 1. 把要傳遞給子元件的物件,作為自定義屬性,通過`v-bind`繫結到子元件身上 ```html ``` 2. 在子元件中,不能直接使用父元件傳遞過來的物件,需要先用`props` 來接收一下 ```javascript props: ['msgobj123'] ``` 3. 在接收父元件傳遞過來的`props`的時候,一定要和父元件中傳遞過來的自定義屬性名稱保持一致 ```javascript template: '

後面傳遞的是父元件中物件 ---- {{ JSON.stringify(msgobj123) }}

' ``` ```html template: '

哈哈 {{ JSON.stringify(msgobj) }}

', ``` 具體程式碼如下: ```html ``` ![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20201018161119730.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ1MTAzNjEy,size_16,color_FFFFFF,t_70#pic_center) ## 八、父元件向子元件傳遞方法 1. 把要傳遞給子元件的方法,通過`v-on`繫結事件到子元件身上 ```html ``` 2. 在子元件中,不能直接使用父元件傳遞過來的方法,需要先用`$emit()` 來接收一下 ```javascript this.$emit('func') ``` 3. 在接收父元件傳遞過來的`$emit()`中,一定要和父元件中傳遞過來的方法名稱保持一致 具體程式碼: ```html ``` ![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20201018163209937.gif#pic_center) >總結: >1.如果要向子元件傳遞 data 中的資料,則 使用 屬性繫結的形式 ` v-bind:` >2. 如果要向子元件傳遞 methods 中的 方法,則 使用 事件繫結的形式 `v-on: ` ## 九、子元件向父元件傳遞資料 ```html ``` ![在這裡插入圖片描述](https://img-blog.csdnimg.cn/2020101816482315.gif#pic_center) 所以可以直接在show()方法中傳入子元件中的data資料 ```javascript methods:{ show(arg){ console.log('觸發了父元件中的show()方法' +'--------'+ arg) // '--------' } }, components: { 'com': { template: '', data:function(){ return{ sonmsg:'這是子元件中的資料' } }, methods:{ btnClick(){ // console.log('hhhh') this.$emit('func','嘿嘿嘿嘿嘿') // this.$emit('func',this.sonmsg) } } } } ``` ![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20201018165140977.gif#pic_center) 把子元件傳遞過來的資料,儲存到 父元件的 data 中 ```javascript methods: { show(arg) { // console.log('觸發了父元件中的show()方法' +'--------'+ arg) // 把子元件傳遞過來的資料,儲存到 父元件的 data 中 this.msgFormSon = arg console.log(this.msgFormSon) } }, ``` >總結: 子元件向父元件傳值,本質上,還是呼叫了父元件傳遞過來的方法 只不過,子元件在呼叫的時候,把 資料 當作引數,傳給這個方法了; ## 十、練習列表案例(結合父子元件傳值) ```html
``` ## 十一、使用rel屬性來獲取頁面中的元素 ```html

{{msg}}

``` 在h2標籤中沒有加入`ref`屬性的列印`console.log(this)`結果 ![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20201018182119699.PNG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ1MTAzNjEy,size_16,color_FFFFFF,t_70#pic_center) 在h2標籤加入`ref`屬性的列印`console.log(this)`結果 ![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20201018182412902.PNG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ1MTAzNjEy,size_16,color_FFFFFF,t_70#pic_center) 所以可以通過`rel`可以很方便的來獲取元素 ```javascript console.log(this) console.log(this.$refs.hhh) console.log(this.$refs.hhh.innerHTML) ``` ![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20201018183028570.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ1MTAzNjEy,size_16,color_FFFFFF,t_70#pic_center) ## 十二、使用rel屬性來獲取頁面中的元件 ![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20201018184916119.PNG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ1MTAzNjEy,size_16,color_FFFFFF,t_70#pic_center) ![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20201018185355523.PNG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ1MTAzNjEy,size_16,color_FFFFFF,t_70#pic_center) 所以可以根據msg去修改元件內部的資料或者呼叫子元件中的方法 ```html ``` ![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20201018190114262.gif#pic_center) ## 十三、在vue元件中data和props的區別 - `data` 在元件中,要被定義成一個function,並且要返回一個物件 - `props` 在元件中,要被定義成陣列,其中,陣列的值都是字串名,表示從父元件傳遞過來的資料 - `props`中的資料,不要直接拿來修改,如果想要修改,必須在data上重新定義一個屬性,然後把屬性的值從`this.props`直接拿過來 - `data` 上的資料,都是元件自己私有的,資料都是可讀可寫的 - `props `都是外界傳遞過來的資料,資料只能讀取,不能重