vue:1、構建使用者介面
2、只關注檢視層
宣告式渲染:Vue.js 的核心是一個允許採用簡潔的模板語法來宣告式地將資料渲染進 DOM 的系統。
資料的雙向繫結
每個元件例項都有相應的 watcher 例項物件,它會在元件渲染的過程中把屬性記錄為依賴,之後當依賴項的 setter 被呼叫時,會通知 watcher 重新計算,從而致使它關聯的元件得以更新。
computed可以偵聽屬性,設定object的屬性的get和set函式
條件渲染
v-if和v-show
相同點:都可以控制某元素的顯示和隱藏
不同:
1、v-if是條件渲染,因為它會確保在切換過程中條件塊內的事件監聽器和子元件適當地被銷燬和重建。
2、v-show:不管初始條件是什麼,元素總是會被渲染,並且只是簡單地基於 CSS 進行切換。
computed和method
這兩種方式的計算結果是一樣的,不過是同一個函式放在了不同的地方
computer:
|
var vm = new Vue({
el: '#example',
data: {
message: 'Hello'
},
computed: {
// 計算屬性的 getter
reversedMessage: function () {
// `this` 指向 vm 例項
return this.message.split('').reverse().join('')
}
}
})
Original message: "Hello"Computed reversed message: "olleH"method:
<p>Reversed message: "{{ reversedMessage() }}"</p>
// 在元件中
methods: {
reversedMessage: function () {
return this.message.split('').reverse().join('')
}
}
複製程式碼
但是計算屬性是基於它們的依賴進行快取的,計算屬性只有在它的相關依賴發生改變時才會重新求值,這意味著只要 message 還沒有發生改變,多次訪問 reversedMessage 計算屬性會立即返回之前的計算結果,而不必再次執行函式。這樣可以提高效能
vue-router
顧名思義:將元件 (components) 對映到路由 (routes),然後告訴 Vue Router 在哪裡渲染它們
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.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>複製程式碼
router-Link元件來導航,<router-Link>預設會渲染成a標籤
通過傳入to屬性來指定連線
<router-view/>會顯示渲染後的元件,相當於佔位符,類似於<img/>
// 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')
// 現在,應用已經啟動了!複製程式碼
通過注入路由器,我們可以在任何元件內通過 this.$router
訪問路由器,也可以通過 this.$route
訪問當前路由:
// Home.vue
export default {
computed: {
username () {
// 我們很快就會看到 `params` 是什麼
return this.$route.params.username
}
},
methods: {
goBack () {
window.history.length > 1
? this.$router.go(-1)
: this.$router.push('/')
}
}
}複製程式碼
該文件通篇都常使用 router
例項。留意一下 this.$router
和 router
使用起來完全一樣。我們使用 this.$router
的原因是我們並不想在每個獨立需要封裝路由的元件中都匯入路由。
宣告式
模式 | 匹配路徑 | $route.params |
---|---|---|
/user/:username | /user/evan | { username: 'evan' } |
/user/:username/post/:post_id | /user/evan/post/123 | { username: 'evan', post_id: 123 } |
一個“路徑引數”使用冒號 :
標記。當匹配到一個路由時,引數值會被設定到 this.$route.params
命名路由
<router-link :to="{ name: 'user', params: { userId: 123 }}">User</router-link>
router.push({ name: 'user', params: { userId: 123 })複製程式碼
程式設計導航
router.push({ name: 'user', params: { userId: 123 })複製程式碼
注意:在 Vue 例項內部,你可以通過 $router
訪問路由例項。因此你可以呼叫 this.$router.push
// 命名的路由
router.push({ name: 'user', params: { userId: 123 }})
// 帶查詢引數,變成 /register?plan=private
router.push({ path: 'register', query: { plan: 'private' }})
複製程式碼
跟 router.push
很像,唯一的不同就是,它不會向 history 新增新記錄,而是跟它的方法名一樣 —— 替換掉當前的 history 記錄。
宣告式 | 程式設計式 |
---|---|
<router-link :to="..." replace> | router.replace(...) |
前進
router.go(1)複製程式碼
命名檢視
有時候想同時 (同級) 展示多個檢視,而不是巢狀展示,例如建立一個佈局,有 sidebar
(側導航) 和 main
(主內容) 兩個檢視,這個時候命名檢視就派上用場了。你可以在介面中擁有多個單獨命名的檢視,而不是隻有一個單獨的出口。如果 router-view
沒有設定名字,那麼預設為 default
。
<router-view class="view one"></router-view>
<router-view class="view two" name="a"></router-view>
<router-view class="view three" name="b"></router-view>複製程式碼
一個檢視使用一個元件渲染,因此對於同個路由,多個檢視就需要多個元件。確保正確使用 components
配置 (帶上 s):
const router = new VueRouter({
routes: [
{
path: '/',
components: {
default: Foo,
a: Bar,
b: Baz
}
}
]
})複製程式碼
重定向和命名
重定向也是通過 routes
配置來完成,下面例子是從 /a
重定向到 /b
:
const router = new VueRouter({
routes: [
{ path: '/a', redirect: '/b' }
]
})
const router = new VueRouter({
routes: [
{ path: '/a', redirect: { name: 'foo' }}
]
})
複製程式碼
“重定向”的意思是,當使用者訪問 /a
時,URL 將會被替換成 /b
,然後匹配路由為 /b
,那麼“別名”又是什麼呢?
/a
的別名是 /b
,意味著,當使用者訪問 /b
時,URL 會保持為 /b
,但是路由匹配則為 /a
,就像使用者訪問 /a
一樣。
上面對應的路由配置為:
const router = new VueRouter({
routes: [
{ path: '/a', component: A, alias: '/b' }
]
})複製程式碼
路由元件傳參
函式模式
const router = new VueRouter({
routes: [
{ path: '/search', component: SearchUser, props: (route) => ({ query: route.query.q }) }
]
})複製程式碼
URL /search?q=vue
會將 {query: 'vue'}
作為屬性傳遞給 SearchUser
元件。
物件模式
如果 props
是一個物件,它會被按原樣設定為元件屬性。當 props
是靜態的時候有用。
const router = new VueRouter({
routes: [
{ path: '/promotion/from-newsletter', component: Promotion, props: { newsletterPopup: false } }
]
})複製程式碼
虛擬DOM
我做過測試,一個只有id屬性的div,遍歷一遍,有235個屬性或方法,同時瀏覽器還要計算css屬性,如果頻繁的操作DOM的話,對於效能影響會很大。
虛擬DOM就是用一個原生的js物件來描述一個DOM節點,現代瀏覽器執行js的速度非常快,所以在js物件裡來對DOM做一些操作會比直接操作DOM代價小的多。
Virtual DOM 除了它的資料結構的定義,對映到真實的 DOM 實際上要經歷 VNode 的 create、diff、patch 等過程。那麼在 Vue.js 中,VNode 的 create 是通過之前提到的 createElement
方法建立的
Vue把掛載的DOM的子節點都劫持到fragment裡,然後儲存以js物件的形式,
在底層的實現上,Vue 將模板編譯成虛擬 DOM 渲染函式。結合響應系統,Vue 能夠智慧地計算出最少需要重新渲染多少元件,並把 DOM 操作次數減到最少。