整理筆記:關於VUE基礎篇

1、基礎用法

MVVM模式:

MVVM是Model-View-ViewModel 的縮寫,它是一種基於前端開發的架構模式,其核心是提供對 View 和 ViewModel 的雙向數據綁定,這使得ViewModel 的狀態改變能夠自動傳遞給 View,即所謂的數據雙向綁定javascript

模板語法和指令

普一般用:

v-cloak //vue 未解析以前 通常配合用 [v-cloak] {display: none;}

v-bind 或者縮寫 <img :src="src" alt="" />
v-on   或者縮寫 <button @click="greet">Greet</button>  

v-text  <span v-text="msg"></span> || <span>{{msg}}</span>
//v-text 權重比{{}}高

v-html  <div v-html="html"></div>

v-show  <div v-show="show"></div>
//顯不顯示

v-if  v-else-if v-else  //條件 存不存在
        <div v-if="status"></div>

v-model  //表單元素,雙向綁定
        <input type="text" v-model="mess"/>

v-pre //不編譯,當字符串輸出
        <span v-pre>{{mess}}</span>

v-once  //內容解析一次,當改變值再改變也不映射修改
         <span v-once>{{mess}}</span>

循環v-for Array | Object | Number | Stringhtml

這個單獨拿出來寫 更清晰:
通常jsfor in是遍歷key,而for of遍歷value
一類:
data = {
  title: 'How to do lists in Vue',
  author: 'Jane Doe',
  publishedAt: '2016-04-10'
}
data = [{},{},{}]
<div v-for="(value, index) in data">
    <span>{{value}}</span>
    <span>{{index}}</span>
</div> 


二類:
data={
    "key1":{
        "aa":"1","bb":"2"
    },
    "key2":{
        "aa":"2","bb":"4"
    }
}
<div v-for="(item,key,index) of data">
    <span>{{item}}</span>
    <span>用of就能訪問到 key1|key2 :{{key}}</span>
    <span>{{index}}</span>
</div>

樣式綁定

綁定 class
對象:
<div :class="{classNam1: 1 == 1, className2: 1 == 2}"></div>
單個:
<div :class="classObject"></div>

數組:
<div :class="[class1, class2, 'className3', active ? 'className4' : '']"></div>
對應的data
data: {
    class1: 'className1',
    class2: 'className2',
    active: true
}

綁定再方法上:
 <div :class="classObjectComputed"></div>
computed: {
    classObjectComputed: function(){
        return{
            className1: true,
            className2: true
        }
    }
}
-----------------------------------------------------------------------


綁定style 

在對象當中,CSS 的屬性名要用駝峯式表達:fontSize 解析成 font-size

對象:
 <div :style="{color: color, fontSize: fontSize, backgroundColor: '#ccc'}"></div>
data: {
    color: 'red',
    fontSize: '12px'
}


數組:
<div :style="[styleObject, {backgroundColor: '#ccc'}]"></div>
data: {
    styleObject: {
        color: 'red',
        fontSize: '12px'
    }
}

事件修飾符 .**

<!--阻止事件冒泡.stop-->
    <div id="div1" class="stop" @click.stop="event1(1)">
    
    <!--使用事件捕獲模式.capture-->
    <div id="div4" class="stop" @click.capture="event1(4)">
    
    <!--事件只做用自己.self,相似於已阻止事件冒泡-->
    <div id="div7" class="stop" @click.self="event1(7)">
    
    <!--阻止瀏覽器默認行爲.prevent-->
    <a href="https://m.baidu.com" target="_blank" @click.prevent="prevent">dk's github</a>
    
    <!--只做用一次.once-->
    <a href="https://m.baidu.com" target="_blank" @click.once="prevent">dk's github</a>
    
    <!--修飾符能夠串聯.click.prevent.once-->
    <a href="https://m.baidu.com" target="_blank" @click.prevent.once="prevent">dk's github</a>

2、Vue實例化時基本屬性

實例元素 el

實例化在哪一個容器裏 若是有多個相同的實例元素則只有第一個起效。前端

##掛載方式一:
<div id="app"></div>
var vm = new Vue({
    el:"#app" //掛載方式一
})

----------------

##掛載方式二:
<div id="app"></div>
vm.$mount("#app"); //掛載方式二: 手動進行掛載
console.log(vm.$el) // 能夠經過實例獲取實例元素

數據對象 data

M(Model) 數據模型層 映射到V層。vue

關於視圖不更新

方法一: vm.set()
對象用法:vm.$set(Object, key, value)
數組用法:vm.$set(Array, index, Value)

1.對於對象,若是要給對象添加新的屬性,數據變化 視圖沒變化。java

Vue在初始化實例時進行雙向數據綁定,使用Object.defineProperty()對屬性遍歷添加 getter/setter 方法,因此setter屬性必須在 data 對象上存在時才能進行setter過程,觸發視圖響應。此時須要用到$set
#視圖不更新:this.dataform.username = '123'; // 直接賦值 在視圖上不顯示

#視圖更新:this.$set(this.dataform, 'username', '123'); //改用 $set 更新能夠在視圖上顯示

2.對於數組,因爲 JavaScript 的限制,Vue不能檢測如下變更的數組。node

//如下兩操做均沒法觸發視圖更新。其他操做正常,另外若是用到splice刪除後引發長度變化 注意
#視圖不更新:this.arr[index] = val; 
#視圖更新:this.$set(this.arr, index, val);

#視圖不更新:this.arr.length = 2;
#視圖更新:this.arr.splice(2);

//對於清空數組推薦
this.arr = [];
方法二:vm.forceUpdate()

但是若是咱們不想利用$set去設置,非要按照咱們第一種方式去寫,能夠實現麼?答案是能夠的,就是利用$forceUpdate了,由於你修改了數據,可是頁面層沒有變更,說明數據自己是被修改了,可是vue沒有監聽到而已,用$forceUpdate就至關於按照最新數據給渲染一下。git

change: function(index) {
    this.arr[index] = '9';
    this.$forceUpdate();
},
clearLen: function() {
    this.arr.length = 2;
    this.$forceUpdate();
}

事件處理器 methods

元素能夠經過事件進行綁定事件github

計算屬性 computed

主要是針對 data 的屬性進行操做,this的指針默認指向實例vm。
能夠像綁定普通屬性同樣在模板中綁定計算屬性api

<div id="example">
  <p>本來值: "{{ basicNum }}"</p>
  <p>計算後的值: "{{ countNum }}"</p>
</div>
<script>
  var vm = new Vue({
  el: '#example',
  data: {
    basicNum: 0
  },
  computed: {
    // 計算屬性的 getter
    countNum: function () {
      return Math.floor(this.basicNum*999/100);
    }
  }
})
</script>
// 設basicNum = 3  >> countNum = 29
// 設countNum = 28 報錯 由於計算屬性默認狀況下不支持set設值

默認只有getter沒有setting,只能讀取不能修改。 須要支持修改的話 要手動加上去 like this:數組

<div id="app">
    <!--fullName.get 只被調用一次-->
    <p>{{fullName}}</p>
    <p>{{fullName}}</p>
    <p>{{fullName}}</p>
    <!--每次點擊都會調用 changeName-->
    <input type="button" value="changeName" @click="changeName('Vue')">
</div>
<script>
var vm = new Vue({
    el: '#app',
    data: {
        firstName:'DK',
        lastName: 'Lan',
        newName: ''
    },
    computed: {
        fullName:{
            get: function(){
                return this.firstName + '.' + this.lastName
            },
            set: function(newValue){
                this.firstName = newValue
            }
        }
    },
    methods: {
        changeName: function(txt){
            this.newName = txt;
            //若是在這裏改變 this.fullName 的值,則會再次自動觸發對應的 getter
        }
    }
})
</script>

監聽器 watch

當該屬性發生改變的時候,自動觸發,此項使用不當會影響性能,慎用

<div id="example">
  <p>輸入的值: <input v-model="basicNum"></p>
  <p>計算後的值: "{{ countNum }}"</p>
  
</div>
<script>
  var vm = new Vue({
  el: '#example',
  data: {
    basicNum: 0
  },
  watch: {
    // 偵聽 data屬性 這個屬性一旦變化 
    basicNum: function () {
      return Math.floor(this.basicNum*999/100);
    }
  }
})
//補充 computer 和 watch 還都支持對象的寫法。
vm.$watch('obj', {
    // 深度遍歷
    deep: true,
    // 當即觸發
    immediate: true,
    // 執行的函數
    handler: function(val, oldVal) {}
})
</script>
computed與watch區別
  • 相同:
    computed和watch都起到監聽/依賴一個數據,並進行處理的做用
  • 不一樣:
    1.computed 建立新的屬性, watch 監聽 data 已有的屬性
    2.computed 會產生依賴緩存
    3.當 watch 監聽 computed 時,watch 在這種狀況下無效,僅會觸發 computed.setter

    {
        computed: {
            a: {
                get: function(){
                    return '';
                },
                set: function(newVal){
                    //會觸發此項
                    console.log('set val %s', newVal);
                }
            }                 
        },
        watch: {
            a: function(){
                //不會被觸發
                console.log('watch');
            }
        }    
    }

因此通常來講須要依賴別的屬性來動態得到值的時候可使用computed,對於監聽到值的變化須要作一些複雜業務邏輯的狀況可使用watch

過濾器 filters

<div id="app"> 
    <!-- 用法一:在雙花括號中 -->
    {{ money | monerFilter }}
    <!-- 用法二:在表達式中  版本要求2.1.0+ -->
    <div v-bind:id="rawId | formatId"></div>
</div>

<script>
//定義方法一:vue選項中定義本地的過濾器
    var vm = new Vue({
        el: '#example',
        filters: {
          capitalize: function (value) {
            return "¥"+ value 
          }
        }
    })
//定義方法二:在vue實例化以前全局定義過濾器
    Vue.filter('formatId', function (value) {
      return value + "_total"
    })

    new Vue({
      // ...
    })
</script>

自定義指令 directives

除了默認內置的指令 (v-modelv-show),Vue容許註冊自定義指令,可分全局指令和局部指令。

全局指令

<div id="app">
    <!--使用自定義的指令 v-myGlobalDir-->
    <input type="text" value="" v-myGlobalDir />
</div>
<script>
// 註冊指令名稱不用寫前綴 v-
// 參數 element:使用指令的元素
Vue.directive('myGlobalDir',  function(element){
    //默認觸發鉤子函數的 inserted
    element.value = "世界和平";
    element.focus();
})

var vm = new Vue({
    el: '#app'
})
</script>

局部指令

<div id="app">
    <!--使用自定義的指令 v-privateDir-->
    <input type="text" value="" v-privateDir />
</div>
<script>
var vm = new Vue({
    el: '#app',
    directives: {
        //註冊指令名稱不用寫前綴 v-
        // 參數 element:使用指令的元素
        privateDir: function(element){ 
            element.style.background = '#ccc';
            element.value = "世界和平";
        }
    }
})
</script>

指令的鉤子函數

鉤子函數能夠理解成是指令的生命週期

  • bind:指令第一次綁定到元素時調用。可用於初始化。
  • inserted:被綁定元素插入父節點時調用
  • update:被綁定元素所在的模板更新時調用。
  • componentUpdated:指令所在組件完成一次更新後調用。
  • unbind:只調用一次,指令與元素解綁時調用。

詳細參數點擊跳轉官網

<div id="app">
    <!--使用自定義的指令 v-demo-->
    <input type="text" v-model="text" v-demo="{color:'red'}">
</div>

<script>
Vue.directive('demo', {
    //先於 inserted 觸發,只調用一次 可用於初始化
    bind: function(element, binding, vnode){
        console.log('bind');
        element.style.color = binding.value.color
    },
    //被綁定元素插入父節點時調用 後於 bind 觸發 
    //參數 element: 使用指令的元素; 參數 binding: 使用指令的屬性對象; 參數 vnode: 整個 Vue 實例
    inserted: function(element, binding, vnode){
        console.log('inserted');
    },
    //被綁定元素所在的模板更新時調用,而不論綁定值是否變化
    update: function(element, binding, vnode){
        console.log('update');
    },
    //被綁定元素所在模板完成一次更新週期時調用。
    componentUpdated: function(element, binding, vnode){
        console.log('componentUpdated');
    }
})

var vm = new Vue({
    el: '#app',
    data:{
        text: '鉤子函數'
    }
})
</script>

案例:自定義日期控件

<div id="app">
    <!--直接在 jQuery 環境下使用 datepicker 插件-->
    <input type="text" id="datepicker" data-date-format="yyyy-mm-dd"/>
    <!--使用 Vue 自定義指令 v-datepicker-->
    <input type="text" v-datepicker data-date-format="yyyy-mm-dd"/>
    <input type="button" value="保存" @click="save">
    <span>{{dataform.birthday}}</span>
</div>

//在沒有使用 Vue 前,datepicker 插件在 jQuery 的環境下是這樣使用
$('#datepicker').datepicker();

//使用 Vue 自定義指令 v-datepicker
Vue.directive('datepicker', function(element, binding, vnode){
    // data = dataform.birthday
    $(element).datepicker({
        language: 'zh-CN',
        pickTime: false,
        todayBtn: true,
        autoclose: true
    }).on('changeDate', function(){
        //因爲不是手動在 input 輸入值,因此雙向綁定 v-model 無效
        //因此須要手動改變實例的數據模型
        var data = $(element).data('model');
        if(data){
            // datas = ['dataform', 'birthday']
            var datas = data.split('.');
            //context = vm
            var context = vnode.context;
            //循環屬性自動添加
            datas.map((ele, idx) => {
                //最後一個屬性就直接賦值
                if(idx == datas.length - 1){
                    context[ele] = element.value
                } else {
                    //動態添加屬性
                    context = context[ele]
                }
            })
        }
    })
})

var vm = new Vue({
    el: '#app',
    data: {
        dataform: {}
    },
    methods: {
        save: function(){
            //使用 $set 更新 dataform
            //更多 $set 的使用在下面繼續介紹
            this.$set(this.dataform)
        }
    }
})

3、 組件

組件source:
https://github.com/Wscats/vue...

組件註冊使用

1.組件命名兩個選擇:
(1)短橫線分隔命名 eg:<my-component-name>;
(2)駝峯命名 eg:<MyComponentName>;
2.組件data必須是個函數並return返回,強迫建立一個獨立做用域,就算組件屢次複用不相互影響。

局部組件

<div id="app">
    <!--組件的使用-->
    <private-component></private-component>
</div>
//組件的定義 Vue.component(組件名稱, {template})
var vm = new Vue({
    el: '#app',
    components:{
        'private-component': {
            template: '<h1>局部組件</h1>'
        }
    }
})

最終渲染的效果

<div id="app">
    <h1>局部組件</h1>
</div>

插槽

Vue 組件默認是覆蓋渲染,爲了解決這一問題,Vue 提出了 slot 分發內容,留給父組件注入內容。

//父組件
<div id="app">
    <component1>
        <h1>Sam</h1>
        <h1>Lucy</h1>
    </component1>
</div>

//組件留有slot
Vue.component('component1', {
    template: `
        <div>
            <h1>Tom</h1>
            <slot></slot>
        </div>`
})

>>渲染出來效果
<div id="app">
    <component1>
        <h1>Tom</h1>
        <h1>Sam</h1> //注入
        <h1>Lucy</h1> //注入
    </component1>
</div>
具名slot

若是要將組件裏面不一樣的子元素放到不一樣的地方,那就爲子元素加上一個屬性 slot="名稱",而後在組件定義的時候用名稱對應位置 ,其它沒有 slot 屬性的子元素將統一分發到 裏面

//父組件
<h1 slot="lucy">Lucy</h1> //在名字爲lucy的slot注入內容


//組件內部
<slot name="lucy"></slot>
縮寫

(v-slot:) 替換爲字符#。例如v-slot:header能夠被重寫爲#header

動態和異步組件

1.動態組件 is

<div id="app" style="display: none;">
    //切換動態組件
    <input type="button" value="changeLight" @click="changeLight" /> 
    <br/>
    //渲染讀取動態組件
    <p :is="show"></p>
</div>

<script type="text/javascript">
    var vm = new Vue({
        el: '#app',
        data: {
            show: 'red',
        },
        methods:{
            changeLight: function(){
                this.show = this.show == 'red' ? 'green' : 'red';
            }
        },
        components: {
            red: {
                template: '<h1>Red</h1>'
            },
            green: {
                template: '<h1>Green</h1>'
            }
        }
    })
</script>
  • <keep-alive> 組件實例在第一次建立的時候被緩存下來

    <!-- 失活的組件將會被緩存!-->
    <keep-alive>
      <component v-bind:is="currentTabComponent"></component>
    </keep-alive>

2.異步組件
Vue.component('async-example', function (resolve, reject)
resolve 加載成功
reject 加載失敗

<template>
<div>
    組件一 延遲300毫秒,從服務器加載
    組件二 不延遲從服務器加載
    <template v-if="loadComponent">
        <child></child>
        <child2></child2>
    </template>
    <button @click="toggle">點擊異步加載組件</button>
</div>
</template>
<script>
import Vue from 'vue';
const child = Vue.component('child', function (resolve) {
    setTimeout(function () {
        require(['./child.vue'], resolve)
    }, 3000);
});
const child2 = Vue.component('child2', function (resolve) {
    require(['./child2.vue'], resolve)
});
export default{
    data: function () {
        return {
            loadComponent: false
        };
    },
    components: {
        child,
        child2,
    },
    methods: {
        toggle:function () {
            this.loadComponent = !this.loadComponent;
        }
    }
}
</script>

組件間的通信

1.父傳子

父組件在引入子組件時上帶屬性過去,子組件props接收。
image.png

2.子傳父

父組件在引入子組件時v-on訂閱監聽對應的數據,子組件經過$.emit數據發送給父
image.png

3.兄弟傳兄弟

引入公共bus文件
image.png

4.引入插件vueX託管狀態

動畫和過分效果


參考資料:
官網:https://cn.vuejs.org/
學習筆記: https://github.com/Wscats/vue...

相關文章
相關標籤/搜索