vue對比jquery
vue
:mvvm
數(shù)據(jù)驅動影響視圖 適用于復雜數(shù)據(jù)
jquery
:mvc
視圖塞入數(shù)據(jù) 適用于復雜視圖動效
生命周期
以下都是鉤子函數(shù)
beforeCreate
(創(chuàng)建前)
created
(創(chuàng)建后)
beforeMount
(載入前)
mounted
(載入后)
beforeUpdate
(更新前)
updated
(更新后)
beforeDestroy
(銷毀前)
destroyed
(銷毀后)
計算屬性
computed
:計算屬性
區(qū)別與methods
:
性能相比methods
要高 因為有緩存 只有在相關值發(fā)生改變時才會觸發(fā) 在第一次渲染頁面也會主動觸發(fā)
計算屬性的數(shù)據(jù)源未發(fā)生變化 則不會觸發(fā)響應的計算屬性
屬性區(qū)分于方法
<div id="app">
<p>原始字符串: {{ message }}</p>
<p>計算后反轉字符串: {{ reversedMessage }}</p>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
message: 'Runoob!'
},
computed: {
// 以下的函數(shù)將提供給計算屬性的 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'; //觸發(fā)set方法
document.write('name: ' + vm.name); //動態(tài)更新dom樹
document.write('<br>');
document.write('url: ' + vm.url);
</script>
相關指令
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
只是會根據(jù)布爾只能判斷是否增加display none
這個內聯(lián)樣式
v-if
和v-show
的區(qū)別:
v-if
有更高的切換消耗;
v-show
有更高的初始渲染消耗买羞;
v-if
適合運營條件不大可能改變;
v-show
適合頻繁切換
v-for
: 循環(huán)
v-once
只會渲染一次 即使數(shù)據(jù)改變
v-bind
用來響應地更新html屬性 使用場景:綁定接口請求得到的數(shù)據(jù) 簡寫: : 吃挑,可以綁定class和內聯(lián)樣式 例如:
<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作出區(qū)分 不使用也可以 前面是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
:用來監(jiān)聽dom
事件 其修飾符可以指定鍵盤事件
v-on:click
簡寫@click
:事件監(jiān)聽
v-model
:雙向綁定 一般結合input
textarea
(多行) 使用 其有修飾符.lazy
.number
.trim
過濾器
vue中可以自定義過濾器 被用作常見地文本格式化
<!-- 在兩個大括號中 -->
{{ message | capitalize }}
<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>
監(jiān)聽屬性
watch
:響應數(shù)據(jù)變化
<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中的相關綁定會觸發(fā)對應的觀察屬性
this.kilometers = val;
this.meters = val * 1000;
},
meters: function(val) {
this.kilometers = val / 1000;
this.meters = val;
}
}
});
// $watch 是一個實例方法 $作用與vue自帶的屬性區(qū)別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知識體系中最重要的一個模塊
組件的作用是:復用
前端路由相對于傳統(tǒng)路由 請求少 節(jié)省資源
mode:history
//不使用html5 實現(xiàn)前進和后退 默認設置
關于組件的引用 除了直接引用自定義標簽 is
標簽也可以引用組件到指定的位置,動態(tài)綁定組件
全局組件
<div id="app">
<runoob></runoob>
</div>
<script>
// 注冊 此中注冊方式為全局組件 所有的外部組件中都可以引用
Vue.component('runoob', {
template: '<h1>自定義組件!</h1>'
})
// 創(chuàng)建根實例
new Vue({
el: '#app'
})
</script>
局部組件
區(qū)分于全局組件
<div id="app">
<runoob></runoob>
</div>
<script>
var Child = {
template: '<h1>自定義組件!</h1>'
}
// 創(chuàng)建根實例
new Vue({
el: '#app',
components: {
// <runoob> 將只在父模板可用
'runoob': Child
}
})
</script>
template
template
模版 用來承載dom
樹 常在組件中使用
props
自定義組件屬性:通過props申明屬性 可以通過v-bind動態(tài)綁定自定義屬性
<div id="app">
<child message="hello!"></child>
</div>
<script>
// 注冊
Vue.component('child', {
// 聲明 props
props: ['message'],
// 同樣也可以在 vm 實例中像 “this.message” 這樣使用
template: '<span>{{ message }}</span>' //可以這樣理解:此處message既是屬性也是變量
})
// 創(chuàng)建根實例
new Vue({
el: '#app'
})
</script>
動態(tài)props
通過v-bind
實現(xiàn)
<div id="app">
<div>
<input v-model="parentMsg">
<br>
<!-- 通過v-bind綁定父組件中的parentMsg 實現(xiàn)動態(tài)綁定-->
<child v-bind:message="parentMsg"></child>
</div>
</div>
<script>
// 注冊
Vue.component('child', {
// 聲明 props
props: ['message'],
// 同樣也可以在 vm 實例中像 “this.message” 這樣使用
template: '<span>{{ message }}</span>'
})
// 創(chuàng)建根實例
new Vue({
el: '#app',
data: {
parentMsg: '父組件內容'
}
})
</script>
組件間交互
父組件往子組件傳入數(shù)據(jù)使用props
反過來則用emit
父傳子:
子組件props
定義屬性 子組件標簽引用v-bind
將父組件參數(shù)與子組件屬性綁定
<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 接受參數(shù)arg
子組件 this.$.emit(<fuc>,<arg>)
子組件標簽引用 v-on:<fuc>="fv_fuc"
流程: 子組件的emit觸發(fā)標簽引用的fuc繼而觸發(fā)父組件的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 //接收子組件的數(shù)據(jù)
}
}
})
</script>
自定義指令
directive
定義指令名稱
inserted
當綁定元素插入到dom中會觸發(fā)
<div id="app">
<p>頁面載入時脖岛,input 元素自動獲取焦點:</p>
<input v-focus>
</div>
<script>
// 注冊一個全局自定義指令 v-focus
Vue.directive('focus', {
// 當綁定元素插入到 DOM 中。
inserted: function(el) {
// 聚焦元素
el.focus()
}
})
// 創(chuàng)建根實例
new Vue({
el: '#app'
})
</script>
vue.directive
定義全局指令 directives: {}
的方式定義局部指令 這點和component(組件)
相似
<div id="app">
<p>頁面載入時,input 元素自動獲取焦點:</p>
<input v-focus>
</div>
<script>
// 創(chuàng)建根實例
new Vue({
el: '#app',
directives: {
// 注冊一個局部的自定義指令 v-focus 和components的使用相似
focus: {
// 指令的定義
inserted: function(el) {
// 聚焦元素
el.focus()
}
}
}
})
</script>
directive
可以和鉤子函數(shù)配合使用 不需要鉤子函數(shù)也可以簡寫 第二個參數(shù)是function
,默認的第一個參數(shù)是el
Vue.directive('runoob', {
// 綁定bind的鉤子函數(shù)
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參數(shù)注入路由 并且掛載根實例
頁面跳轉 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() 創(chuàng)建的組件構造器红淡,
// 或者在旱,只是一個組件配置對象颈渊。
// 我們晚點再討論嵌套路由俊嗽。
const routes = [{
path: '/foo',
component: Foo
},
{
path: '/bar',
component: Bar
}
]
// 3. 創(chuàng)建 router 實例,然后傳 `routes` 配置
// 你還可以傳別的配置參數(shù), 不過先這么簡單著吧竹揍。
const router = new VueRouter({
routes // (縮寫)相當于 routes: routes
})
// 4. 創(chuàng)建和掛載根實例芬位。
// 記得要通過 router 配置參數(shù)注入路由,
// 從而讓整個應用都有路由功能
const app = new Vue({
router
}).$mount('#app')
// 現(xiàn)在被饿,應用已經(jīng)啟動了!
</script>
路由參數(shù)
在映射表里設置 如:path:'/apple/:color'
ex6 語法
import
配合export default
使用以page的形式導出組件 這都是ex6的語法
另外一種寫法: 區(qū)別與上一種寫法 需要 {}
的使用
let com={ //let 在當前作用域下聲明一個變量,不會泄漏到外部 區(qū)別與var const:常量
}
export { com } //注意{}的使用
引用的時候:
import { com } from ...
腳手架
vue-cli
官方腳手架工具
優(yōu)勢
- 成熟的vue項目架構設計
- 本地測試服務器 熱加載服務器 熱更新
- 集成打包上線方案 webpack
系統(tǒng)要求:
node
>4.0
指令
vue list
:查看模版方案
vue init webpack demo
利用腳手架 初始化項目
項目結構
利用vue_lic
生成的項目結構:
build
: 項目構建(webpack)相關代碼
config
:配置目錄 包括端口號等 初學可以使用默認的
node_modules
:npm
加載的項目依賴模塊
src
:源碼 包含幾個目錄及文件:
-
assets
:放置一些圖片 logo -
components
:放置一個組件文件 可以不使用 -
App.vue
: 項目入口文件 可以直接把組件寫在這里 取代components
目錄 -
main.js
:項目的核心文件
.****
文件 配置文件 包括語法配置 git配置
static
:靜態(tài)文件 資源目錄 如圖片 字體等
package.json
:npm
需要的一套配置文件
index.html
: 首頁文件入口 可以添加一些meta
信息或者統(tǒng)計代碼
npm run build
:此指令用于生成部署用的文件 文件會存在dist
中
創(chuàng)建項目
步驟:
vue init webpack Vue-Project
- 根據(jù)提示配置項目信息
- cd 到項目下 執(zhí)行
npm install
:安裝相關依賴 此處需要翻墻 -
npm run dev
:運行項目
有時候瀏覽器打不開頁面可能是端口被占用
更換端口:
mac下查詢端口占用情況 例如查看8081端口:
lsof -i tcp:8081
細節(jié)雜記
字符串反轉:
message.split('').reverse().join('')
"-" 命名的屬性引用時必須使用單引號
vue中可以綁定對象 也可以綁定對象的計算屬性
例子:
<div id="app">
<div v-bind:class="classObject"></div>
</div>
<script>
new Vue({
el: '#app',
data: {
isActive: true,
error: null
},
computed: {
classObject: function () {
return {
active: this.isActive && !this.error,
'text-danger': this.error && this.error.type === 'fatal',
}
}
}
})
</script>
內聯(lián)樣式的兩種寫法:
- 在
html
中直接{}
- 在
css
中定義class
然后html
中引用
關于導出組件的data中采用函數(shù)return data
的方式 形成自己的實例 防止復用沖突
vue2.0
如果需要js的完全編程能力 必須使用render
渲染外部引入的app組件
區(qū)別與template
更接近與編譯器
template
寫 html撼泛,script
寫 js损俭,style
寫樣式雁仲,一個template
只能有一個div
除了數(shù)據(jù)屬性,Vue
實例還提供了一些有用的實例屬性與方法吹艇。它們都有前綴 $
,以便與用戶定義的屬性區(qū)分開來,例如:
<div id="vue_det">
<h1>site : {{site}}</h1>
<h1>url : {{url}}</h1>
<h1>Alexa : {{alexa}}</h1>
</div>
<script type="text/javascript">
// 我們的數(shù)據(jù)對象
var data = {
site: "菜鳥教程",
url: "www.runoob.com",
alexa: 10000
}
var vm = new Vue({
el: '#vue_det',
data: data
})
document.write(vm.$data === data) // true 使用的時候需要前綴$
document.write("<br>") // true
document.write(vm.$el === document.getElementById('vue_det')) // true
</script>