vue01

vue01 : vue基本語法javascript

vue02 : 博彩項目採用vue方式實現css

vue03 : 博彩項目採用vue方式實現html

傳統的Web項目 : 後臺邏輯,html數據的渲染thymeleaf,jsp前端

web項目: 後臺程序只負責提供數據, 前端負責去展示html數據vue

介紹

簡單來講,Vue是一套渲染UI的強大前端框架。java

官網地址:https://cn.vuejs.org/webpack

主要特性:git

  • 學習曲線很是平緩,只要有html/css,js基礎便可上手
  • 響應式的支持,讓咱們從傳統的JQuery的面向DOM編程,轉變爲面向數據編程
  • 豐富的語法支持
  • 優雅的單文件組件
  • 完善的組件動畫支持
  • 成熟的生態,好比vue-cli,VueRouter,Vuex等相關配套的工具

其中,最重要最核心的特性就是:響應式和組件化。github

安裝

官方文檔:https://cn.vuejs.org/web

  • 經過<script></script>引用

    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
  • 經過vue-cli安裝全套開發環境,項目開發推薦

快速嚐鮮

經過一個簡單的例子,來快速感覺一下Vue的特性。

例子中使用:值填充以及響應式的UI刷新,

  • v-model實現輸入項雙向綁定特性

  • v-for循環
  • v-if條件判斷
  • v-on:click單擊事件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
</head>
<body>
<div id="app">
    {{msg}}
    <input type="text" v-model="username"><span>{{username}}</span>
    <ul>
        <li v-for="item in list">{{item}}</li>
    </ul>
    <h3 v-if="isShow">我在某些條件下才顯示</h3>
    <button @click="isShow=!isShow">點我隱藏上面的文字</button>
    
</div>
<script>
    let vm = new Vue({
        el: '#app',
        data:{
            msg: "我是Vue",
            list:[
                'a', 'b', 'c'
            ],
            isShow: true,
            username: "aaaa"
        }
    });
    setTimeout(()=>{
        vm.msg = "個人值被改變了,會響應式的刷新到UI上";
        vm.list.push("dd");
    }, 2000)
</script>
</body>
</html>

Vue實例

數據和方法

每個Vue實例,均可以有本身的數據和自定義方法。自定義方法通常用來獲取數據或者對數據進行處理。

let vue = new Vue({
       el: "#app",
       data: {
           content: "aaa"
       },
       template: "<div><button v-on:click=\"handleClick\">點我讓content變化</button> : {{content}}</div>",
       methods: {
           handleClick(){
               this.content = "bbb"
           }
       }
    });

生命週期鉤子

所謂的生命週期其實就像咱們人,從出生到成長到死亡的過程同樣.在Vue中生命週期指的是Vue實例從初始化,建立,顯示,更新以及銷燬的整個過程,而生命週期鉤子指的是每一個過程都有一個回調函數,Vue中把回調函數稱爲鉤子。

  • beforeCreate : 開始建立實例
  • created : 實例建立出來了,vue的實例基本上被初始化
  • beforeMount : 模版與數據相結合,頁面渲染以前,執行的函數
  • mounted: 模版和數據結合完成,會將Vue實例掛載到dom樹上
  • beforeDestroy : 實例要被回收的時候執行
  • destroyed : 實例回收完成的時候調用
  • beforeUpdate: 數據發生改變,尚未渲染以前
  • updated : 渲染完成

再次回顧一下什麼是Vue生命週期鉤子? 生命週期鉤子就是Vue實例在某個時間點自動執行的回調函數.咱們經常使用的生命週期鉤子有: created,mounted

<script>
    let vm = new Vue({
        el:'#app',
        template:'<span>{{msg}}</span>',
        data:{
            msg:'hahaha'
        },
        beforeCreate(){
            console.log("beforeCreate...")
        },
        created(){
            console.log("created...")
        },
        beforeMount(){
            console.log("beforeMount..."+this.$el.innerHTML)
        },
        mounted(){
            console.log("mounted..."+this.$el.innerHTML)
        },
        beforeDestroy(){
            console.log("beforeDestory...")
        },
        destroyed(){
            console.log("destoryed...")
        },
        beforeUpdate(){
            console.log("beforeUpdate...")
        },
        updated(){
            console.log("updated")
        }
    })
</script>

計算屬性

計算屬性和方法均可以對數據進行處理。可是計算屬性有基於依賴數據的智能緩存,當計算屬性所依賴的值發生改變,計算屬性纔會從新計算, 因此性能更高,咱們應該優先考慮使用。

若是是普通的方法實現相同的功能,每當頁面數據任何數據發生改變的時候,方法都會被執行一次

let vue = new Vue({
       el: "#app",
       data: {
           firstName: "Xiao",
           lastName: "Kaikai",
           age:30
       },
       computed: {
           // 計算屬性有基於依賴數據的緩存
          fullName(){
              console.log("計算屬性執行了一次");
              return this.firstName + this.lastName;
          }
       } ,
       methods: {
         getFullName(){
             console.log("自定義方法執行了");
             return this.firstName + this.lastName;
         }
       }
    });

偵聽器

偵聽器能夠用來偵聽數據的改變. 若是一個功能,方法能實現,計算屬性能實現,偵聽器也能實現,咱們應該優先選擇計算屬性

let vm = new Vue({
        el:'#app',
        data:{
            firstName:'Kaikai',
            lastName:'Xiao',
            age:30,
            fullName:"Kaikai Xiao"
        },
        methods:{
          getFullName(){
              console.log("getFullName執行了一次運算")
              return this.firstName + ' ' + this.lastName;
          }
        },
        watch:{
            firstName(newVal,oldVal){
                this.fullName = this.firstName + this.lastName;
                console.log('newVal:'+newVal+" oldVal:"+oldVal);
            },
            lastName(){
                this.fullName = this.firstName + this.lastName;
            }
        }
    }

class動態綁定

Vue容許咱們給DOM元素動態綁定一些class。

<body>
       <div id="app">
           <div class="c1" :class="{c2:isShow,c3:isShow}" @click="isShow=!isShow" >{{name}}</div>
           class動態綁定數組的語法   
           <div class="c1" :class="classes" @click="isShow=!isShow" >{{name}}</div>
       </div>
</body>
<script>
    let vm = new Vue({
        el:'#app',
        data:{
            name:'zhangsan',
            isShow:true,
            classes:['c1','c2','c3']
        }
    });
</script>
<style>
    .c1{
        font-size: 10px;
        color: green;
        background-color: yellow;
    }
    .c2{
        font-size: 30px;
    }
    .c3{
        background-color: red;
    }
</style>

條件渲染

v-show

<div v-show="isShow">頁面內容v-show</div>

v-if

v-else-if

v-else

<div id="app" >
    <div v-if="isLogin">您好,劉德華</div>
    <div v-else><button @click="isLogin=true">登陸</button></div>

    <!--對於須要頻繁切換顯示隱藏的場景,用v-show,由於性能更高-->
    <!--<div v-show="isLogin">您好,劉德華2</div>-->
</div>
<script>
    let vue = new Vue({
       el: "#app",
       data: {
           isLogin: false
       }
    });
</script>

列表渲染

當咱們去使用v-for的時候,最好去給它指定一個惟一的key值,這樣的會方便vue複用dom節點,從而提升性能

遍歷數組

使用的語法: v-for="(item,index) in 數組" 若寫了:key,那麼它的值須要是惟一的值

<div id="app" >
    <div>最好吃的水果:</div>
    <div v-for="item in list">{{item}}</div>
    <input type="text" v-model="fruit"><button @click="handleClick">添加</button>
    <div>
        <button @click="handleDelete">刪除第</button><input type="text" v-model="index">個
    </div>
</div>
<script>
    let vm = new Vue({
       el: "#app",
       data: {
           list:[
               "蘋果","西瓜","哈蜜瓜"
           ],
           fruit: "",
           index: 0
       },
        methods:{
            handleClick(){
                this.list.push(this.fruit);
                this.fruit = "";
            },
            handleDelete(){
                this.list.splice(this.index, 1);
            }
        }
    });
</script>

注意:當咱們去修改數組的時候,不能使用下標的方式,不然數據添加進去了,頁面不會刷新,咱們須要藉助數組提供的一些方法來修改,咱們經常使用的數組方法有:

  • push : 添加元素
  • pop : 取出末尾元素
  • splice : 根據角標刪除元素
  • sort : 排序
  • forEach : 循環處理

遍歷對象

v-for="(item,key,index) in 對象"

<div v-for="item,key,index in user">{{item}}--{{key}}--{{index}}</div>
let vm = new Vue({
        el:'#app',
        data:{
            user:{
                username:"haha",
                password:123,
                age:100
            }
        }
    });

注意: 咱們若是直接添加一個屬性,頁面上並不會跟着刷新

Vue中的set方法

當咱們去修改某一個對象的內容的時候,因爲vue中並不知道對象內容發生了改變,因此也就不會從新渲染了,若想當對象內容發生改變頁面從新渲染,咱們須要藉助Vue給咱們提供的一下方法

使用全局的方法: Vue.set(對象,改變的key,改變的值)

使用實例的方法: vm.$set(對象,改變的key,改變的值)

數組中使用set方法: vm.$set(對象,要改變的下標,改變的值)

ToDoList

用上面學的語法,實現一個ToDoList。

<body>
       <div id="app">
            <h3>添加今日要完成任務</h3>
            <input type="text" v-model="currentInput" /><button @click="handleAdd">添加</button>
           <ul>
               <li v-for="item in todos" :class="{done:item.isDone}" >
                   {{item.text}}
                   <button @click="handleComplete(item)" >標記完成</button>
                   <button @click="handleDelete(item)">刪除</button>
               </li>
           </ul>
       </div>
</body>
<style>
    .done{
        background-color: red;
    }
</style>
<script>
    
    let vm = new Vue({
        el:'#app',
        data:{
           todos:[],
           currentInput:""
        },
        methods:{
            handleAdd(){
                //判斷是否爲空
                if(this.currentInput === ""){
                    return ;
                }
                //檢查是否有重複的內容
                for(let i=0;i<this.todos.length;i++){
                    //數組中的每一項
                    let item = this.todos[i];
                    //判斷是否有重複
                    if(item.text === this.currentInput){
                        return;
                    }
                }
                //獲取輸入項的內容,將輸入項的內容存到todos
                this.todos.push({text:this.currentInput,isDone:false});
                //清空輸入項的內容
                this.currentInput = ""
            },
            handleComplete(item){
                item.isDone = true;
            },
            handleDelete(item){
                //從todos中刪除這個item
                let index = this.todos.indexOf(item);
                //調用數組中刪除的方法
                this.todos.splice(index,1);
            }
        }
    });
</script>
</html>

組件

組件是Vue的核心之一,任何一個大的系統均可以由多個小的組件共同構成。組件的複用性,也大大提升了前端開發的效率。

組件註冊

組件的註冊有全局註冊和局部註冊兩種方式。

全局註冊: 註冊以後能夠用在任何新建立的 Vue 根實例 (new Vue) 的模板中

全局組件

<script>
    /*定義一個全局組件*/
    Vue.component('title-bar',{
        template:`<div><h1>首頁標題欄</h1></div>`
    });
    /*定義一個全局組件*/
    Vue.component('MenuBar',{
        template:`<div><h1>底部菜單欄</h1></div>`
    });

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

局部組件

局部註冊: 全局註冊每每是不夠理想的。好比,若是你使用一個像 webpack 這樣的構建系統,全局註冊全部的組件意味着即使你已經再也不使用一個組件了,它仍然會被包含在你最終的構建結果中。這形成了用戶下載的 JavaScript 的無謂的增長。

<script>
    <!--定義局部組件-->
    let TitleBar = {
        name:'title-bar',
        template:`<div><h1>{{title}}標題部分</h1></div>`,
        data(){
            return {
                title:'首頁'
            }
        }
    }

    /*定義一個局部組件*/
    let MenuBar = {
        name:'menu-bar',
        template:`<div><h1>底部菜單部分</h1></div>`
    }
    //根實例
    let vm = new Vue({
        el:'#app',
        components:{
            TitleBar,
            MenuBar
        }
    });
</script>

父子組件數據通訊

父子組件之間每每不是獨立的,須要進行數據的通訊。從父到子,用props;從子到父,用$emit。

<div id="app">
    <ul>
        <li v-for="item,index in list"><todo-item :content="item" :index='index' @delete-item="handleDeleteItem"></todo-item></li>
    </ul>
    <child :text="text"></child>
</div>
<script>
    // 全局註冊
    Vue.component("todo-item", {
        props:['content','index'],
        data() {
            return {

            }
        },
        template: "<div @click='handlerClick'>{{content}}</div>",
        methods: {
            handlerClick(){
                this.$emit("delete-item", this.index);
            }
        }
    });

    // 子組件不要去直接修改父組件的數據
    Vue.component("child", {
        props:['text'],
        data() {
            return {
                myText: this.text
            }
        },
        template: "<div @click='changeText'>{{myText}}</div>",
        methods: {
            changeText(){
                this.myText = "修改了的文字";
            }
        }
    });


    let vue = new Vue({
        el: "#app",
        data: {
            list: [
                "吃飯", "睡覺", "打豆豆"
            ],
            text: "文字"
        },
        methods:{
            handleDeleteItem(index){
                this.list.splice(index, 1);
            }
        }
    });
</script>

組件綁定原生事件

若是咱們在自定義組件上綁定事件是沒有效果的,由於組件上定義的事件都是自定義的,想要觸發須要咱們在子組件內部調用$emit派發.可是這樣作又很麻煩,因此當咱們想使用點擊事件,咱們可使用Vue提供的綁定原生事件方式,咱們只須要使用@click.native

<div id="app">
    <child :text="text" @click.native="handleChildClick"></child>
</div>

<script>
 //全局組件
    Vue.component('child',{
        template:`<div>子組件的內容展現</div>`
        /*template:`<div @click="handleChildClick">子組件的內容展現</div>`,
        methods:{
            handleChildClick(){
                console.log("child click");
                this.$emit('click');
            }
        }*/
    });
    //根實例 ,父組件
    let vm = new Vue({
        el:'#app',
        methods:{
            handleFatherClick(){
                console.log("father click")
            }
        }
    });
</script>

組件插槽

有時候咱們組件的內容是不肯定的,咱們定義組件的時候使用slot留出空白,外界使用的時候動態插入,這就是插槽。

<body>
       <div id="app">
           <child >
               <div slot="header">header</div>
               <!--<div slot="footer">footer</div>-->
           </child>
       </div>
</body>

<script>
    //定義子組件
    Vue.component('child',{
       template:`<div>
                    <slot name="header"></slot>
                    <div>內容不變</div>
                    <slot name="footer">默認頁腳</slot>
                 </div>
                `
    });

    //根實例 ,父組件
    let vm = new Vue({
        el:'#app',
    });
</script>

動態組件:is

動態組件能夠很是方便的切換幾個不一樣的組件,並且支持緩存。

<body>
       <div id="app">
           <component :is="currentName"></component>
           <button @click="handleClick('home')">首頁</button>
           <button @click="handleClick('my')">個人</button>
       </div>
</body>

<script>
    Vue.component('home',{
        template:`<div>這是網站首頁的內容</div>`
    });

    Vue.component('my',{
        template:`<div>這是個人我的頁面</div>`
    })

    //根實例 ,父組件
    let vm = new Vue({
        el:'#app',
        data:{
            currentName:'home'
        },
        methods:{
            handleClick(name){
                this.currentName = name;
            }
        }
    });
</script>

Vue-cli

以上內容是項目開發中經常使用的基礎知識點。可是作項目開發,咱們須要考慮一下幾點:

  1. 編寫的代碼須要打包工具進行打包壓縮,圖片處理
  2. 爲了效率,但願有一個HotReload功能,不用手動刷新
  3. Vue單文件組件的支持
  4. 第三方JS編譯器的使用,如babel
  5. 第三方CSS預處理器的使用,如stylus,sass
  6. 第三方插件的使用,如ESLint。PostCSS

而Vue-cli就爲了解決上面的問題而生的,它給咱們打包好了全部能用到的好工具,提供一個開箱即用的項目開發環境。因此,咱們須要用它來建立項目。

vue-cli官網:https://cli.vuejs.org/,官網寫的是3.0版本的使用,2.xx纔是穩定版。

vue-cli github主頁:https://github.com/vuejs/vue-cli

建立工程

vue-cli的github網站默認是3.0的測試版本分支,須要切換爲主分支。

npm install -g vue-cli
vue init webpack xxx

?Project name lottery
?Project description this is a niubility project
?Author xiaokaikai
?Vue build (選擇一種構建的形式)
> Runtime + Compiler: recommended for most users
?Install vue-router?(Y/n) Y  --這裏說是否安裝路由插件
?Use ESLint to lint your code? N-- 是否檢查代碼格式
?Pick an ESLint preset Standard  -- 選擇一種代碼檢查的規範
?Set up unit tests  N  是否進行單元測試
?Setup e2e tests with Nightwatch N 是否使用e2e工具進行構建
?Should we run 'npm install' for you after the project has been created? npm --選擇npm方式安裝

輸入完成以後,工具就開始構建咱們的工程啦!

工程目錄結構

  • build:構建相關目錄
  • config:開發相關配置
  • src:要編寫的代碼
  • static:不須要webpack處理的靜態文件,好比壓縮後的資源,能夠直接訪問

Vue-Router

傳統的路由是後端來作,簡單說就是請求一個url,後端根據請求的參數內容渲染出相應的html返回。因爲JS能夠感知到瀏覽器URL的變化,所以能夠作到在url變化的時候去加載不一樣的DOM內容,這就是前端路由,和後端沒有任何關係了。

單頁應用(SPA)的用戶體驗比傳統的多頁應用要好不少,因此愈來愈多的公司開始嘗試單頁應用。單頁應用就將原來的多個頁面作成一個html,JS根據url的變化切換DOM的內容。這樣不用再去請求服務器的整個html內容,只須要請求對應的json數據,所以速度會快不少。

Vue-Router爲前端路由提供了封裝和簡化,並結合組件的使用。讓咱們能夠一個url對應一個組件,輕鬆編寫大型的SPA應用。

<router-view> 顯示當前路徑所對應的組件內容
<router-link to="要跳轉去的組件的路徑">

總結:

根實例 : let vm = new Vue({參數})
el
template
data
methods
computed
watch
props
生命週期鉤子

vue中屬性
v-model
v-show
v-if
v-else-if
v-else

v-for
v-html
v-text

使用屬性:  :屬性名稱

綁定事件:@事件名稱 

全局組件和局部組件

父子組件之間通信
父-->子 : props
子 --> 父: $emit(事件名稱)

@click.native 組件綁定原生事件

動態組件: <component :is=組件的名稱
相關文章
相關標籤/搜索