Vue 學習筆記
vue對比jquery
vue
:mvvm
資料驅動影響檢視 適用於複雜資料jquery
:mvc
檢視塞入資料 適用於複雜檢視動效
(其實都是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-if
和v-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