1. 程式人生 > >Vue 學習筆記

Vue 學習筆記

vue對比jquery

vuemvvm 資料驅動影響檢視 適用於複雜資料
jquerymvc 檢視塞入資料 適用於複雜檢視動效

(其實都是js 的封裝,以及對html 的擴充套件)

相關指令

v-text 等同大鬍子效果 但是會轉換為字串

v-html 繫結html屬性

  <div id="app">
    <div v-html="message"></div>
  </div>

  <script>
    new Vue({
      el: '#app',
      data: {
        message: '<h1>菜鳥教程</h1>'
      }
    })
  </script>

v-if三兄弟 只會渲染判斷為真的dom
v-show 繫結值的布林值來判斷是否顯示 會渲染整個dom只是會根據布林只能判斷是否增加display none這個內聯樣式
v-ifv-show的區別:
v-if有更高的切換消耗;
v-show有更高的初始渲染消耗;
v-if適合運營條件不大可能改變;
v-show適合頻繁切換

v-for: 迴圈

v-once 只會渲染一次 即使資料改變

v-bind 用來響應地更新html屬性 使用場景:繫結介面請求得到的資料 簡寫: : ,可以繫結class和內聯樣式

<style>
  .class1 {
    background: #444;
    color: #eee;
  }
</style>

<body>
  <script src="https://cdn.bootcss.com/vue/2.2.2/vue.min.js"></script>

  <div id="app">
    <label for="r1">修改顏色</label><input type="checkbox" v-model="class1" id="r1">
    <br><br>
    <!-- 單引號只是對下面對兩個class1作出區分 不使用也可以 前面是class 樣式 後面是bool值 -->
    <div v-bind:class="{'class1': class1}">
      directiva v-bind:class
    </div>
  </div>

  <script>
    new Vue({
      el: '#app',
      data: {
        class1: false
      }
    });
  </script>
</body>

v-on:用來監聽dom事件 其修飾符可以指定鍵盤事件
v-on:click 簡寫@click:事件監聽
v-model:雙向繫結 一般結合input textarea (多行) 使用 其有修飾符.lazy .number .trim

生命週期

以下都是鉤子函式

beforeCreate(建立前)
created(建立後)
beforeMount (載入前)
mounted(載入後)
beforeUpdate(更新前)
updated(更新後)
beforeDestroy(銷燬前)
destroyed(銷燬後)

(在不同的時間點,可以進行不同的操作。)

計算屬性

computed:計算屬性

區別與methods
效能相比methods要高 因為有快取 只有在相關值發生改變時才會觸發 在第一次渲染頁面也會主動觸發

計算屬性的資料來源未發生變化 則不會觸發響應的計算屬性
屬性區分於方法

 <div id="app">
    <p>原始字串: {{ message }}</p>
    <p>計算後反轉字串: {{ reversedMessage }}</p>
  </div>

  <script>
    var vm = new Vue({
      el: '#app',
      data: {
        message: 'Runoob!'
      },
      computed: {
        // 以下的函式將提供給計算屬性的 getter   計算屬性預設只有getter
        reversedMessage: function() {
          // `this` 指向 vm 例項
          return this.message.split('').reverse().join('')
        }
      }
    })
  </script>

計算屬性中預設存在getter方法 我們可以手動新增setter方法:

<div id="app">
    <p>{{ site }}</p>
  </div>

  <script>
    var vm = new Vue({
      el: '#app',
      data: {
        name: 'Google',
        url: 'http://www.google.com'
      },
      computed: {
        site: {
          // getter
          get: function() {
            return this.name + ' ' + this.url
          },
          // setter
          set: function(newValue) {
            var names = newValue.split(' ')
            this.name = names[0]
            this.url = names[names.length - 1]
          }
        }
      }
    })
    // 呼叫 setter, vm.name 和 vm.url 也會被對應更新
    vm.site = '菜鳥教程 http://www.runoob.com';  //觸發set方法
    document.write('name: ' + vm.name); //動態更新dom樹
    document.write('<br>');
    document.write('url: ' + vm.url);
  </script>

過濾器

vue中可以自定義過濾器 被用作常見地文字格式化

<div id="app">
    <!-- 過濾器的用法 -->
    {{ message | capitalize }}
  </div>

  <script>
    new Vue({
      el: '#app',
      data: {
        message: 'runoob'
      },
      filters: {
        capitalize: function(value) {
          if (!value) return ''
          value = value.toString()
          return value.charAt(0).toUpperCase() + value.slice(1) //對字串的第一個字母進行大寫
        }
      }
    })
  </script>

監聽屬性

watch:響應資料變化

<div id="computed_props">
    <!-- 分別繫結kilometers和meters -->
    千米 : <input type="text" v-model="kilometers"> 米 : <input type="text" v-model="meters">
  </div>
  <p id="info"></p>
  <script type="text/javascript">
    var vm = new Vue({
      el: '#computed_props',
      data: {
        kilometers: 0,
        meters: 0
      },
      methods: {},
      computed: {},
      watch: {
        kilometers: function(val) {  //dom中的相關繫結會觸發對應的觀察屬性
          this.kilometers = val;
          this.meters = val * 1000;
        },
        meters: function(val) {
          this.kilometers = val / 1000;
          this.meters = val;
        }
      }
    });
    // $watch 是一個例項方法 $作用與vue自帶的屬性區別u與自定義的屬性
    vm.$watch('kilometers', function(newValue, oldValue) {
      // 這個回撥將在 vm.kilometers 改變後呼叫
      document.getElementById("info").innerHTML = "修改前值為: " + oldValue + ",修改後值為: " + newValue;
    })
  </script>

樣式繫結

  • 單樣式繫結:
<style>
  .active {
    width: 100px;
    height: 100px;
    background: green;
  }
</style>

<body>
  <div id="app">
    <!-- 主要是v-bind的使用 -->
    <div v-bind:class="{ active: isActive }"></div>
  </div>

  <script>
    new Vue({
      el: '#app',
      data: {
        isActive: true
      }
    })
  </script>
  • 多樣式繫結:
<style>
  .active {
    width: 100px;
    height: 100px;
    background: green;
  }

  .text-danger {
    background: red;
  }
</style>

<body>
  <div id="app">
    <div class="static" v-bind:class="{ active: isActive, 'text-danger': hasError }">
    </div>
  </div>

  <script>
    new Vue({
      el: '#app',
      data: {
        isActive: true,
        hasError: false
      }
    })
  </script>

元件

元件是整個vue知識體系中最重要的一個模組
元件的作用是:複用
前端路由相對於傳統路由 請求少 節省資源
mode:history //不使用html5 實現前進和後退 預設設定
關於元件的引用 除了直接引用自定義標籤 is標籤也可以引用元件到指定的位置,動態繫結元件

全域性元件

<div id="app">
    <runoob></runoob>
  </div>

  <script>
    // 註冊  此中註冊方式為全域性元件 所有的外部元件中都可以引用
    Vue.component('runoob', {
      template: '<h1>自定義元件!</h1>'
    })
    // 建立根例項
    new Vue({
      el: '#app'
    })
  </script>

區域性元件

區分於全域性元件

<div id="app">
    <runoob></runoob>
</div>

<script>
var Child = {
  template: '<h1>自定義元件!</h1>'
}

// 建立根例項
new Vue({
  el: '#app',
  components: {
    // <runoob> 將只在父模板可用
    'runoob': Child
  }
})
</script>

template

template 模版 用來承載dom樹 常在元件中使用

props

自定義元件屬性:通過props申明屬性 可以通過v-bind動態繫結自定義屬性

  <div id="app">
    <child message="hello!"></child>
  </div>

  <script>
    // 註冊
    Vue.component('child', {
      // 宣告 props
      props: ['message'],
      // 同樣也可以在 vm 例項中像 “this.message” 這樣使用
      template: '<span>{{ message }}</span>' //可以這樣理解:此處message既是屬性也是變數
    })
    // 建立根例項
    new Vue({
      el: '#app'
    })
  </script>

動態props

通過v-bind實現

<div id="app">
    <div>
      <input v-model="parentMsg">
      <br>
      <!-- 通過v-bind繫結父元件中的parentMsg 實現動態繫結-->
      <child v-bind:message="parentMsg"></child>
    </div>
  </div>

  <script>
    // 註冊
    Vue.component('child', {
      // 宣告 props
      props: ['message'],
      // 同樣也可以在 vm 例項中像 “this.message” 這樣使用
      template: '<span>{{ message }}</span>'
    })
    // 建立根例項
    new Vue({
      el: '#app',
      data: {
        parentMsg: '父元件內容'
      }
    })
  </script>

元件間互動

父元件往子元件傳入資料使用props 反過來則用emit

父傳子:
子元件props定義屬性 子元件標籤引用v-bind將父元件引數與子元件屬性繫結

   <div id="counter-event-example">
      <button-todo v-bind:todo="item"></button-todo>
    </div>

    <script>
      Vue.component('button-todo', {
        props: ['todo'],
        template: '<button >{{ todo }}</button>'
      })
      new Vue({
        el: '#counter-event-example',
        data: {
          item: '我是item'
        }
      })
    </script>

子傳父:
父元件定義method:fv_fuc 接受引數arg
子元件 this.$.emit(<fuc>,<arg>)
子元件標籤引用 v-on:<fuc>="fv_fuc"
流程: 子元件的emit觸發標籤引用的fuc繼而觸發父元件的fv_fuc

  <div id="app">
      <div id="counter-event-example">
        <p>{{ counter }}</p>
        <button-counter v-on:increment="setCounter"></button-counter>
      </div>
    </div>

    <script>
      Vue.component('button-counter', {
        template: '<button v-on:click="incrementHandler">{{ counter }}</button>',
        data: function() {
          return {
            counter: 0
          }
        },
        methods: {
          incrementHandler: function() {
            this.counter += 1
            this.$emit('increment', this.counter)
          }
        },
      })
      new Vue({
        el: '#counter-event-example',
        data: {
          counter: 0
        },
        methods: {
          setCounter: function(somedata) {
            this.counter = somedata //接收子元件的資料
          }
        }
      })
    </script>

自定義指令

directive 定義指令名稱
inserted 當繫結元素插入到dom中會觸發

<div id="app">
    <p>頁面載入時,input 元素自動獲取焦點:</p>
    <input v-focus>
  </div>

  <script>
    // 註冊一個全域性自定義指令 v-focus
    Vue.directive('focus', {
      // 當繫結元素插入到 DOM 中。
      inserted: function(el) {
        // 聚焦元素
        el.focus()
      }
    })
    // 建立根例項
    new Vue({
      el: '#app'
    })
  </script>

vue.directive定義全域性指令 directives: {}的方式定義區域性指令 這點和component(元件)相似

  <div id="app">
    <p>頁面載入時,input 元素自動獲取焦點:</p>
    <input v-focus>
  </div>

  <script>
    // 建立根例項
    new Vue({
      el: '#app',
      directives: {
        // 註冊一個區域性的自定義指令 v-focus 和components的使用相似
        focus: {
          // 指令的定義
          inserted: function(el) {
            // 聚焦元素
            el.focus()
          }
        }
      }
    })
  </script>

directive可以和鉤子函式配合使用 不需要鉤子函式也可以簡寫 第二個引數是function,預設的第一個引數是el

 <script>
  Vue.directive('runoob', {
      // 繫結bind的鉤子函式
      bind: function(el, binding, vnode) {
        var s = JSON.stringify
        el.innerHTML =
          'name: ' + s(binding.name) + '<br>' +
          'value: ' + s(binding.value) + '<br>' +
          'expression: ' + s(binding.expression) + '<br>' +
          'argument: ' + s(binding.arg) + '<br>' +
          'modifiers: ' + s(binding.modifiers) + '<br>' +
          'vnode keys: ' + Object.keys(vnode).join(', ')
      }
    })
    new Vue({
      el: '#app',
      data: {
        message: '菜鳥教程!'
      }
    })
  </script>

路由

路由:
需要下載 vue_router庫 然後vue.use(VRouter)
使用步驟:
1.定義路由元件
2.定義路由:對映元件
3.通過routes配置新建router例項
4.通過router引數注入路由 並且掛載根例項

頁面跳轉 rooter-link

<!-- 匯入路由用到的js -->
<script src="https://cdn.bootcss.com/vue-router/2.7.0/vue-router.min.js"></script>
  <div id="app">
    <h1>Hello App!</h1>
    <p>
      <!-- 使用 router-link 元件來導航. -->
      <!-- 通過傳入 `to` 屬性指定連結. -->
      <!-- <router-link> 預設會被渲染成一個 `<a>` 標籤 -->
      <router-link to="/foo">Go to Foo</router-link>
      <router-link to="/bar">Go to Bar</router-link>
    </p>
    <!-- 路由出口 -->
    <!-- 路由匹配到的元件將渲染在這裡 -->
    <router-view></router-view>
  </div>

  <script>
    // 0. 如果使用模組化機制程式設計,匯入Vue和VueRouter,要呼叫 Vue.use(VueRouter)

    // 1. 定義(路由)元件。
    // 可以從其他檔案 import 進來
    const Foo = {
      template: '<div>foo</div>'
    }
    const Bar = {
      template: '<div>bar</div>'
    }

    // 2. 定義路由
    // 每個路由應該對映一個元件。 其中"component" 可以是
    // 通過 Vue.extend() 建立的元件構造器,
    // 或者,只是一個元件配置物件。
    // 我們晚點再討論巢狀路由。
    const routes = [{
        path: '/foo',
        component: Foo
      },
      {
        path: '/bar',
        component: Bar
      }
    ]

    // 3. 建立 router 例項,然後傳 `routes` 配置
    // 你還可以傳別的配置引數, 不過先這麼簡單著吧。
    const router = new VueRouter({
      routes // (縮寫)相當於 routes: routes
    })

    // 4. 建立和掛載根例項。
    // 記得要通過 router 配置引數注入路由,
    // 從而讓整個應用都有路由功能
    const app = new Vue({
      router
    }).$mount('#app')

    // 現在,應用已經啟動了!
  </script>

路由引數

在對映表裡設定 如:path:'/apple/:color'

&n