前端框架_Vue

JS表達式

  • 函數(方法)調用表達式
test() //函數調用表達式
  • 屬性調用表達式
var obj = {name:'wt'};
var arr = [123,'bai'];
obj.name   //屬性調用表達式
arr[0]     //屬性調用表達式
  • 變量(常量)調用表達式
let name = 'wutao';
name  //變量調用表達式
  • 字面量表達式
123         //數值字面量表達式
'wtao'      //字符串字面量表達式
true        //布爾字面量表達式
null        //空表達式
undefined   //未定義表達式
{name:'wt'} //對象字面量表達式
[123,true]  //數組字面量表達式
  • 算術表達式
a + 1       //算術表達式
b * 1       //算術表達式
  • 三目表達式
conidion ? name : title

模板語法

  • 插值
// 語法:     雙大括號{{}}
// 使用場景: 標籤內容處使用
// 單向數據綁定
// 支持JS表達式

<div id="app">
    {{msg}}
    <div>{{getContent()}}</div>
</div>

<script>
    const vue = new Vue({
        el: '#app',
        data: {
            msg: 'who is this'
        },
        methods: {
            getContent: function(){
                return 'wtao';
            }
        }
    });
</script>
插值v-text 區別
二者都是在標籤內容處插入內容,但v-text是全量插入,而插值更靈活,除了全量插入,還可使用部分插入
推薦只要使用 插值就能夠了
  • 指令
是模板語法重中之重,經常使用以下
v-text     //使用插值替代
v-html     
v-show
v-if       //條件判斷
v-else
v-else-if
v-for      //循環
v-on       //綁定事件
v-bind     //綁定屬性
v-model    //雙向數據綁定
v-pre
v-cloak
v-once

指令

  • 屬性綁定
// 單向數據綁定
// 支持JS表達式
// 使用指令v-bind,需傳入標籤屬性做爲參數,例如:v-bind:title=""

<div id="app">
    <div title="你好" :title="go">xxx</div>
    <p :title="test()"></p>
</div>
<script>
    const vue = new Vue({
        el: '#app',
        data: {
            go: '振東',
            test: function(){
                return 'xxx';
            }
        }
    });
</script>
出現上面的狀況,屬性誰後誰顯示,原理是 後面替代前面若是title在:title後面,那單向數據綁定失效
若是是使用函數,必須後面加括號調用()
一、數值型   :title="123"             等同於  title="123"
二、布爾型   :title="true"            等同於  title="true"   //false時,屬性消失
三、字符串   :title="'go'"            等同於  title="go"
四、對象     :title="{name:'wt'}"     等同於  title="[Object object]" 
五、數組     :title="[123,true,'bb']" 等同於  title="true,ok,123"
  • 事件綁定
<div id="app">
    <div v-html="title" @click="fngo"></div>

    <div v-html="title" @click="getUser"></div>
</div>
<script>
    var vm = new Vue({
        el: '#app',
        data: {
            name:'wt',
            title: '<h1>試試</h1>',
            fngo: function(){
                console.log(this);   // this表明window
            }
        },
        methods: {
            getUser: function(){
                console.log(this);   // this表明Vue實例
            }
        }
    });
</script>
注意若是改成以下代碼,this將發生變化
<div id="app">
    <div v-html="title" @click="fngo()"></div>

    <div v-html="title" @click="getUser"></div>
</div>
<script>
    var vm = new Vue({
        el: '#app',
        data: {
            name:'wt',
            title: '<h1>試試</h1>',
            fngo: function(){
                console.log(this);   // this表明Vue實例
            }
        },
        methods: {
            getUser: function(){
                console.log(this);   // this表明Vue實例
            }
        }
    });
</script>
全部函數(方法)的定義,強烈推薦放在methods裏,不要定義到data裏面
  • 條件判斷渲染
// 單向數據綁定
// 支持JS表達式

<div v-if="0"></div>    //數字0 --> false
<div v-else-if="'0'"></div>    //字符串0 ---> true
<div v-else></div>
注意點:
一、對象和數組轉boolean都是true
二、空字符串轉boolean是false
三、null、underfined、NaN轉boolean是false
四、數值0是false
let arr = []
if(arr){
    console.log('true');
}

if(arr == fasle){
    console.log('true');  // ==兩邊轉數值
}
  • 循環渲染
// 單向數據綁定
// 支持JS表達式
// items能夠是數字、字符串、數組、對象

<ul id="example-1">
  <li v-for="item in 15">
    {{ item.message }}
  </li>
</ul>

<ul id="example-1">
  <li v-for="(item,key) in 'abcd'">
    {{ item }} : {{ key }}
  </li>
</ul>

<ul id="example-1">
  <li v-for="(item,key) in {name:'taobi',age:18}">
    {{ item }} : {{key}}
  </li>
</ul>

雙向/單向數據動態綁定__原理

  • 單向
var obj = {};
var initValue = 'hello';
Object.defineProperty(obj,"newKey",{
    get:function (){
        //當獲取值的時候觸發的函數
        return initValue;
    },
    set:function (value){
        //當設置值的時候觸發的函數,設置的新值經過參數value拿到
        initValue = value;
    }
});
//獲取值
console.log( obj.newKey );  //hello   輸出

//設置值
obj.newKey = 'change value';

console.log( obj.newKey ); //change value
console.log( initValue );  //change value
  • 雙向
var obj = {};
var initValue = 'hello';
Object.defineProperty(obj,"newKey",{
    get:function (){
        //當獲取值的時候觸發的函數
        return initValue;
    },
    set:function (value){
        //當設置值的時候觸發的函數,設置的新值經過參數value拿到
        initValue = value;
    }
});
document.getElementById('txt').oninput = function(e){
    obj.newKey = e.target.value;
}

單頁應用 vs 多頁應用

  • 多頁應用
頁面跳轉 ---> 返回html

優勢:
首屏速度快,SEO效果好

缺點:
頁面切換慢
  • 單頁應用
頁面跳轉 ---> JS動態渲染

優勢:
頁面切換快

缺點:
首屏速度慢,SEO差

Vue 實例

  • 分類

圖片描述

  • 根實例組件實例區別
一、是否有掛載
    有---根實例
    沒---組件實例
    
二、文件後綴
    .js---根實例
    .vue--組件實例
    
三、寫法
    手動new Vue()---根實例
    導出export default {}---組件實例

組件

  • 組件是什麼?與模塊有什麼不一樣?
使用Vue構建單頁應用,單頁應用由Vue單文件組件組成, 所謂組件指的就是Vue單文件組件(包含模板、樣式、交互)
模塊指的就是JS模塊(單純包含JS代碼)
使用ES6模塊化導入

一、路徑問題

nodejs內置模塊與npm安裝的第三方模塊,直接引用
import Vue from 'vue';
import http from 'http';

自定義模塊或自定義組件,要帶路徑引用
./ 表明 當前文件所在路徑
../表明 當前文件父級所在路徑
import App from './App.vue';
import App from '../App.vue';

二、後綴問題(無後綴,先判斷是不是文件,找不到再判斷是不是目錄)

當省略後綴,只會匹配js/json/node後綴文件
因此當你要導入css、vue單文件組件時,就必須加上後綴
若是導入的是文件夾(包),將按以下順序查找:
<1>查找 package.json 下是否認義了 main 字段,是則讀取 main 字段下定義的入口。
<2>若是沒有 package.json 文件,則讀取文件夾下的 index.js 或者 index.node。
<3>若是都 package.json、index.js、index.node 都找不到,拋出錯誤 Error: Cannot find module 'some-library'。

連接描述css

組件與模塊最大區別是: 是否要註冊
使用流程

組件(.vue): 導入——>註冊——>使用
模塊(.js):   導入——>使用
  • 組件之間關係
一、嵌套關係(父子、爺孫)
二、非嵌套關係(兄弟、表叔與我)
  • 組件定義的三大區域
一、模板 <template> 0~1個
二、腳本 <script>   0~1個
三、樣式 <style>    0~n個

組件間通訊

  • 通訊方式
一、父子組件間通訊

   1>經過props  父向子傳遞數據,單向,響應
   2>經過引用   $root/$refs/$parent/$children  
   3>經過自定義事件   $on/$emit/$once/$off
   4>經過vuex   (推薦)

二、兄弟組件間通訊

   1>經過事件   $on/$emit/$once/$off
   2>經過vuex   (推薦)
  • 自定義事件通訊
原則: 誰發起自定義事件,誰就註冊處理自定義事件函數
// 父級
this.$refs.customComp.$on('custom-event',function(){});

// 子級
this.$emit('custom-event');
還有另一種寫法

Vuex 集中式狀態管理

  • 安裝與使用
一、安裝
npm i vuex -S

二、導入
import Vue from 'vue';
import Vuex from 'vuex';

三、安裝插件
Vue.use(Vuex);

四、定義一個倉庫並導出
export default new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment (state) {
      state.count++
    }
  }
});

五、在vue根實例中注入store
import store from './store'

new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')
初始化Vue根實例時,自動注入兩個插件, 分別是$router與$store,之後直接this.$store使用
  • 狀態是什麼?有哪些分類?
狀態就是數據

狀態的分類:
一、組件級別 --- 組件內部的數據,只容許內部操做
二、應用級別 --- 多組件共享的數據,整個應用均可以操做,並且是響應式的,適用於層級很深的
Vuex 就是 集中存儲 應用級別狀態
  • 獲取狀態
在Vuex的store中如此定義
export default new Vuex.Store({
  state: {
    count: 0
  }
});

在模板中
<p>{{$store.state.count}}</p>

在腳本中
this.$store.state.count
  • 修改狀態
必須使用 mutation來對 Vuex存儲的狀態進行修改,修改方式相似處理事件
export default new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment (state) {     // state參數自動注入
      state.count++
    }
  }
});

在模板中
<button @click="$store.commit('increment')">改變</button>

在腳本中
this.$store.commit('increment')
修改要傳值時,該如何寫?
一、只能傳一個參數,建議傳一個對象,代碼以下:

export default new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment (state,payload) {     // state參數自動注入
      state.count += payload.num;
    }
  }
});

在模板中
<button @click="$store.commit('increment',{num:12})">改變</button>

在腳本中
this.$store.commit('increment',{num:12});
  • 使用注意
一、不要在組件中直接在data選項中綁定狀態,以下

export default {
    name: 'about',
    data() {
        return {
            title: this.$store.state.num
        }
    }
}

若是修改狀態後,data中數據不會發生響應,所以推薦使用計算屬性,代碼修改以下

export default {
    name: 'about',
    data() {
        return {
            
        }
    },
    computed: {
        title(){
            return this.$store.state.num;
        }
    }
}

Vue Router 路由器

單頁應用,遇到第一個 <router-view>標籤開始適配 /根路由 若是<router-view>中有<router-view>,那必需要配有嵌套路由,不然裏面的<router-view>沒有內容
相關文章
相關標籤/搜索