Vue 基礎篇

Vue 基礎篇

一、框架與庫的區別

  • JQ庫->DOM(DOM操作) + Ajax請求
  • art-template庫->模板引擎
  • 框架 -> 全方位、功能齊全

    • 簡易的DOM體驗 + 發請求 + 模板引擎 + 路由功能 + ...
  • 代碼上的不同:

    • 一般使用庫:調用某個函數,自己可以把控庫的代碼
    • 一般使用框架:其框架在幫我們運行已編寫好的代碼

      • 框架:初始化自身的一些行爲
      • 執行你所編寫的代碼
      • 施放一些資源
庫:小而精

框架:大而全 ( 框架包含了各種庫 )

二、起步

  • 引包

    • 直接用 <script> 引入
    • CDN
    • NPM
npm install --yes
npm install vue --save ( npm install vue -S )
  • 創建實例化對象 new Vue( options 對象 )

    • options

      • el : 目的地( 選擇器 )
      • data : 數據屬性 ( 既可以是一個對象,也可以是一個函數 )

        • 數據驅動試圖:數據發生改變時,視圖 發生改變。
        • 除了數據屬性,vue 實例還暴露了一些有用的實例屬性和方法。他們都有前綴 $,如: $el,$data 。
      • template : 模板內容

        • 優先級:如果 template 中定義了內容,那麼有限加載 template;反之,加載 el 掛載的模板
  • vue的模板語法:

    • {{}} 雙大括號插值 同 react 中的 {}
    • {{ 表達式 }}

      • 對象 ( 不要連續三個大括號 {{ { key : value } }} )
      • 字符串 {{ ’XXX‘ }}
      • 判斷後的布爾值 {{ true }}
      • 三元表達式 {{ true ? '正確' : '錯誤' }}
    • 可以用於頁面中簡單粗暴的調試
    • 注意:必須在 data 這個函數中返回的對象中聲明
  • 設計模式:MVC 與 MVVM

    • MVC:Model( 數據模型 )、View( 視圖 )、Controller( 控制器 )

      • 數據不是主動展示到 視圖 上的,它是靠 控制器 取到 model 然後展示到 view。
    • MVVM:Model、View、ViewModel

      • vue的設計模式爲MVVM, 只關注的是視圖層

三、指令 ( v-xxx )

  • 在vue中提供了一些對於頁面+數據的更爲方便的輸出,這些操作就叫做指令

    • 比如html頁面中的屬性 <div v-xxx></div>
    • 指令中封裝了一些DOM行爲,結合屬性作爲一個暗號,暗號有對應的值,根據不同的值,框架會進行相關的DOM操作的綁定。
  • 常用指令

    • v-text:元素的InnerText屬性,其實就是給元素的innerText賦值,必須是雙標籤,跟{{}}效果是一樣的,使用較少。
    • v-html:元素的InnerHtml,其實就是給元素的innerHtml賦值
    • v-if:判斷是否插入這個元素,相當於對元素的銷燬和創建。appendChild()、removeChild()
    • v-else-if
    • v-else
    • v-show:隱藏元素,如果確定要隱藏,會給元素的style加上 display:none;,是基於css樣式的切換。
  • v-if 與 v-show 的區別 ( 官網解釋 )

    • v-if是“真正”的條件渲染,因爲它會確保在切換過程中條件塊內的事件監聽器和子組件適當的被銷燬和重建。
    • v-if也是惰性的:如果在初始渲染時條件爲假,則什麼也不做——直到條件第一次變爲真時,纔會開始渲染條件塊。
    • 相比之下,v-show就簡單的多——不管初始條件是什麼,元素總會被渲染。並且只是簡單的基於css進行 顯/隱 切換。
    • 一般來說,v-if有更高的切換開銷,而v-show有更高的初始渲染開銷。因此,如果需要非常頻繁的切換,則使用v-show較好;如果在運行時條件很少改變,則使用v-if較好。
  • v-bind:綁定標籤上的屬性( 內置的屬性和自定義的屬性 ),v-bind:class="box",簡寫 :
<div class="container" :class="{active: true}"></div>
// 渲染爲 DOM
<div class="container active"></div>
  • v-on:v-on:原生事件名 = '函數名',簡寫 @
// html
<div class="container" @click="clickHandler"></div>
// js
methods:{
    clickHandler(e){
        console.log(this);
    }
}
  • v-for:v-for="item,index in arr"
<ul>
    <li v-for="item,index in list">
        {{index}}--{{item}}
    </li>
</ul>
  • v-model:數據雙向綁定

    • 只會體現在UI空間中,只能應用在有value屬性的元素。
<input v-model="msg">
// 等同於
<input :value="msg" @input="msg = $event.target.value" />
那麼 v-model 其實就是 v-bindv-on 的語法糖。

四、組件

1.局部組件

局部組件使用打油詩:聲子掛子用子

聲明子組件;父組件掛載子組件;父組件使用子組件。
// 局部組件的聲明
var App = {
    data(){
        return{

        }
    },
    template:`
        <div>我是入口組件</div>
    `
}
// vue實例
new Vue({
    el:"",
    data(){

    },
    // 掛載子組件
    components:{
        App
    },
    // 父組件直接可以使用
    template:`<App />`
})
組件命名:

​ 1.短橫線分隔 命名:當引用組件時,也要使用 短橫線分隔 形式。( 如: <my-compnent-name> )

​ 2.駝峯式命名:當引用組件時,可以使用 短橫線分隔 形式或者 駝峯 形式。( 如: <my-compnent-name> 或 <MyCompnentName>)

​ [注]:直接在DOM( 即非字符串的模板 )中使用時只有 短橫線分隔 形式是有效的。

​ [建議]:命名時用 駝峯 形式,使用時用 短橫線分隔 形式。

2.全局組件

Vue.component("組件名", options)

// 全局組件聲明
// 第一個參數是組件的名字,第二個參數是options配置項
Vue.component("Vbtn", {
    template:`
        <button>按鈕</button>
    `
})
// 全局組件使用
var App = {
    template:`
        <div>
            ...
            <Vbtn />
        </div>
    `
}

五、組件通信

1.通過 prop 往子組件通信
  • 1.Parent 2.Child
  • 先給父組件中綁定自定義的屬性
Vue.component("Parent", {
    data(){
        return{
            msg:"我是父組件的數據"
        }
    },
    template:`
        <div>
            <p>我是父組件</p>
            <Child :childData="msg" />
        </div>
    `
})
  • 在子組件中使用 props 接收父組件傳遞的數據
  • 在子組件中任意使用
Vue.component("Child", {
    template:`
        <div>
            <p>我是子組件</p> 
            <input type="text" v-model="childData" />
        </div>
    `,
    props:["childData"]
})
2.通過 事件 向父組件發送消息
  • 在父組件綁定自定義的事件
  • 在子組件中 觸發原生的事件,在函數中使用 $emit 觸發其父組件中自定義的事件

    • $emit("自定義的事件名", "消息")
// Child
Vue.component("Child", {
    template:`
        <div>
            <p>我是子組件</p> 
            <input type="text" v-model="childData" @input="changeValue(childData)" />
        </div>
    `,
    props:["childData"],
    methods:{
        changeValue(val){
            // 自定義的事件一定要通過 this.$emit() 去觸發
            // $emit("自定義的事件名", "消息")
            this.$emit(childHandler, val)
        }
    }
})

// Parent
Vue.component("Parent", {
    data(){
        return{
            msg:"我是父組件的數據"
        }
    },
    template:`
        <div>
            <p>我是父組件</p>
            <Child :childData="msg" @childHandler="childHandlerFn" />
        </div>
    `,
    methods:{
        childHandlerFn(val){
            console.log(val);
        }
    }
})

六、插槽 slot

插槽:內置組件 slot,作爲承載分發內容的出口
/* 模擬 elementUI 按鈕組件的實現 */
// 子組件
Vue.component("Vbtn", {
    template:`
        <button class="default" :class="type">
            <slot>按鈕</slot>
        </button>
    `,
    props:["type"]
})

// 父組件
var App = {
    template:`
        <div>
            ...
            <Vbtn type="primary">登陸</Vbtn>
               <Vbtn type="success">註冊</Vbtn>
        </div>
    `
}
具名插槽
// 子組件
Vue.component("liItem", {
    template:`
        <li>
            第一個槽
            <slot name="idx-1"></slot>
            第二個槽
            <slot name="idx-2"></slot>
        </li>
    `
})

// 父組件
var App = {
    template:`
        <div>
            <ul>
                <liItem>
                    <h1 slot="idx-1">我是第一個槽</h1>
                    <h3 slot="idx-2">我是第二個槽</h3>
                </liItem>
            </ul>
        </div>
    `
}

七、過濾器

  • 過濾器的作用:爲頁面中的數據進行添油加醋的功能
  • 分類

    • 局部過濾器
    • 全局過濾器
/* 局部過濾器 */
// 1.聲明過濾器
// 2. {{ 數據 | 過濾器的名字 }}
var App = {
    data(){
        return{
            price:0,
            msg:"hello filter"
        }
    },
    template:`
        <div>
            <input type="number" v-model="price" />
            <!-- 使用過濾器 -->
            <h2>{{ price | myCurPrice }}</h2>
            <h3>{{ price | myReverse }}</h3>
        </div>
    `,
    filters:{
        // 聲明過濾器
        myCurPrice: function(val){
            return "¥" + val
        }
    }
}

/* 全局過濾器 */
// 字符串反轉過濾器
Vue.filter("myReverse", function(val){
    return val.split("").reverse().join("");
})

{{ 數據 | 過濾器的名字(可以傳值) }}

例:

​ {{ price | myReverse("這裏是傳入的值") }}

​ // 其中 arg 就是傳入的值

​ Vue.filter("myReverse", function(val, arg){
​ return val.split("").reverse().join("");
​ })

八、watch 監聽

watch 監聽的是單個屬性

基本的數據類型 -- 簡單監視

複雜的數據類型 -- 深度監視

  • 監聽簡單數據類型
new Vue({
    el:"",
    data(){
        return{
            msg : ''
        }
    },
    watch:{
        msg: function(newVal, oldVal){
            console.log(newVal, oldVal);
        }
    }
})
  • 監聽複雜數據類型 obj, arr, 等 -- 深度監視
new Vue({
    el:"",
    data(){
        return{
            userList : [{name:"jack"}]
        }
    },
    watch:{
        userList: {
            deep:true, // 深度監視
            handler: function(newVal, oldVal){
                console.log(newVal, oldVal);
            }
        }
    }
})

九、計算屬性

  • 計算屬性 getter
// html
<img :src="getCurSrc" />
<ul>
    <li v-for="item,index in dataList" @click="clickHandler(index)" :class="{active: curIdx == index}">{{ index }}</li>
</ul>

// js
new Vue({
    el:"",
    data(){
        return{
            dataList:[{imgsrc:'1'},{imgsrc:'2'},{imgsrc:'3'}],
            curIdx : 0
        }
    },
    computed:{
        // 計算屬性默認只有 getter
        getCurSrc: function(){
            return this.dataList[this.curIdx].imgsrc
        }
    },
    methods:{
        clickHandler(index){
            this.curIdx = index;
        }
    }
})
  • 計算屬性 setter
// js
new Vue({
    computed:{
        getCurSrc: {
            set: function(newVal){
                console.log(newVal);
                this.curIdx = newVal;
            },
            get: function(){
                return this.dataList[this.curIdx].imgsrc
            }
        }
    },
    methods:{
        clickHandler(index){
            // 點語法 set方法 和 get方法
            // getter 方法
            console.log(this.getCurSrc);
            // 調用set方法
            this.getCurSrc = index;
        }
    }
})

十、生命週期

  • beforeCreate:組件創建之前會調用
  • created:組件創建之後 會調用

    • 在created這個方法中可以操作後端的數據,數據驅動視圖
    • 應用:發起Ajax請求
  • beforeMount:掛載數據到 DOM 之前會調用
  • mounted:掛載數據到 DOM 之後會調用

    • 應用:操作DOM
  • beforeUpdate:在更新DOM之前 調用該鉤子

    • 應用:可以獲取原始的DOM
  • updated:在更新DOM之後 調用該鉤子

    • 應用:可以獲取最新的DOM
  • beforeDestroy:組件銷燬之前會調用
  • destroyed:組件銷燬之後會調用

vue 內置組件 <keep-alive></keep-alive>:能在組件的切換過程中將狀態保留在內存中,防止重複渲染DOM。

  • activated:組件被激活了
  • deactivated:組件被停用了

生命週期圖

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章