Vue基礎知識彙總(含webpack打包工具的使用)

基礎知識一

框架和庫的區別

  • 概念:小而巧的是庫,大而全的是框架
  • 框架:是一套完整的解決方案,對項目的侵入性很大,項目若是須要更換框架,則須要從新架構整個項目
  • 庫(插件):提供某一個小功能,對項目的侵入性較小,若是某個庫沒法完成某些需求,能夠很容易的切換到其餘庫實現需求

MVC和MVVM思想

  • MVC 主要是後端的分層開發思想;把 一個完整的後端項目,分紅了三個部分:javascript

    • Model:(數據層)主要負責 數據庫的操做;
    • View:(視圖層)全部前端頁面,統稱爲 View 層
    • Controller:(業務邏輯層)主要處理對應的業務邏輯;(對於後臺來講,這是開發的重點)

  • MVVM是前端頁面的分層開發思想,主要關注於 視圖層 分離,也就是說:MVVM把前端的視圖層,分爲了 三部分 Model, View, ViewModel
    • Model 是 頁面中,須要用到的數據
    • View 是頁面中的HTML結構;
    • ViewModel 是 一個 中間的調度者,提供了雙向數據綁定的概念;
  • 爲何有了MVC還要有MVVM
    • 由於 MVC是後端的開發思想,並無明肯定義前端的頁面該如何開發;
    • MVVM 是前端的頁面的開發思想,把每一個頁面,分紅了三個部分,同時 VM 做爲 MVVM 的核心,提供了雙向數據綁定的概念,前端程序員,不須要手動渲染頁面了,並且,頁面數據發送變化,也不須要程序員手動把 數據的變化同步到Model中;這全部的操做,都是 VM 自動完成的!
    • 有了 MVVM 的思想之後,前端只關心 頁面交互邏輯,不關心頁面如何渲染;

Vue.js 基本代碼 和 MVVM 之間的對應關係

1. 注意:Vue中,不推薦程序員手動操做DOM元素;因此,在Vue項目中,沒有極其變態的需求,通常不要引入 Jquery;
2. Vue代碼解析執行的步驟:
   1. 當 VM 實例對象,被 建立完成以後,會當即解析 el 指定區域中的全部代碼;
   2. 當 VM 在解析 el 區域中全部代碼的時候,會把 data 中的數據,按需,填充到 頁面指定的區域;
3. 注意:每當 vm 實例對象,監聽到 data 中數據發生了變化,就會當即 從新解析 執行 el 區域內,全部的代碼;
複製代碼
<!-- 1.導入vue的包 -->
    <!-- 只要導入了vue的包,在window全局會掛載Vue成員(構造函數) --> <script src="./lib/vue-2.5.16.js"></script> </head>
<body>
    <!--2. 放一個id爲app的div,未來new 出來的vue實例會控制這個div內部的代碼 --> <!-- 注意:不能vm實例對象直接控制body或者是html--> <div id="app"> <h3>{{msg}}</h3> </div> <script> // 3new 一個Vue,建立Vue的實例對象 // new出來的vm實例對象就是mvvm中的 vm const vm=new Vue({ // 指定new 出來的vm實例要控制頁面上的哪一個區域 el:'#app',//這個vm中指定的區域就是mvvm中view data:{//指定被控制的區域,要用到的數據 msg:'Hello Vue.js' }//這個data指向對象就是mvvm 中的model }); // function Person(obj){ // this.name=obj.name; // this.age=obj.age; // } // const p1=new Person({name:'zs',age:20}); </script> </body>
複製代碼

Vue指令及插值表達式

定義:Vue中,經過一些特殊的用法,擴展了HTML的能力
複製代碼
  • 未來 建立 Vue 實例的時候,Vue 會把 這些指令 都進行解析,從而,根據不一樣的指令,執行不一樣的操做、渲染不一樣的結果;
Vue指令之 插值表達式 {{ }}
  1. 基本使用演示 在指定的位置動態插入內容,例如:
<p>{{msg}}</p>
複製代碼
注意:指令是框架中提出的概念,擴展了html的能力,指令若是想要生效就必須被vm實例對象所解析
複製代碼
  1. 在插值表達式中 使用簡單的表達式,不能寫語句
<div id="app">
        <h3>{{msg}}</h3>
        <h3>{{1+1}}</h3>
        <h3>{{boo ? '條件爲真':'條件爲假'}}</h3>
        <h3>{{msg.length}}</h3>
        <!--注意插值表達式只能在內容區域,不能在屬性節點裏面-->
        <h3>{{arr}}</h3>
       <!--不能寫循環等語句-->
    </div>
    <script>
        const vm=new Vue({
            el:'#app',
            data: {
               msg:'Hello Vue.js',
               boo:false,
               arr:[1,2,3]
            },
        });
    </script>
複製代碼
  1. 注意:插值表達式只能用在元素的內容區域;不能用在元素的屬性節點中; 4.若是對於{{}}的這種形式不滿意,能夠經過下面的形式修改自定義的形式:
var vm = new Vue({
            delimiters:['$','#'],//把插值表達中的雙花括號換成是指定的,可是通常不推薦
            el: '#app',
            data: {
                city: '北京',
                people: 2000
            }
        })
複製代碼

5.對於自增和自減運算會出現異常,因此這裏暫時不推薦在插值表達中使用自增自減元素。css

Vue指令之v-cloak
  1. 解決的問題
    • 插值表達式有閃爍的問題(v-cloak 指令來解決閃爍問題)
[v-cloak]{
            display: none;
        }
複製代碼
  1. 應用場景
    • 當 網絡比較卡的時候,咱們能夠爲 最外層的 元素,添加 v-cloak ,防止用戶看到 插值表達式
  2. 原理
    • 經過vm建立完成以後,動態的移除v-cloak的屬性,從而顯示插值表達式的節點
Vue指令之v-text

1.基本使用 在元素的屬性節點上,添加v-text 命令,例如:html

<p v-text="msg"></p>
複製代碼

2.v-text中也可使用簡單的語句 3.v-text與{{}}的區別前端

  • v-text會覆蓋全部內容 {{}}不會覆蓋
  • v-text不會出現閃爍問題,可是{{}}會出現閃爍問題

4.應用場景(v-text)vue

  • 向指定元素的內容區域中,渲染指定的文本
Vue指令之v-html

1.基本使用 在元素的屬性節點上,添加v-text 命令,例如:java

<!-- 總結: vue 中的指令只有插值表達式是用在內容節點上的, 其餘的全部指令都是用在屬性節點的 -->
<p v-text="msg"></p>
複製代碼

2.應用場景 當服務器返回的數據中,包含的html的標籤,此時,這些標籤只能在v-html來渲染node

Vue指令之 v-bind: 屬性綁定(自定義屬性和固有屬性)
添加在元素節點身上的屬性均可以經過v-bind進行綁定(id width src)等
複製代碼

1.基本使用react

  • v-bind:是爲html屬性節點動態綁定數據的,例如:
<div id="app">
        <!-- v-bind:指令表示屬性綁定, 能夠在v-bind中寫一些簡單的表達式 從此在開發中很是經常使用 v-bind:指令能夠簡寫爲英文的:表明的是屬性綁定 -->
        <button :title="titleStr">按鈕</button>
        <img :src="boo ? img:img1" alt="">
        <!-- <img v-bind:src="img1" alt=""> -->
    </div>
    <script> // 當vm實例被建立完畢後會當即解析執行el區域內全部vue的指令 // 並且只要data數據中發生了變化,就會當即從新解析數據 const vm=new Vue({ el:'#app', data:{ titleStr:'這是title屬性值', boo:false, img:'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=2391791031,3623366227&fm=26&gp=0.jpg' ,img1:'https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=486958716,243120904&fm=26&gp=0.jpg' } }) </script>
複製代碼

2.應用場景webpack

  • 若是元素的屬性值,須要動態地進行綁定,則須要使用v-bind: 指令
Vue指令之v-on:事件綁定
  1. 基本使用: v-on: 的做用,是爲 HTML 元素,綁定 事件處理函數,例如:
<input type="button" value="按鈕" v-on:click="事件處理函數名" />
複製代碼
  1. 綁定事件處理函數並傳參:
<input type="button" value="按鈕" v-on:click="show(123)" />
複製代碼
關於參數問題:
1. 有傳遞使用傳遞的參數
2. 沒有聲明(),第一個形參就是事件對象object MouseEvent
3. 有聲明(),尚未傳遞實參,形參就是undefined
   methods: {
            // 成員方法
                exp(id){
                    console.log('商品被刪除了'+id);
                }
                // 不傳遞實參的狀況下是undefined
                // 不加括號[object MouseEvent]
            },

複製代碼
  1. 簡寫形式: v-on: 指令能夠簡寫成 @,例如,能夠簡寫成以下格式:
<input type="button" value="按鈕" @click="事件處理函數名" />
複製代碼
Vue指令之v-modle實現雙向綁定

1.基本使用:ios

  • 能夠把頁面上數據的變化,自動同步更新到 VM 實例的 data 中。例如:
<input type="text" v-model="msg"/>
複製代碼

2.和v-bind的區別

  • v-bind: 只能實現單向的數據同步 data ---> 頁面;
  • v-model 能夠實現雙向的數據同步 data <--> 頁面;
  • 在寫法上v-bind能夠簡寫爲:的形式.v-model沒有簡寫方式
  • v-model ="msg",:v-bind:src="mySrc",他們裏面的屬性值都須要在data中設置,哪怕沒有值也須要設置爲空字符串。 3.注意:
  • v-model只能和表單元素配合使用,例如input select textarea等
  • v-model是Vue中惟一支持雙向數據綁定的指令.

4.v-model簡易版原理整理 v-model的原理就給input輸入框中定義oninput事件,在該事件中把用戶輸入的信息都給隨時得到到,並對data成員進行賦值

data成員變化了,頁面上用到的地方就從新渲染,達成簡易雙向綁定的效果 代碼以下:

<div id="app">
        <p>{{city}}</p>
        <!-- 這裏的$event就表明的是event -->
        <input type="text" @input="city=$event.target.value" :value="city">
        <input type="text" @input="feel" :value="city">
    </div>
    <script src="./vue.js"></script>
    <script>
    var vm=new Vue({
        el:'#app',
        data:{
            city:'北京'
        },
        methods: {
            feel(evt){
            //    console.log(evt);
            // console.log(evt)  // InputEvent對象
        // evt.target:表明觸發當前事件的html元素dom對象,具體是input框對象
        // evt.target.value: 隨時感知輸入框輸入的信息

        // 把隨時輸入的信息賦予給city,這樣city變化,因爲「從新渲染」,頁面上用到的地方就更新了
        // 就達成v-model雙向綁定的效果了  
            this.city=evt.target.value;
            }
        },
    })
    </script>
複製代碼

5.應用場景: 簡易計算器的實現:

<body>
    <div id="app">
        <!-- 第一個運算的數值 -->
        <input type="text" v-model="n1">
        <select v-model="opt">
            <option value="+">+</option><br>
            <option value="-">-</option><br>
            <option value="*">*</option><br>
            <option value="/">/</option><br>
        </select>
        <!-- 第二個元素的數值 -->
        <input type="text" v-model="n2">
        <!-- 注意這裏不要寫錯 -->
        <button @click="calc">=</button>
        <!-- 運算的結果 -->
        <input type="text" readonly :value="result">
    </div>
    <script> const vm=new Vue({ el:'#app', data:{ n1:0, n2:0, opt:'+', result:0 }, methods: { calc(){ switch(this.opt){ case '+': this.result= parseFloat(this.n1)+parseFloat(this.n2); break; case '-': this.result= parseFloat(this.n1)-parseFloat(this.n2); break; case '*': this.result= parseFloat(this.n1)*parseFloat(this.n2); break; case '/': this.result= parseFloat(this.n1)/parseFloat(this.n2); break; } } }, }) </script>
</body>
複製代碼
this 操控data

根據業務須要,事件在執行過程當中須要對Vue實例的data數據進行操做,經過this關鍵字實現,

this表明Vue實例對象,而且針對data或methods成員均可以直接進行調用

在Vue中使用class樣式

1.類名數組

  • 經過 v-bind: 爲元素的 class 綁定具體的類名:
<p :class="['thin', 'red', 'big']">哈哈哈</p>
複製代碼

2.類名數組中使用三元表達式,按需爲元素添加某些類名

<button @click="getInfo()" >獲取數據</button>

<script>
  var vm = new Vue({
    el:'#app',
    data:{
      address:'鐵嶺'
    },
    methods:{
      getInfo:function(){
        // 經過 this關鍵字 得到 data區域的數據信息
        console.log(this.address+'是一個大城市');
      }
    }
  })
</script>
複製代碼
<p :class="['thin', flag ? 'red' : '']">哈哈哈</p>
複製代碼

3.應用場景

  • 網頁開關燈
<div id="app" :class="[flag ? 'light':'dark']">
        <button @click="flag=!flag">切換</button>
        <h1>{{msg}}大渣好,我係咕天樂,我係渣渣輝,貪挽難約,介系一個你沒有挽過的船新版本,擠需體驗3番鍾,裏就會幹我同樣,捱上節款遊戲</h1>
        <img :src="flag ? img1:img2" alt="">
    </div>
    <script>
        const vm=new Vue({
            el:'#app',
            data:{
                //false是黑夜,true是白天
                flag:false,
                img1:'./images/6.jpg',
                img2:'./images/段段.jpg'
            }
        })
    </script>
複製代碼
在Vue中使用style樣式

style屬性也比較特殊,其能夠給標籤設置許多css樣式,在vue中能夠作以下應用

- 對象語法
      <div :style="{color: 'red', 'font-size': '20px', fontWeight:'bold' }"></div>
- 數組語法
      <div :style="[{color: 'red'}, {'font-size': '20px', fontWeight:'bold' }]"></div>
複製代碼

在一個數組元素中能夠綁定多個或一個樣式成員 有的樣式屬性名稱是經過"-"中橫線鏈接的,這在javascript的命名規則中不容許的,例如font-size、font-weight,在處理時有兩種方式

  1. 引號限定 如 'font-size'
  2. 中橫線去除,後邊首字母大寫 如 fontWeight

以上對象或數組綁定class語法均渲染爲:

<div style="color:red; font-size:20px; font-weight:bold"></div>

複製代碼

經過 數組 或 對象 對 class/style 進行綁定的好處是,屬性值能夠嵌入編程內容,實現精細化控制

Vue指令之v-for和:key屬性

1.基本用法:

  • 普通數組 (通常般)
<li v-for="(item,i) in list1">{{item}}---索引{{i}}</li>
複製代碼
  • 對象數組(用的最多)
<li v-for="(item,i) in list2">{{item.id}}---{{item.name}}---索引值{{i}}</li>
複製代碼
  • 迭代對象中的屬性
  • 迭代數字 (這兩種方法平時不怎麼用,因此這裏不詳細介紹了)

2.:key的用法

<li v-for="item in list2" :key="item.id">{{item.id}}---{{item.name}}---索引值{{i}}</li>
複製代碼
注意:從此只要用到了id值,就必定要爲循環的每一項,添加:key屬性綁定,並且key的值最好綁定到id值上,key的值必定要惟一,單獨的使用索引值也是不能夠的,由於這個key值是用來標識數據惟一性的,經過key綁定的數據項和數據狀態(好比複選框的選中僞選中關係)之間的關係
複製代碼
Vue中v-if和v-show指令
  • v-if 和 v-show 的做用,都是切換界面上元素的顯示或隱藏的;
<div id="app">
        <button @click="flag=!flag">Toggle</button>{{flag}}
        <!-- v-if是經過動態建立或者移除元素實現動態切換 -->
        <h3 v-if="flag">奔跑的五花肉</h3>
        <hr>
        <!-- v-show是經過控制元素的display:none樣式實現切換 -->
        <h3 v-show="flag">2432432</h3>
    </div>
複製代碼
通常來講,v-if 有更高的切換消耗 而  v-show 有更高的初始渲染消耗。

所以,若是須要頻繁切換 v-show 較好,若是在運行時條件不大可能改變 v-if 較好。

複製代碼

修飾符

事件修飾符(用來修飾事件的,若是點擊事件)

.prevent 阻止默認行爲(使用最頻繁)

<a href="http://www.baidu.com" @click.prevent="show">百度</a>
複製代碼

.once 只觸發1次(幾乎不經常使用)

<button @click.once="btnHandler">按鈕</button>
複製代碼

.stop阻止冒泡

<button @click.stop="btnHandler">按鈕</button>
複製代碼

.self只有在當前元素上觸發事件的時候,纔會調用處理函數

<div class="inner" @click.self="innerHandler"></div>
複製代碼
按鍵修飾符

按鍵修飾符是配合文本框的使用的 .enter

<input type="text" v-model="password" @keyup.enter="login"><br>

複製代碼

.tab

<input type="text" v-model="password" @keyup.tab="login"><br>

複製代碼

.esc

<input type="text" v-model="password" @keyup.esc="login"><br>

複製代碼

基礎知識二

Vue過濾器

"2018-01-25T02:10:02.945Z"    =>   2018-01-25
複製代碼

概念:過濾器的本質就是一些函數,可被用做一些常見的文本格式化

  • 過濾器只能用在兩個地方,插值表達式和v-bind表達式中
<td :title="item.ctime |dateFormate">{{item.ctime | dateFormate}}</td>
複製代碼
  • 過濾器應該被添加在javascript表達式的尾部,由 管道 符指示

全局過濾器

1.使用全局過濾器的語法

<span>{{ dt | 過濾器的名稱 }}</span>
|的做用就是調用一個過濾器
複製代碼

2.定義全局過濾器的語法

  • Vue.filter('過濾器的名稱', function(originVal){ /* 對數據進行處理的過程,在這個 function 中,最後必須 return 一個處理的結果 */ })
注意:全局過濾器必須定義在new Vue()以前
複製代碼

3.使用過濾器的注意事項

  • 若是想拿管道符前面的值,經過 function 的第一個形參來拿
  • 過濾器中,必定要返回一個處理的結果,不然就是一個無效的過濾器
  • 在調用過濾器的時候,直接經過 () 調用就能傳參; 從過濾器處理函數的第二個形參開始接收傳遞過來的參數
  • 能夠 屢次 使用 | 管道符 一次調用多個過濾器
<div id="app">
        <!-- 在插值表達式中可使用|管道符來調用指定的過濾器 -->
        <!-- 若是調用過濾器了,則在這個內容區域顯示的內容是過濾器方法最終返回的處理結果 -->
        <!-- 過濾器只是對原有的數據作了一層包裝,並無修改原來的值 -->
        <h3>{{dt | dateFormate}}</h3>
        <p>{{dt}}</p>
    </div>
    <script>
        // 經過Vue.filter定義一個全局過濾器
        // 注意,調用過濾器的時候,管道符前面的值,必須經過function的第一個參數接收
        // Vue.filter('過濾器的名稱',function(originVal){//過濾器的處理函數

        // })
        Vue.filter('dateFormate',function(originVal){
            //最終必定要返回一個處理結果
            // return originVal+'-------'
            const dt=new Date(originVal);
            const y=dt.getFullYear();
            const m=(dt.getMonth()+1+'').padStart(2,'0');
            const d= (dt.getDate()+'').padStart(2,'0');
            const hh= (dt.getHours()+'').padStart(2,'0');
            const mm=(dt.getMinutes()+'').padStart(2,'0');
            const ss= (dt.getSeconds()+'').padStart(2,'0');

            const dtstr=`${y}-${m}-${d} ${hh}:${mm}:${ss}`;

            return dtstr;
        });
        const vm=new Vue({
            el:'#app',
            data:{
                dt:'2018-01-25T02:10:02.945Z'
            },
            methods: {
                
            },
        })
    </script>
複製代碼

私有過濾器

const vm=new Vue({
            el:'#app',
            data:{
                dt:'2018-01-25T02:10:02.945Z'
            },
            methods: {
               
               
            },
            // 注意是跟methods同級
             // 注意:私有的過濾器帶s,全局過濾器不帶過濾器
             // 私有過濾器的名稱:function (){//私有過濾器的處理函數}
            //  過濾器是按照就近原則進行調用的,先調用私有的,若是私有過濾器先看私有過濾器,沒有再看全局過濾器
             filters:{
                //  es3寫法
                    // dateFormate:function(originVal){
                    //     return originVal+'-----'
                    // }
                // es6寫法
                    dateFormate(originVal){
                        return originVal+'-----'
                    }
                }
        })
複製代碼
過濾器是按照就近原則進行調用的,先調用私有的,若是私有過濾器先看私有過濾器,沒有再看全局過濾器
複製代碼

帶參數的過濾器

有的時候,過濾器主體業務邏輯不變化的狀況下,可能結果的形式根據業務要求有所調整,爲了加強靈活度,能夠經過傳遞參數實現。

Vue實例.$mount()動態掛載實例

語法:Vue.$mount("選擇器 - 指定要控制的區域")

const vm=new Vue({
            data:{
                msg:'Hello'
            }
        });

        //mount是掛載的意思,表示 手動指定當前的vm實例要控制的區域
        vm.$mount('#app');
複製代碼

template屬性指定模塊

語法:template:'<h6>{{msg}}</h6>'

const vm=new Vue({
            el:'#app',
            data:{
                msg:'Hello'
            },
            methods: {},
            filters:{},
            // 指定當前vm要渲染的模版
            // 結論:若是同時指定了el和template,那麼template會把el區域替換掉
            template:'<h6>{{msg}}</h6>'
        })
複製代碼

Vue的生命週期

生命週期

概念 : 實例的生命週期,就是一個階段,從建立到運行,再到銷燬的階段;

生命週期函數

在實例的生命週期中,在特定階段執行的一些特定的事件,這些特定的事件叫作生命週期函數

  • 生命週期函數=生命週期鉤子=聲明週期事件
主要的生命週期函數分類
  • 建立期間的生命週期函數(特色:每一個實例一生只執行一次)
    • beforeCreate:建立以前,此時data和methods方法還沒有初始化,還不能訪問裏面的數據
    • created:(第一個重要的函數,此時data和methods已經建立好了,裏面的數據還有方法均可以被訪問了)
    • beforeMounted:掛載模版以前,此時頁面尚未被渲染出來
    • mounted:(第二個重要的函數,此時,頁面剛被渲染出來,,若是要操做DOM元素,最好在這個階段)
  • 運行期間的生命週期函數(特色,按需被調用,至少0次,最多N次)
    • beforeUpdate :數據是最新的,可是頁面仍是舊的頁面
    • updated 頁面和數據都是最新的
  • 銷燬期間的聲明周期函數(特色:每一個實例一生只執行一次)
  • beforeDestroy:銷燬以前,實例還能夠正常使用
  • destroyed :銷燬以後,實例已經不存在,沒法工做了

axios的使用

<script>
    // 經過這個屬性,全局設置 請求的 根路徑
    axios.defaults.baseURL = 'http://www.liulongbin.top:3005'
    // 未來項目中都這麼搞
    Vue.prototype.$http = axios

    // 建立 Vue 實例,獲得 ViewModel
    var vm = new Vue({
      el: '#app',
      data: {},
      methods: {
        async getInfo() {
          const { data: res } = await this.$http.get('/api/get', { params: { name: 'zs', age: 22 } })
          console.log(res)
        },
        async postInfo() {
          const { data: res } = await this.$http.post('/api/post', { name: 'zs', age: 22 })
          console.log(res)
        }
      }
    });
  </script>

複製代碼
注意:axios這個庫能夠在任意的請求中使用,他們發送get和post請求時的參數是不相同的,get請求參數是params而那個post請求,請求參數是data,可是這裏太過麻煩,就用對象結構賦值的方式將代碼進行解構
複製代碼
axios的缺點
  • 只支持 get 和 post 請求,沒法發起 JSONP 請求;
  • 若是涉及到 JSONP 請求,可讓後端啓用 cors 跨域資源共享便可;

在Vue中,還可使用 vue-resource 發起數據請求

  • vue-resource 支持 get, post, jsonp請求【可是,Vue官方不推薦使用這個包了!】

基礎知識三

Vue中的動畫

Vue中動畫的基本介紹

使用動畫的緣由
  • 動畫可以增長頁面的趣味性,目的是爲了讓用戶更好的理解頁面的功能
注意:Vue中的動畫,都是簡單的動畫過渡,並不會有CSS3那麼炫酷
複製代碼
動畫簡單介紹

1.每一個動畫都是由兩部分組成的:

- 入場動畫:從不可見(flag = false) -> 可見(flag = true)
- 出場動畫:可見(flag = true) -> 不可見(flag = false)
複製代碼
  1. 入場時候,Vue把這個動畫,分紅了兩個時間點和一個時間段:
    • v-enter:入場前的樣式
    • v-enter-to:入場完成之後的樣式
    • v-enter-active:入場的時間段
  2. 離場時候,Vue把動畫,分紅了兩個時間點和一個時間段:
    • v-leave:離場以前的樣式
    • v-leave-to:離場完成之後的樣式
    • v-leave-active:離場的時間段

動畫圖示:

總結:帶active的都是時間段的效果,
     帶to的都是完成以後的狀態,
     什麼也不帶的都是開始時的狀態
    
也就是說動畫都是從哪來,從哪去

複製代碼
使用過渡類名
  1. 把須要添加動畫的元素,使用v-if或v-show進行控制
  2. 把須要添加動畫的元素,使用Vue提供的元素 包裹起來
  3. 添加兩組類:
<style> /* 定義元素入場之間和離場以後的位置 */ /* 注意:他在入場以前並非標準裏的位置 */ .v-enter, .v-leave-to { transform: translateX(150px); opacity: 0; } /* 定義元素,入場階段,和離場階段的過渡效果 */ .v-enter-active, .v-leave-active { transition: all 0.8s; } /* 動畫完成以後,默認的位置就是標準流中的效果 */ /* 定義元素在標準流中的效果, 這個標準流的效果就是入場完成以後,移入離場開始以前,元素的效果*/ h3 { transform: translateX(50px); opacity: 0.5; } /* 經過類名,能夠設置頁面上的多組動畫效果 */ .test-enter,.test-leave-to{ opacity: 0; transform: translateY(200px); } .test-enter-active, .test-leave-active{ transition: all 0.8s; } </style>
複製代碼

此時transition身上的name屬性也要改爲對應的屬性值

<div id="app">
        <button @click="flag=!flag">Toggle</button>
        <!-- 1.使用vue框架提供的transition標籤,把須要添加過渡的效果包裹起來 -->
        <transition name="">
            <h3 v-if="flag">函數哈哈胡莎莎</h3>
        </transition>
        <hr>
        <button @click="flag2=!flag2">Toggle</button>
      <transition name="test">
            <h6 v-if="flag2">這是第二個元素</h6>
      </transition>
    </div>
複製代碼
注意:v-if和v-show在前面講過是控制元素的顯示和隱藏,具體的操做能夠再回顧一下上面的筆記.
複製代碼
使用第三方的css動畫庫
  1. 把須要添加動畫的元素,使用v-if或v-show進行控制
  2. 把須要添加動畫的元素,使用Vue提供的元素 包裹起來
  3. 爲 添加兩個屬性類enter-active-class, leave-active-class
  4. 把須要添加動畫的元素,添加一個 class="animated"
<div id="app">
        <button @click="flag=!flag">Toggle</button>
        <!-- 指定入場的類名 -->
        <transition enter-active-class="bounceInDown" leave-active-class="bounceOutDown">
            <h3 v-if="flag" class="animated"> 哇哈哈哈哈哈哈</h3>
        </transition>
    </div>
複製代碼
v-for的列表過渡
  1. 把v-for循環渲染的元素,添加 :key 屬性[注意:若是要爲列表項添加動畫效果,必定的指定key,而且key的值不能是索引]
  2. 在 v-for循環渲染的元素外層,包裹 標籤
  3. 添加兩組類便可:
<!-- transition-group這個標籤要放在ul裏面,而且這個標籤會自動的渲染爲span -->
            <!-- 可是這裏也能夠強制的將這個標籤渲染爲ul,這時,外面的ul屬性也不須要設置了 -->
            <transition-group tag="ul">
                <li v-for="item in list" :key="item.id">
                    {{item.id}}---{{item.name}}
                </li>
            </transition-group>
複製代碼
列表的排序過渡

組件還有一個特殊之處。不只能夠進入和離開動畫,還能夠改變定位。要使用這個新功能只需瞭解新增的 v-move 特性,它會在元素的改變定位的過程當中應用。

  • v-move 和 v-leave-active 結合使用,可以讓列表的過渡更加平緩柔和:
<style>
   /* 爲即將被刪除的元素,添加樣式,讓他脫離標準流 */
        .v-leave-active{
            position: absolute;
            width: 100%;
        }
        /* 經過.v-move這個類,可讓後續的元素,經過過渡,漸漸的頂上去 */
        /* 若是不加這個類的話,下面的元素會一下就頂上去,也就沒有了過渡的效果 */
        .v-move{
            transition: all 0.8s;
        }
    </style>
複製代碼

Webpack

什麼是webpack?

  • 什麼是webpack:webpack 是前端項目的構建工具;前端的項目,都是基於 webpack 進行 構建和運行的;
  • 爲何要使用webpack:
    1. 若是項目使用 webpack 進行構建,咱們能夠書寫高級的ES代碼,且不用考慮兼容性;
    2. webpack 可以優化項目的性能,好比合並、壓縮文件等;
    3. 基於webpack,程序員能夠把 本身的開發重心,放到功能上;
  • 什麼項目適合使用webpack:
    • webpack 很是適合與 單頁面應用程序(SinglePageApplication) 結合使用;
      • vue, react, angular 只要用前端三大框架開發項目,必然會使用webpack工具;
    • 不太適合與多頁面的普通網站結合使用;
  • 根據webpack官網的圖片介紹webpack打包的過程
  • webpack分不少版本 1.x 2.x 3.x 4.x

ES6導入導出語法

因爲下面的筆記,在配置的時候可能會遇到ES6中導入導出的語法,因此這裏提早在筆記中記錄一下。

在webpack中一切皆模塊,這裏主要是ES6中模塊化的導入和導出。

在webpack中,每一個js文件都須要獨立的模塊,每一個模塊都有獨立的做用域,其餘模塊默認沒法直接訪問當前模塊中定義的成員。

默認導入導出方式

1.默認導入

默認導入的語法可使用任何合法的名稱來進行接收
import 接收名稱 from '模塊名稱'
複製代碼

2.默認導出語法:

export default {

    a:a
}
複製代碼
按需導入和導出
  1. 按需導入語法: import { 成員名稱 } from '模塊名稱'
  2. 按需導出語法: export var a = 10

在項目中安裝和配置

webpack 是前端的一個工具,這個工具,能夠從NPM官網上下載到本地使用;

  1. 新建一個項目的空白目錄,並在在終端中,cd到項目的根目錄,執行npm init -y 初始化項目
  2. 裝包:運行 npm i webpack webpack-cli -D 安裝項目構建所須要的 webpack
  3. 打開 package.json文件,在 scripts 節點中,新增一個 dev 的節點:
  4. 在項目根目錄中,新建一個 webpack.config.js 配置文件,內容以下
{
  "name": "code2",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev":"webpack" 
  },

複製代碼
  1. 在項目根目錄中,新增一個 src 目錄,而且,在 src 目錄中,新建一個 index.js 文件,做爲 webpack 構建的入口;會把打包好的文件輸出到 dist -> main.js
  2. 在終端中,直接運行 npm run dev 啓動webpack進行項目構建;

實現webpack的實時打包構建

  1. 藉助於 webpack-dev-sever 這個工具,可以實現 webpack 的實時打包構建;
  2. 運行npm i webpack-dev-server -D 安裝包
  3. 打開package.json文件,把 scripts 節點下的 dev 腳本,修改成以下配置:
"scripts": {
           "test": "echo \"Error: no test specified\" && exit 1",
           "dev": "webpack-dev-server"
         },
複製代碼
  1. 修改 index.html 文件中的 script 的 src, 讓 src 指向 內存中根目錄下的 /main.js
<script src="/main.js"></script>
複製代碼

使用html-webpack-plugin插件配置啓動頁面

  1. 裝包npm i html-webpack-plugin -D
  2. 在 webpack.config.js中,導入 插件:
// 導入 html-webpack-plugin,從而幫咱們自動把 打包好的 main.js 注入到 index.html 頁面中
       // 同時,html-webpack-plugin 能夠把 磁盤上的 index.html 頁面,複製一份並託管到 內存中;
       const HtmlPlugin = require('html-webpack-plugin')
       const htmlPlugin = new HtmlPlugin({
         // 傳遞一個配置對象
         template: './src/index.html', // 指定路徑,表示 要根據哪一個物理磁盤上的頁面,生成內存中的頁面
         filename: 'index.html' // 指定,內存中生成的頁面的名稱
       })
複製代碼
  1. 把 建立好的 htmlPlugin 對象,掛載到 plugins數組中:
// webpack 這個構建工具,是基於 Node.js 開發出來的一個前端工具
       module.exports = {
         mode: 'development', // 當前處於開發模式
         plugins: [htmlPlugin] // 插件數組
       }
複製代碼

實現自動打開瀏覽器、熱更新和配置瀏覽器的默認端口號

  • --open 自動打開瀏覽器
  • --host 配置IP地址
  • --port 配置 端口號
  • --hot 熱更新;最新的代碼,以打補丁的形式,替換到頁面上,加快編譯的速度;

webpack打包非js文件

webpack打包css文件

因爲webpack只能打包js文件,因此對於非js文件就須要單獨進行處理

使用webpack打包css文件

  1. 運行 npm i style-loader css-loader -D
  2. 打開 webpack.config.js 配置文件,在 module -> rules 數組中,新增處理 css 樣式表的loader規則:
module: { // 全部 非.js 結尾的第三方文件類型,均可以在 module 節點中進行配置
           rules: [ // rules 是匹配規則,若是 webpack 在打包項目的時候,發現,某些 文件的後綴名是 非 .js 結尾的
             // webpack 默認處理不了,此時,webpack 查找 配置文件中的 module -> rules 規則數組;
             { test: /\.css$/, use: ['style-loader', 'css-loader'] }
           ]
         }
複製代碼
注意:因爲使用非js文件打包,都須要對他進行loader的出來,可是這裏css-loader也有他本身的調用順序,這裏這個loader的調用時逆向的,先調用css-loader,而後再調用style-loader
複製代碼

使用webpack打包less文件

  1. 運行 npm i less-loader less -D
  2. 在 webpack 的配置文件中,新增一個 rules 規則來 處理 less 文件:
{ test: /\.less$/, use: ['style-loader', 'css-loader', 'less-loader'] }
複製代碼
注意:只要是樣式表,在他的loader配置中都須要加上style-loader和css-loader這兩個選項。
複製代碼

使用webpack處理css中的路徑

  1. 運行 npm i url-loader file-loader -D
  2. 在 webpack 的配置文件中,新增一個 rules 規則來 處理 圖片 文件:
{ test: /\.jpg|png|gif|bmp$/, use: 'url-loader' }
複製代碼

webpack中使用bootstrap

  1. 運行 npm i bootstrap 對bootstrap裝包
  2. 在webpack中使用bootstrap自己沒有問題,可是因爲boostrap自己引入了其餘的字體的樣式表,這裏又只能打包的是js文件,因此這裏還須要字體樣式表的loader
{ test: /\.eot|woff|woff2|ttf|svg$/, use: 'url-loader' }
複製代碼

默認狀況下,若是導入的模塊是路徑,webpack會優先去node_modules目錄下,查找指定的路徑是否存在

注意:這裏打包字體文件和loader和打包處理圖片的loader都是url-loader
複製代碼

使用babel處理高級JS語法

1.因爲webpack默認只能打包處理一部分高級的js的語法,若是某些js語法,過於高級,則webpack也是處理不了的,此時只能藉助於babel這個插件,來打包處理高級的js語法 2.運行兩套命令,去安裝相關的 loader:

- 運行 npm i babel-core babel-loader babel-plugin-transform-runtime -D
- 運行 npm i babel-preset-env babel-preset-stage-0 -D
複製代碼
  1. 添加 babel-loader 配置項:
// 注意:在配置 babel-loader 的時候,必定要添加 exclude 排除項,把 node_modules 目錄排除
       // 這樣,只讓 babel-loader 轉換 程序員 本身手寫的 JS 代碼;
       // 好處:1. 可以提升編譯的轉換效率; 2. 可以防止沒必要要的報錯!
       { test: /\.js$/, use: 'babel-loader', exclude: /node_modules/ }
複製代碼
  1. 在項目根目錄中,添加 .babelrc 配置文件:
{
         "presets": ["env", "stage-0"],
         "plugins": ["transform-runtime"]
       }

複製代碼

基礎知識四

在 webpack 中安裝和配置 vue

  1. 運行 npm i vue -S 把 vue 安裝到項目依賴
  2. 在 index.js 中使用 import 導入 vue 模塊:
import Vue from 'vue'
複製代碼
  1. 在 index.html 中建立未來要被 vm 實例控制的 div:
<!-- 未來,這個 div 就是 Vue實例 要控制的區域 -->
       <div id="app"></div>
複製代碼
  1. 在 index.js 中建立 vm 實例,並使用 el 指定要控制的區域,使用 data 指定要渲染的數據:
const vm = new Vue({
         el: '#app', // 要控制的區域
         data: {
           msg: 'ok' // 要渲染的數據
         }
       })
複製代碼

爲何在基於 webpack 的 vue項目中, 按照如上操做會報錯呢

  1. 由於使用 import 導入的 vue 模塊,導入的並非功能最全的 vue 包;而是刪減版的;
  2. 刪減版的 vue 包中功能不多,目的是爲了減少vue 包的體積,由於文件越小,網絡請求越快!
  3. 如何讓 import 導入最全的 vue 包呢?
- 把 import Vue from 'vue' 改寫爲 import Vue from 'vue/dist/vue.js'
複製代碼
  1. 注意:在學習階段,能夠暫時 import 最全的 vue 包;等開發項目的時候,必定要使用 刪減版的 包;

定義Vue組件

模塊化和組件化的概念解讀

  1. 什麼是模塊化:是從代碼的角度分析問題;把可複用的代碼,抽離爲單獨的模塊;
    • 模塊化的好處:
      • 提供模塊做用域的概念,防止全局變量污染;
      • 提升了代碼的複用率,方便了程序員之間 共享代碼;
  2. 什麼是組件化:組件化是從頁面UI的角度進行分析問題的;把頁面中可複用的UI結構,抽離爲單獨的組件;
    • 組件化的好處:
      • 方便了UI結構的重用;
      • 隨着項目開發的深刻,手中可用的組件會愈來愈多;
      • 能夠直接使用第三方封裝好的組件庫;
      • 組件化可以讓程序員更專一於本身的業務邏輯;

定義全局組件

1.定義組件的語法

  • Vue.component('組件的名稱', { 組件的配置對象 });

  • 在組件的配置對象中:可使用 template 屬性指定當前組件要渲染的模板結構;

Vue.component('my-test',{
    template:`<div>這是我定義的第一個Vue組件</div>`
});
注意:這裏的組件名稱最好都寫成是小寫的,而且中間最好用-鏈接一下
複製代碼
  • 在組件的配置對象中:可使用 template 屬性指定當前組件要渲染的模板結構;

2.使用組件的語法(全局組件)

  • 把 組件的名稱, 以標籤的形式,引入到頁面上就行; 注意:

  • 從更抽象的角度來講,每一個組件,就至關因而一個自定義的元素;

  • 組件中的DOM結構,有且只能有惟一的根元素(Root Element)來進行包裹!

Vue.component('my-test',{
    template:`<div> <div>這是我定義的第一個Vue組件</div> <div>這是我定義的第一個Vue組件</div> </div>`
});
複製代碼

3.使用組件的語法(私有組件)

注意:定義私有組件,只能在定義區域內使用,超出定製區域內使用無效,會報錯誤

const vm = new Vue({
    el: '#app',
    data: {
        msg: 'Hello World!'
    },
    components: {
        //使用compoents屬性定義的組件,叫作是私有組件 
        // '組件名稱':{/組件的配置對象/}
        'my-test2': {
            template: `<div>這是私有組件</div>`
        }
    }
})
複製代碼

組件中定義data數據、methods方法以及生命週期函數

組件中定義data數據
Vue.component('my-test', {
    template: `<div> <div>這是我定義的第一個Vue組件{{d1}}</div> <div>這是我定義的第一個Vue組件</div> </div>`,
    // 注意Vue規定,組件中的data必須是function函數,並且必須return一個對象
   data(){
    // return 當前實例對象
       return {
           d1:'111'
       }
   }
});
複製代碼

區分vm實例中定義data數據

//在vm實例中,data既能夠是對象也能夠方法,可是在組件中只能是方法
const vm = new Vue({
    el: '#app',
    // data: {
    //     msg: 'Hello World!'
    // },
    data() {
        return {
            msg: 'Hello World!'
        }
    },
    components: {
        //使用compoents屬性定義的組件,叫作是私有組件 
        // '組件名稱':{/組件的配置對象/}
        'my-test2': {
            template: `<div>這是私有組件</div>`
        }
    }
})
複製代碼
組件中定義本身的methods,fifters以及生命週期函數
Vue.component('my-test', {
    template: `<div> <div @click="show">這是我定義的第一個Vue組件{{d1}}</div> <div>這是我定義的第一個Vue組件</div> </div>`,
    // 注意Vue規定,組件中的data必須是function函數,並且必須return一個對象
   data(){
    // return 當前實例對象
       return {
           d1:'111'
       }
   },
   //組件中也能夠有本身的私有方法
   methods: {
       show(){
           console.log('調用了自定義組件中的show方法')
       }
   },
    //組件中也能有本身的私有過濾器
    filters:{
        testFilter(originval){
            return originval+'~~~'
        }
    } ,
    // 組件也能夠有本身的聲明周期函數
    created() {
        console.log('調用了created函數')
;    },
複製代碼
組件和實例的區別
  1. 組件中的 data 必須是一個 function 並 return 一個 字面量對象;在 Vue 實例中,實例的 data 既能夠是 對象,能夠是 方法;

  2. 組件中,直接經過 template 屬性來指定組件的UI結構;在 Vue 實例中,經過 el 屬性來指定實例控制的區域;可是實例也可使用 template;

  3. 組件和實例,都有本身的生命週期函數,私有的過濾器,methods 處理函數;

爲何組件中的 data 屬性必須定義爲一個方法並返回一個對象

主要是內存中存儲的地址不同,具體操做能夠看下圖的指示:

.vue單文件組件

  • 爲何要把組件,單獨的定義到 .vue 文件中?

    • 以前建立組件太麻煩,沒有智能提示和代碼高亮;
    • 以前定義組件,和其它JS代碼邏輯摻雜在一起,代碼不易維護,沒有把組件化的優點發揮到極致!
  • 每一個 .vue 文件,都是一個 vue 組件(叫作 單文件組件),它由三部分組成:

    1. template 結構
    2. script 行爲
    3. style 樣式
<template>
    <div>
        <!--注意單文件中的template節點只能有惟一的父元素進行包裹  -->
        <h3>這是使用.vue文件定義單文件組件---{{msg}}</h3>
    </div>
</template>
<script>
// 行爲中固定寫法
// 當前組件中私有的data數據
export default {
    data(){
        return {
            msg:'hello .vue文件'
        }
    },
    methods:{},
    filters:{},
    created(){}
}
</script>
<style >
h3{
    color: red;
}
</style>
複製代碼

在webpack中配置.vue組件頁面的解析

// 導入單文件組件
import Home from './components/HOME.vue';
//把單文件組件,以Vue.compondent註冊爲全局組件
Vue.component('my-home',Home);
複製代碼

從上述代碼中能夠看出,當前導入的是.vue文件,不是以js爲後綴名的文件,同時也不是咱們以前處理的文件類型,因此這裏在瀏覽器運行就會報出一個沒有loader的錯誤.

  1. 運行npm i vue-loader vue-template-compiler -D
  2. 添加rules匹配規則:
{ test: /\.vue$/, use: 'vue-loader' }
複製代碼
  1. 在webpack.config.js中導入並配置插件:
// 導入插件
       const VueLoaderPlugin = require('vue-loader/lib/plugin')
       // new 一個插件的實例對象
       const vuePlugin = new VueLoaderPlugin()
       
       // 把 new 出來的插件實例對象,掛載到 `plugins` 節點中:
       plugins: [...其它插件, vuePlugin]
複製代碼

導入並使用 .vue 組件的兩種方式

全局註冊 .vue 文件:

  • 在 index.js 中導入 .vue 組件
  • 使用 Vue.component() 把導入的 .vue 組件,註冊爲全局組件
// 導入單文件組件
import Home from './components/HOME.vue';
//把單文件組件,以Vue.compondent註冊爲全局組件
Vue.component('my-home',Home);

const vm=new Vue({
    el:'#app',
    data:{

    }
})
複製代碼

2.私有註冊 .vue 文件:

  • 定義兩個獨立的組件 Home.vue 和 Son.vue
  • 在 Home.vue 組件中,導入 Son.vue 文件,並使用 Home.vue 組件的 components 屬性,把 Son.vue 註冊爲本身的私有子組件
//導入son組件
import Son from './Son.vue';

// 行爲中固定寫法
// 當前組件中私有的data數據
export default {
    data(){
        return {
            msg:'hello .vue文件'
        }
    },
    // 在.vue文件中,能夠經過components屬性,將另一個.vue組件,定義爲本身的私有組件
    
    components:{
        'my-son':Son,
    }
}
複製代碼

組件中的樣式問題

因爲咱們指望在組件中的樣式只在當前組件中生效,可是咱們經過運行能夠發現,子組件在父組件中使用,他也被父組件的樣式影響,這個是由於默認狀況下,組件中定義的樣式是全局組件,因此可使用下面的這種方法:

<style  scoped>

/* 咱們指望在組件中的樣式只在當前組件中生效 */
/* 因此從此,咱們都須要給組件的style添加scoped,防止樣式衝突 */

  h3 {
    color: red;
  }

</style>>
複製代碼

若是咱們但願使用標籤嵌套的方式,也就是less的文件樣式,就須要添加一個lang="less"屬性,

<style lang="less" scoped>
/* 咱們指望在組件中的樣式只在當前組件中生效 */
/* 因此從此,咱們都須要給組件的style添加scoped,防止樣式衝突 */
.home-box {
    border: 1px solid #000;
  h3 {
    color: red;
  }
}
</style>>

複製代碼

組件之間的數據通訊

父組件向子組件傳遞普通數據

1.在父組件中,以標籤形式使用子組件的時候,能夠經過屬性綁定,爲子組件傳遞數據:

<my-son :pmsg1="parentMsg" :pinfo="parentInfo"></my-son>
複製代碼

2.在子組件中,若是向用父組件傳遞過來的數據,必須先定義 props 數組來接收:

<script>
  export default {
    data(){
      return {}
    },
    methods: {},
    // property 屬性
    // 注意:父組件傳遞到子組件中的數據,必須通過 props 的接收,才能使用;
    // 經過 props 接收的數據,直接能夠在頁面上使用;注意:不接受,不能使用外界傳遞過來的數據
    props: ['pmsg1', 'pinfo']
  }
</script>
複製代碼

3.接收完的props數據,能夠直接在子組件的 template 區域中使用:

<template>
  <div>
    <h3>這是子組件 --- {{pmsg1}} --- {{pinfo}}</h3>
  </div>
</template>
複製代碼

具體操做能夠看下圖:

注意:父組件傳遞給子組件的成員數據props都是可讀數據,不要爲他們從新賦值,
可是data數據都是當前屬性的私有數據,並且data中的數據都是可讀可寫的
因爲props中的數據都是隻讀的,因此若是想爲props數據從新複製,能夠把數據轉存到data中,從而實現從新賦值
複製代碼

因爲上述進行值的傳遞和轉存的時候,都是簡單的數據類型的值,因此若是變成是引用數據類型的值,就會出現值會同時修改的狀況,因此這裏須要進行深拷貝操做,這裏進行深拷貝操做的是利用一個包lodash:

import _ from 'lodash';
export default {
  data(){
    // 對於轉存修改屬性只是簡單數據類型能夠轉,對於複雜數據類型還須要另外進行操做
    return {
      infoFromParent:this.pinfo,
      msgFromParent:_.cloneDeep(this.pmsg)
    }
  },
    // 子組件須要使用props按鈕,接收外界傳遞過來的數據
  props:['pmsg','pinfo']
}
複製代碼

經過_cloneDeep(傳遞一個對象),這樣就能夠實現深拷貝,而且返回的是一個全新的對象,修改他的值,不會影響其餘的值.

父組件向子組件傳遞方法(屬性綁定)

  1. 若是父向子傳遞方法,須要使用 事件綁定機制:
<my-son @func="show"></my-son>
複製代碼

其中,爲 子組件傳遞的 方法名稱爲 func, 具體的方法引用,爲 父組件中的 show 方法 2. 子組件中,能夠直接經過 this.$emit('func') 來調用父組件傳遞過來的方法;

子組件向父組件傳值(事件綁定)

  1. 子向父傳值,要使用 事件綁定機制@;

  2. 父向子傳遞一個方法的引用

  3. 子組件中,可使用 this.$emit() 來調用父組件傳遞過來的方法

  4. 在使用this.$emit()調用 父組件中方法的時候,能夠從第二個位置開始傳遞參數;把子組件中的數據,經過實參,傳遞到父組件的方法做用域中;

methods: {
    // 點擊子組件中的按鈕,觸發按鈕的點擊事件
    btnHandle(){
      // 在子組件中經過this.$emit()方法,觸發父組件,爲子組件綁定func事件

      this.$emit('func' +this.msg)
    }

  },
複製代碼
  1. 父組件就能夠經過形參,接收子組件傳遞過來的數據;

兄弟組件之間傳值

注意:兄弟組件之間,實現傳值,用到的技術,是 EventBus

  1. 定義模塊 bus.js
import Vue from 'vue'
       
   export default new Vue()
複製代碼
  1. 在須要接收數據的兄弟組件中,導入 bus.js 模塊
import bus from './bus.js'
複製代碼
  1. 在須要接收數據的兄弟組件中的 created 生命週期函數裏, 使用 bus.$on('事件名稱', (接收的數據) => {}) 自定義事件:
created(){
         // 定義事件
         bus.$on('ooo', (data)=>{
           console.log(data)
         })
       }
複製代碼
  1. 在須要發送數據的兄弟組件中,導入 bus.js 模塊
import bus from './bus.js'
複製代碼
  1. 在須要發送數據的兄弟組件中,使用 bus.$emit('事件名稱', 要發送的數據) 來向外發送數據:
import bus from './bus.js'
       export default {
           data(){
             return {
               msg: 'abcd'
             }
           },
           methods: {
             sendMsg(){
               // 觸發 綁定的 事件,並向外傳遞參數
               bus.$emit('ooo', this.msg)
             }
           }
       }

複製代碼

使用 this.$refs來獲取元素和組件

1.把要獲取的DOM元素,添加 ref 屬性,建立一個DOM對象的引用,指定的值,就是引用的名稱:

//經過ref獲取的DOM元素的引用就是一個元素的DOM對象
<p ref="myElement11">這是父組件</p>
複製代碼
  1. 若是要獲取 某個引用所對應的 DOM對象,則直接使用 this.$refs.引用名稱
console.log(this.$refs.myElement11)
複製代碼
  1. 也可使用 ref 爲組件添加引用;可使用 this.$refs.組件應用名稱,
console.log(this.$refs.myElement11)
複製代碼

3.也可使用 ref 爲組件添加引用;可使用 this.$refs.組件應用名稱, 拿到組件的引用,從而調用組件上的方法 和 獲取組件data上的 數據;

使用 霸道的 render 函數渲染組件

  1. 若是在 vm 實例中既指定了 el 又指定了 render 函數,則會把 el 所指的的區域,替換爲 render 函數中所提供的組件;

  2. 既然 render 函數會替換到 el 區域內的全部代碼,也會讓 template 屬性失效;所以,在刪減版的 vue 包中,new 出來的 Vue 實例對象,不容許 掛載 data 屬性和 template 屬性!

const vm = new Vue({
  el: '#app',
  // createElements 形參是一個方法,專門用於渲染一個組件,並替換掉 el 區域
  /* render: function(createElements){ return createElements(App) }, */
  // 這是 render 的終極格式
  // 被render渲染的組件,叫作 根組件
  // 什麼是根組件:【不論瀏覽器中的頁面如何切換,根組件永遠都在頁面上顯示】
  render: h => h(App)
})

// 注意:只要在 vm 實例中,指定了 render 函數來渲染組件,那麼,el 區域,就會被 render 中渲染的組件替換掉;

複製代碼

基礎知識五

使用標籤實現組件切換

  1. 是Vue提供的;做用是 把 is 指定的 組件名稱,渲染到 內部
  2. 身上有一個 :is屬性
<template>
  <div>
    <h1>App 根組件</h1>
    <button @click="comName='my-home'">Home</button>
    <button @click="comName='my-movie'">Movie</button>
    <!-- 能夠經過 component 的is屬性,動態指定要渲染的組件 -->
    <component :is="comName"></component>
  </div>
</template>

<script>
import Home from './coms/Home.vue'
import Movie from './coms/Movie.vue'
export default {
  data() {
    return {
      // 默認是展現home屬性的
      comName: 'my-home'
    }
  },
  components: {
    'my-home': Home,
    'my-movie': Movie
  }
}
</script>
複製代碼

SPA單頁應用

錨連接及常規url的區別

  1. 普通的URL地址:會刷新整個頁面;會追加瀏覽歷史記錄;
  2. 錨連接:不會觸發頁面的總體刷新;會追加瀏覽歷史記錄;(錨連接是頁面內的跳轉)

什麼是SPA,爲何有SPA

  • 概念定義:SPA英文全稱是Single Page Application, 中文翻譯是 「單頁面應用程序」;
  • 通俗的理解是:只有一個Web頁面的網站;網站的全部功能都在這個惟一的頁面上進行展現與切換;
  • 特色:
    • 只有一個頁面
    • 瀏覽器一開始請求這個頁面,必須加載對應的HTML, CSS, JavaScript
    • 用戶的全部操做,都在這惟一的頁面上完成
    • 頁面數據都是用Ajax請求回來的
  • 好處:
    • 實現了先後端分離開發,各司其職;提升了開發效率;
    • 用戶體驗好、快,內容的改變不須要從新加載整個頁面;
  • 缺點:
    • 對SEO不是很友好,由於頁面數據是Ajax渲染出來的; (Server Side Render)服務器端渲染;
    • 剛開始的時候加載速度可能比較慢;項目開發完畢以後,能夠單獨對首屏頁面的加載時間作優化;
    • 頁面複雜度比較高,對程序員能力要求較高;

原生實現SPA

使用 component 標籤的:is屬性來切換組件

總結:單頁面應用程序中,實現組件切換的根本技術點,就是 監聽 window.onhashchange 事件;

路由

什麼是路由:路由 就是 對應關係;

  1. 後端路由的定義:URL地址 到 後端 處理函數之間的關係;
  2. 前端路由的定義:hash 到 組件 之間的對應關係;
  3. 前端路由的目的:爲了實現單頁面應用程序的開發;
  4. 前端路由的三個組成部分:
    • 連接
    • 組件
    • 連接 和 組件之間的對應關係

在 vue 中使用 vue-router【重點】

  1. 安裝導入並註冊路由模塊:
    • 運行 npm i vue-router -S 安裝路由模塊
    • 在 index.js 中導入並註冊路由模塊
// 導入路由模塊
         import VueRouter from 'vue-router'
         // 註冊路由模塊(把路由模塊安裝到Vue上)
         Vue.use(VueRouter)
複製代碼
  1. 建立路由連接:
<!-- router-link 就是 第一步,建立 路由的 hash 連接的 -->
<!-- to 屬性,表示 點擊此連接,要跳轉到哪一個 hash 地址, 注意:to 屬性中,你們不須要以 # 開頭 -->
<router-link to="/home">首頁</router-link>
<router-link to="/movie">電影</router-link>
<router-link to="/about">關於</router-link>
複製代碼

3.建立並在 index.js 中導入路由相關的組件:

import Home from './components/Home.vue'
import Movie from './components/Movie.vue'
import About from './components/About.vue'
複製代碼

4.建立路由規則

// 建立路由規則(對應關係)
const router = new VueRouter({ // 配置對象中,要提供 hash 地址 到 組件之間的 對應關係
  routes: [ // 這個 routes 就是 路由 規則 的數組,裏面要放不少的對應關係
    // { path: 'hash地址', component: 配置對象 }
    { path: '/home', component: Home },
    { path: '/movie', component: Movie },
    { path: '/about', component: About }
  ]
})
// 建立的 router 對象,千萬要記得,掛載到 vm 實例上
const vm = new Vue({
  el: '#app',
  render: c => c(App),
  router // 把 建立的路由對象,必定要掛載到 VM 實例上,不然路由不會生效
})
複製代碼

5.在頁面上放路由容器

<!-- 這是路由的容器,未來,經過路由規則,匹配到的組件,都會被展現到這個 容器中 也就是切換的內容會在下面的這個區域進行顯示 -->
<router-view></router-view>
或者是直接寫成是單閉合標籤
<router-view />
複製代碼

路由規則的匹配過程

  1. 用戶點擊 頁面的 路由連接router-link,點擊的一瞬間,就會修改 瀏覽器 地址欄 中的 Hash 地址;
  2. 當 hash 地址被修改之後,會當即被 vue-router 監聽到,而後進行 路由規則的 匹配;最終,找到 要顯示的組件;
  3. 當 路由規則匹配成功之後,就找到了 要顯示的 組件,而後 把 這個組件,替換到 頁面 指定的 路由容器router-view 中

設置路由高亮的兩種方式

  1. 經過路由默認提供的router-link-active, 爲這個類添加本身的高亮樣式便可;
<style lang="less" scoped> .router-link-active { color: red; font-weight: bold; } </style>

複製代碼
  1. 經過路由構造函數,在傳遞路由配置對象的時候,提供 linkActiveClass 屬性,來覆蓋默認的高亮類樣式;
// 3. 建立路由實例對象
const router = new VueRouter({
  routes: [
    // 路由?  就是對應關係
    // 前端路由? hash => 組件 之間的對應關係
    // vue 中路由的格式     { path, component }
    // path 路由hash地址中,路徑必須以 / 開頭,並且必須是小寫,並且不能帶空格
    { path: '/home', component: Home },
    { path: '/movie', component: Movie },
    { path: '/about', component: About },
    { path: '/me', component: Me }
  ],
  linkActiveClass: 'my-active' // 若是你們作項目時候, 用到的 UI 組件庫中,提供了默認的高亮效果
})


//在頁面上的顯示類名以下:

.my-active {
  color: #007ACC;
  font-weight: 700;
}
複製代碼

嵌套路由(子路由)

  1. 在對應的路由組件中,新增 router-link 路由連接;
  2. 建立 router-link 對應要顯示的組件;
  3. 在對應的路由規則中,經過 children 屬性,定義子路由規則:
const router = new VueRouter({
  routes: [
    // 路由? 就是對應關係
    // 前端路由? hash => 組件 之間的對應關係
    // vue 中路由的格式 { path, component }
    // path 路由hash地址中,路徑必須以 / 開頭,並且必須是小寫,並且不能帶空格
    // 在路由規則中,經過 redirect 屬性,指向一個新地址,就可以實現路由的重定向
    { path: '/', redirect: '/home' },
    { path: '/home', component: Home },
    { path: '/movie', component: Movie },
    // 在某個路由規則中,如何嵌套子路由規則? path 和 component 平級,還有個 children 屬性
    // children 屬性 是一個數組, 做用,就是來嵌套子路由規則的
    {
      path: '/about',
      component: About,
      redirect: '/about/tab1',
      children: [
        { path: '/about/tab1', component: Tab1 },
        { path: '/about/tab2', component: Tab2 }
      ]
    },
    { path: '/me', component: Me }
  ],
  linkActiveClass: 'my-active' // 若是你們作項目時候, 用到的 UI 組件庫中,提供了默認的高亮效果
})

複製代碼

路由傳參

經過屬性綁定實現路由傳參,也就是在路由規則的參數項以前加冒號實現路由傳參

<!-- 當router-link的to地址,要動態進行拼接的時候,那麼,必定要把 to 設置成屬性綁定的形式 -->
      <router-link v-for="item in mlist" :key="item.id" :to="`/mdetail/${item.id}/${item.name}`" tag="li">{{item.name}}</router-link>
複製代碼

可是仍是可能會出現參數不固定的狀況

const router = new VueRouter({
  routes: [
    { path: '/', component: MovieList },
    // 把路由規則中, 參數項位置,前面加上 : 表示這是一個參數項
    // props: true 表示,爲當前路由規則,開啓 props 傳參
    { path: '/mdetail/:id1/:name2', component: MovieDetail, props: true }
  ]
})

複製代碼
  1. 能夠在組件中,直接使用this.route.params 來獲取參數;【寫起來太麻煩,不推薦】
this.route是一個路由的參數對象, this.$router是路由的導航對象
  2. 也能夠開啓路由的 props 傳參,來接收路由中的參數;【推薦方式】
    1. 在須要傳參的路由規則中,添加 props: true
{ path: '/movie/:type/:id', component: movie, props: true }
複製代碼
  1. 在 對應的組件中,定義 props 並接收路由參數
const movie = {
                template: '<h3>電影組件 --- {{type}} --- {{id}}</h3>', // 使用參數
                props: ['type', 'id'] // 接收參數
              }
複製代碼

命名路由

什麼是命名路由: 就是爲路由規則,添加了一個 name ;

  1. 什麼是命名路由
  2. router-link中經過路由名稱實現跳轉
  3. 命名路由使用 params屬性傳參
<!-- 使用 命名路由實現跳轉 -->
       <router-link v-for="item in mlist" :key="item.id" :to="{name: 'moviedetail', params: {id1: item.id, name2:item.name}}" tag="li">{{item.name}}</router-link> 
複製代碼

編程式(JS)導航

以前所學的router-link是標籤跳轉;

除了使用router-link是標籤跳轉以外,還可使用Javascript來實現路由的跳轉;

  1. 什麼是編程式導航
    • 使用vue-router提供的JS API實現路由跳轉的方式,叫作編程式導航;
  2. 編程式導航的用法

//跳轉到指定的路由規則中

  • this.$router.push('路徑的地址')

//能夠前進和後退

  • this.$router.go(n)

//能夠前進

  • this.$router.forward()

//能夠後退

  • this.$router.back()

關於路由的方法的總結

  • this.$route是路由參數對象
  • this.$router是路由導航對象
  • vm實例上的router屬性,是掛載路由對象的
  • 在new VueRouter(/配置對象/)的時候,配置對象中,有一個routes屬性,是建立路由規則的
  • router單獨的寫在 vm實例對象裏面,表示掛載路由

path 是要匹配的hash值, component 要展現的組件 redirect 要重定向的路由 props 開啓props傳參 name 命名路由 children 嵌套子路由

路由導航守衛

  • 案例需求:只容許登陸的狀況下訪問 後臺首頁 ,若是不登陸,默認跳轉回登陸頁面;
  • API語法:
// 參數1:是要去的那個頁面路由相關的參數
      // 參數2:從哪一個頁面即將離開
      // 參數3:next 是一個函數,就至關於 Node 裏面 express 中的 next 函數
      // 注意: 這裏的 router 就是 new VueRouter 獲得的 路由對象
      router.beforeEach((to, from, next) => { /* 導航守衛 處理邏輯 */ })
複製代碼

案例核心代碼:

// 經過 路由導航守衛, 控制有權限頁面的訪問, 只有登陸之後,才容許訪問高級的頁面
router.beforeEach((to, from, next) => {
  // to.path 表示咱們下一刻要訪問哪一個地址
  // console.log(to)
  // from.path 表示咱們上一刻,所訪問的是哪一個地址
  // console.log(from)

  // next() 直接調用,表示放行
  // next()

  // 若是 要訪問的地址,是 /login, 證實用戶要去登陸, 沒有必要攔截,直接放行
  if (to.path === '/login') return next()
  // 若是用戶訪問的不是 登陸頁面,則 先嚐試從sessionStorage中獲取 token 令牌字符串
  const tokenStr = window.sessionStorage.getItem('token')
  // 若是沒有 token 令牌,則 強制用戶跳轉到登陸頁
  if (!tokenStr) return next('/login')
  // 若是有令牌,則直接放行
  next()
})
複製代碼

關於token驗證問題

token是一個令牌,是服務器端發送過來的客戶端必須經過登陸,才能獲取這個令牌,

watch 監聽

  • watch 監聽的特色:監聽到某個數據的變化後,側重於作某件事情;

    • 只要被監聽的數據發生了變化,會自動觸發 watch 中指定的處理函數;
  • 案例:登陸 密碼 的長度檢測

  • 密碼長度小於8位,字體爲紅色;大於等於8位,字體爲黑色;

export default {
  data() {
    return {
      uname: '',
      upwd: ''
    }
  },
  // watch 是監聽 data 中數據的變化, 側重於作某件事件
  watch: {
    upwd(newVal, oldVal) {
      if (newVal.length < 8) {
        this.$refs.pwdDOM.style.color = 'red'
      } else {
        this.$refs.pwdDOM.style.color = ''
      }
    }
  }
}
複製代碼

computed 計算屬性

計算屬性特色:同時監聽多個數據的變化後,側重於獲得一個新的值;

  • 只要依賴的任何一個數據發生了變化,都會自動觸發計算屬性的從新求值;
export default {
  data() {
    return {
      firstname: '',
      lastname: ''
    }
  },
  // 計算屬性
  computed: {
    // 定義一個計算屬性,叫作 fullName
    // 注意: 全部的計算屬性,在定義的時候, 都要被定義爲 function,
    // 可是,在頁面上使用計算屬性的時候, 是直接看成普通的 變量 來使用的,而不是看成方法去調用的!!!
    // 特色:只要計算屬性的 function 中,依賴的 任何一個數據發生了變化,都會對這個計算屬性,從新求值
    fullName: function() {
      return this.firstname + '-' + this.lastname
    }
  }
}

複製代碼

應用

若是頁面須要訪問一個數據,這個數據比較複雜,是須要經過其餘data通過複雜步驟製做出來的,那麼就能夠經過「計算屬性」簡化得到該數據

補充:Vue自己支持模板中使用複雜表達式表現業務數據,可是這會使得模板內容過於雜亂,若是確有需求,能夠經過computed計算屬性實現

與methods方法的區別:

computed計算屬性自己有「緩存」,在關聯的data沒有變化的狀況下,後續會使用緩存結果,節省資源

methods方法沒有緩存,每次訪問 方法體 都須要加載執行,耗費資源

複製代碼

使用 vue-cli 快速建立 vue 項目

爲何要使用 vue-cli 建立項目:

  • 在終端運行一條簡單的命令,便可建立出標準的 vue 骨架項目;
  • 沒必要本身手動搭建 vue 項目基本結構,省時省力;
  • 沒必要關心 webpack 如何配置,只關注於項目代碼的開發;

webpack 中 省略文件後綴名 和配置 @ 路徑標識符

省略文件擴展名:

  • 打開 webpack.config.js,在導入的配置對象中,新增 resolve 節點;
  • 在 resolve 節點中,新增 extensions 節點:
resolve: {
    // resolve 節點下的 extensions 數組中,能夠配置,哪些擴展名能夠被省略
    extensions: ['.js', '.vue', '.json']
}
複製代碼

修改完配置之後,從新運行 npm run dev 查看效果;

配置 @ 指向 src 目錄:

resolve: {
    alias: {
      '@': path.join(__dirname, './src') // 讓 @ 符號,指向了 項目根目錄中的 src
    }
  }
複製代碼

基礎知識六

自定義指令

全局自定義指令

  • 概念:在全局任何組件中均可以被調用的自定義指令,叫作全局自定義指令;
  • 語法:Vue.directive('全局自定義指令名稱', { /* 自定義指令配置對象 */ })
// Vue.directive('全局指令名稱', { /*指令的配置對象*/  })

// 注意:自定義指令名稱以前,不須要手動添加 v- 前綴
Vue.directive('red', {
  // 只要指令被解析指令了,就會優先調用指令中的 bind 方法
  bind(el) {
    // 只要bind被指向了,那麼el,就是它所綁定到的 UI 元素
    // el 是原生DOM對象,也正是由於他是原生的DOM對象,因此他才能夠經過style.color的方式修改樣式
    
    el.style.color = 'red'
  }
})
複製代碼

私有自定義指令

概念:只有指令所屬的組件中,才能夠被正常調用的指令,叫作私有自定義指令;

// 私有自定義指令的定義節點
  directives: {
    // 指令名稱: { /配置對象/ }
    blue: {
      bind(el) {
        el.style.color = 'blue'
      }
    }
  }
複製代碼

指令配置對象中 bind 和 inserted 的區別

  • bind 方法:
    • 綁定當前指令的元素,在內存中被建立的時候就會被當即調用;
    • 推薦把樣式相關的設置,都定義在 bind 方法中;
  • inserted 方法:
    • 綁定當前指令的元素,被插入到DOM樹以後纔會被調用;
    • 推薦把行爲相關的設置,都定義在 inserted 方法中;
  • 演示 bind 和 inserted 的區別:
    • 在終端中打印 el.parentNode 便可; 在bind中輸出的el.parentNode爲null, 可是在inserted中輸出的是他的父節點
Vue.directive('focus', {
  // bind 表示指令第一次被解析執行時候調用,此時,這個 DOM 元素,尚未被append到父節點中;
  // 此時只是在內存中存儲着,因此還你沒有渲染到頁面上
  bind(el) {
    // el.focus()
    // console.log(el.parentNode),null
  },
  // inserted 會在元素被插入到父節點以後,執行,此時已經渲染到頁面之上了
  inserted(el) {
    // 定義 文本框得到焦點的指令,只能經過 inserted 來實現
    // 由於 bind方法 和 inserted方法 的執行時機不同
    el.focus()
  }
})

// 總結:若是隻是單純的爲元素設置樣式,儘可能寫到 bind 中
// 若是要設置JS行爲,好比文本框獲取焦點,這種行爲,儘可能寫到 inserted 中

複製代碼

自定義指令傳參

Vue.directive('color', {
  // 經過 形參中的 binding 來接收指令傳遞過來的數據
  // 全部經過=傳過來的值都是在binding中存儲着
  // 傳遞過來的參數,是 binding.value 屬性
  bind(el, binding) {
    // console.log(binding.value)
    el.style.color = binding.value
  }
})
複製代碼

插槽

定義:定義子組件的時候,在子組件內部刨了一個坑,父組件想辦法往坑裏填內容;

單個插槽(匿名插槽)

  1. 定義插槽:在子組件做用域中,使用 定義一個插槽;
  2. 使用插槽:在父做用域中使用帶有插槽的組件時,組件內容區域中的內容,會插入到插槽中顯示;
  3. 注意:在一個組件的定義中,只容許出現一次匿名插槽

Son.vue子組件代碼:

<template>
    <div>
        <h4>這是子組件</h4>
        <p>哈哈哈</p>
        <!-- 沒有name屬性的插槽,稱爲是匿名插槽 -->
        <slot></slot>
        <!-- 注意:在同一個組件中,只容許定義一次插槽 -->
        <!-- <slot></slot> -->
        <p>heiehei</p>
    </div>
</template>
複製代碼

APP.vue主組件代碼展現:

<template>
    <div>
        <h1>這是父組件</h1>
        <hr>
        <!-- 在子組件的內部放置內容 -->
        <!-- 默認狀況下載組件內容中,定義的信息都會被顯示到匿名插槽中 -->
        <my-son>
            <img src="./images/土撥鼠啊.gif" alt="">
            <img src="./images/老王.png" alt="">
            <h3>6666</h3>
        </my-son>
    </div>
</template>
複製代碼

多個插槽(具名插槽)

  1. 定義具名插槽:使用 name 屬性爲 slot 插槽定義具體名稱;
<template>
    <div>
        <h1>這是子組件</h1>
        <p>啊,五環</p>
        <!-- 匿名插槽 -->
         <slot></slot>
        <p>你比四環多一環</p>
        <!-- 具名插槽 -->
        <slot name="s2"></slot>
        <p>啊,五環</p>
        <slot name="s3"></slot>
        <p>你比七環少兩環</p> 
    </div>
</template>
複製代碼
  1. 使用具名插槽:在父做用域中使用帶有命名插槽的組件時,須要爲內容指定 slot="插槽name" 來填充到指定名稱的插槽;
<template>
  <div>
    <h1>這是父組件</h1>
    <hr />
    <my-son>
      <!-- 默認狀況下指定的元素會被插入到匿名插槽中 -->
      <img src="../03默認插槽/images/一臉懵逼表情包.jpg" alt />
      <img slot="s2" src="../03默認插槽/images/土撥鼠啊.gif" alt />
      <img src="../03默認插槽/images/老王.png" alt />
      <img slot="s3" src="../03默認插槽/images/擅用百度.jpg" alt="">
    </my-son>
  </div>
</template>
複製代碼

做用域插槽

  1. 定義做用域插槽:在子組件中,使用 slot 定義插槽的時候,能夠經過 屬性傳值 的形式,爲插槽傳遞數據,
<template>
    <div>
        <h4>這是子組件</h4>
        <slot smsg="hello Vue" sinfo="你好"></slot>
        <p>
            ~~~~~~~~~~~~~~
        </p>
        <slot name="s2" :umsg="m1" :uinfo="m2">

        </slot>
    </div>
</template>
<script>
export default {
    data(){
        return {
            m1:'abcd',
            m2:'123456'
        }
    }
}
</script>
複製代碼
  1. 使用做用域插槽:在父做用域中,經過定義 slot-scope="scope" 屬性,接收並使用 插槽數據;
  2. 注意:同一組件中不一樣插槽的做用域,是獨立的!
<template>
    <div>
        <h1>這是父組件</h1>
        <hr>
        <my-son>
            <h6 slot-scope="scope">{{scope}}</h6>
            <!-- <h3 slot="s2" slot-scope="scope">{{scope}}</h3>
            <h3 slot="s2" slot-scope="scope">{{scope}}</h3> -->
            <!--  若是要接收做用域插槽中的數據,並且渲染爲多個標籤,
            則必須在多個標籤以外,包裹一個父元素,進行接收插槽中的數據
            -->
            <!-- 注意 template只起到包裹元素的做用,不會被渲染爲任何標籤-->
            <template slot="s2" slot-scope="scope">
                <h3>{{scope.uinfo}}</h3>
                <h3>{{scope.umsg}}</h3>
            </template>
        </my-son>
    </div>
</template>
複製代碼

element-ui

待更新....

1.element-ui 是 餓了麼 前端團隊,開源出來的一套 Vue 組件庫;

2.完整引入 Element-UI 組件:

1. 運行 yarn add element-ui -S 安裝組件庫
2. 在 index.js 中,導入 element-ui 的包、配套樣式表、而且安裝到Vue上:
複製代碼
// 導入 element-ui 這個包
import ElementUI from 'element-ui'
// 導入 配套的樣式表
import 'element-ui/lib/theme-chalk/index.css'

// 把 element-ui 安裝到 Vue 上
Vue.use(ElementUI)
複製代碼

3.按需導入和配置 Element-UI :

  1. 運行 npm i babel-plugin-component -D 安裝支持按需導入的模塊;
  2. 打開 .babelrc 配置文件,修改以下:
{
  "presets": ["@babel/preset-env"],
  "plugins": ["@babel/plugin-transform-runtime", "@babel/plugin-proposal-class-properties", 
    + [
    + "component",
    + {
    +   "libraryName": "element-ui",
    +   "styleLibraryName": "theme-chalk"
    + }
  ]]
}
複製代碼

使用vue-cli快速初始化vue項目

$ npm install -g vue-cli        // 全局安裝腳手架工具
$ vue init webpack my-project   // 初始化項目
$ cd my-project                 // 切換到項目根目錄中
$ npm install                   // 安裝依賴包
$ npm run dev                   // 一鍵運行項目
複製代碼

ESLint 語法檢查規範

  1. 聲明可是未使用的變量會報錯
  2. 空行不能連續大於等於2
  3. 在行結尾處,多餘的空格不容許
  4. 多餘的分號,不容許
  5. 字符串要使用單引號,不能使用雙引號
  6. 在方法名和形參列表的小括號之間,必須有一個空格
  7. 在單行註釋的 // 以後,必須有一個空格
  8. 在每個文件的結尾處,必須有一個空行
  9. import語句必須放到最頂部
  10. etc...

如何配置VSCode幫咱們自動把代碼格式爲須要的樣子

  1. 在安裝 Vetur 插件
  2. 安裝 Prettier - Code formatter 插件
  3. 打開 vs code 的 文件 -> 首選項 -> 設置,在用戶設置最底部的合適位置,添加以下配置:
// 使用 ESLint 規則
"prettier.eslintIntegration": false,
// 每行文字個數超出此限制將會被迫換行
"prettier.printWidth": 100,
// 使用單引號替換雙引號
"prettier.singleQuote": true,
// 格式化文件時候,不在每行結尾添加分號
"prettier.semi": false,
// 設置 .vue 文件中,HTML代碼的格式化插件
"vetur.format.defaultFormatter.html": "prettier"
複製代碼
  1. 重啓VS Code讓插件和配置生效!
  2. 打開vue-cli生成的項目中,.eslintrc.js配置文件,找到 rules 節點, 將以下語法規則,粘貼到 rules 配置中:
相關文章
相關標籤/搜索