開發之路,羊腸九曲,荊棘密佈,幸得高人指點,前輩填坑,一路謹小慎微,終得工程圓滿;其間填坑之經驗,開路之歷程,皆爲精華,不可棄之;記錄於此,以便事後回顧,亦想於有相關開發疑惑之同學做參考之用,文中如若有錯,懇請雅正,不勝感激。
VUE快速入門筆記
- 概述
- 學習筆記
- 安裝
- 聲明式渲染
- 綁定屬性
- 條件
- 循環
- 點擊事件
- 組件化
- 數據與方法
- 實例屬性與方法。它們都有前綴 $
- 生命週期函數(鉤子)
- 文本
- 富文本
- 對於布爾特性 (它們只要存在就意味着值爲 true)
- 縮寫
- 計算屬性(基於它們的響應式依賴進行緩存的,不會多次執行,)
- 偵聽屬性
- 偵聽器(異步/開銷大)
- 對象語法
- 數組語法
- 條件
- 用 key 管理可複用的元素
- 變異方法 (mutation method)
- 替換數組
- 不檢測改動
- 已有對象賦值新屬性
- 父子組件傳值
- 監聽事件
- 訪問原始dom
- 事件修飾符 (可以串聯)
- 按鍵修飾符
- 系統修飾鍵
- 雙向數據綁定
- 修飾符
- 組件註冊
- 組件data 必須是函數
- 實例創建之前驗證
- 動態組件持久化
- 異步組件
- 邊界情況
- 自定義指令
- 插件
- 類型推斷
- 生產環境
- vue-router路由
- Ajax axios
- vue-resource
概述
vue 是一套漸進式Javascript框架,它的設計採用的是自底向上增量開發設計,因爲其核心庫只關注視圖層,所以學習起來很方便,並且易於其他庫及現有項目結合。
學習筆記
現就學習vue整個過程做一簡單記錄,方便後期回顧,亦方便有需要是查閱。
Vue官方文檔
安裝
npm install vue
聲明式渲染
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
})
綁定屬性
v-bind:title=""
:title=""
條件
v-if=“”
循環
v-for=“todo in todos”
點擊事件
v-on:click=""
@click=""
methods:{
function(){}
}
組件化
Vue.component('todo-item', {
props: ['todo'],
template: '<li>{{ todo.text }}</li>'
})
<todo-item
v-for="item in groceryList"
v-bind:todo="item"
v-bind:key="item.id"
></todo-item>
數據與方法
var data={a:1}
var vm = new Vue({
data:data
})
Object.freeze(),這會阻止修改現有的屬性
實例屬性與方法。它們都有前綴 $
vm.$data = data
vm.$el = document.getElementById()
vm.$watch('a',function(newvalue,oldvalue){
//vm.a改變之後調用
})
生命週期函數(鉤子)
beforeCreate created beforeMount mounted
beforeUpdate updated beforeDestroy destroyed
文本
{{msg}}
v-once 一次性插值
富文本
v-html=“html”
對於布爾特性 (它們只要存在就意味着值爲 true)
js表達式
{{ ok ? 'YES' : 'NO' }}
指令 v-if 參數 v-bind:href=“url” v-on:click=“fun”
動態參數 null移除 轉小寫
v-bind:[attr]=“url”
修飾符(modifier)
<form v-on:submit.prevent="onSubmit">...</form>
告訴 v-on 指令對於觸發的事件調用 event.preventDefault()
縮寫
v-bind == :
v-on == @
計算屬性(基於它們的響應式依賴進行緩存的,不會多次執行,)
默認getter
computed: {
now: function(){
return this.msg
},
fullName:{
get:function(){
return this.firstName
},
set:function(newValue){
this.firstName = newValue
}
}
}
vm.fullName="newValue"
偵聽屬性
watch: {
firstName: function (val) {
this.fullName = val + ' ' + this.lastName
},
lastName: function (val) {
this.fullName = this.firstName + ' ' + val
}
}
偵聽器(異步/開銷大)
_.debounce
是一個通過 Lodash 限制操作頻率的函數。
watch: {
// 如果 `question` 發生改變,這個函數就會運行
question: function (newQuestion, oldQuestion) {
this.answer = 'Waiting for you to stop typing...'
this.debouncedGetAnswer()
}
},
對象語法
v-bind:class="{acrive:isActive,'danger':hasErr}"
數組語法
v-bind:class="[isActive ? activeClass:'',errClass]"
v-bind:class="[{ active: isActive }, errorClass]"
條件
v-if="" v-else-if="" v-else
用 key 管理可複用的元素
<template v-if="loginType === 'username'">
<label>Username</label>
<input placeholder="Enter your username" key="username-input">
</template>
<template v-else>
<label>Email</label>
<input placeholder="Enter your email address" key="email-input">
</template>
- v-show 的元素始終會被渲染並保留在 DOM 中
- v-for 具有比 v-if 更高的優先級
- v-for="(item, index) in items"
- v-for="(value, name) in object"
- v-for=“item in items” v-bind:key=“item.id”
變異方法 (mutation method)
push() pop() shift() unshift() splice() sort() reverse()
替換數組
filter()、concat() 和 slice()
不檢測改動
vm.items[indexOfItem] = newValue
Vue.set(vm.items, indexOfItem, newValue)
vm.items.splice(indexOfItem, 1, newValue)
vm.$set(vm.items, indexOfItem, newValue)
已有對象賦值新屬性
vm.userProfile = Object.assign({}, vm.userProfile, {
age: 27,
favoriteColor: 'Vue Green'
})
v-for 的優先級比 v-if 更高
父子組件傳值
props: [‘title’]
監聽事件
v-on
訪問原始dom
@click=“fun($event)”
事件修飾符 (可以串聯)
.stop 阻止單擊事件繼續傳播
.prevent 阻止默認行爲的發生
.capture 元素自身觸發的事件先處理,然後交內部處理
.self 事件不是從內部觸發的
.once 事件將只會觸發一次
.passive 不阻止事件的默認行爲
按鍵修飾符
.enter .tab .delete .esc .space .up .down .left .right
// 可以使用 `v-on:keyup.f1`
Vue.config.keyCodes.f1 = 112
系統修飾鍵
.ctrl .alt .shift .meta
@click.ctrl="doSomething" ctrl+click
@keyup.alt.67="clear" Alt+C
.exact 修飾符允許你控制由精確的系統修飾符組合觸發的事件。
雙向數據綁定
v-model=“”語法糖
複選框 true-value="yes" false-value="no"
修飾符
.lazy input事件與change同步
.number 輸入值轉爲數值類型
.trim 去除首尾空格
組件註冊
Vue.component('my-component-name', {
// ... options ...
})
new Vue({
el: '#app',
components: {
'component-a': ComponentA,
'component-b': ComponentB
}
})
import ComponentA from './ComponentA'
import ComponentC from './ComponentC'
export default {
components: {
ComponentA,
ComponentC
},
// ...
}
組件data 必須是函數
data: function () {
return {
count: 0
}
}
每個組件必須只有一個根元素
模板字符串 ``
子組件可以通過調用內建的 emit('父級屬性‘)
通過插槽分發內容 v-slot:==#
<slot name="default" v-bind:user="user">Default</slot>
<template v-slot:default="slotProps">default {{slotProps.user.name}}</template>
<current-user #default="{ user }">
{{ user.firstName }}
</current-user>
特殊的 is 特性 判斷 並替換 <tr is="">
prop
props: {
title: String,
propA:{
type:Object,
required:true,
default:function(){
return {msg:"hello"}
},
validator:function(value){
return ['',''].indexOf(value) !== -1
}
}
}
實例創建之前驗證
v-bind:is-published="post.isPublished"
v-bind="post" //傳入對象的所有屬性
單向流動 賦值初始值或者使用計算屬性
非prop屬性自動添加至跟元素 class style會合並,其他會替換
禁用特性繼承 inheritAttrs: false
一個組件上的 v-model 默認會利用名爲 value 的 prop 和名爲 input 的事件
model: {
prop: 'checked',
event: 'change'
},
<base-checkbox v-model="lovingVue"></base-checkbox>
<base-input v-on:focus.native="onFocus"></base-input> 原生事件
Vue.component('base-input', {
inheritAttrs: false,
props: ['label', 'value'],
computed: {
inputListeners: function () {
var vm = this
// `Object.assign` 將所有的對象合併爲一個新對象
return Object.assign({},
// 我們從父級添加所有的監聽器
this.$listeners,
// 然後我們添加自定義監聽器,
// 或覆寫一些監聽器的行爲
{
// 這裏確保組件配合 `v-model` 的工作
input: function (event) {
vm.$emit('input', event.target.value)
}
}
)
}
},
template: `
<label>
{{ label }}
<input
v-bind="$attrs"
v-bind:value="value"
v-on="inputListeners"
>
</label>
`
})
<text-document v-bind:title.sync="doc.title"></text-document>
動態組件持久化
<keep-alive>
<component v-bind:is="currentTabComponent"></component>
</keep-alive>
異步組件
new Vue({
// ...
components: {
'my-component': () => import('./my-async-component')
}
})
Vue.component('async-webpack-example', function (resolve) {
// 這個特殊的 `require` 語法將會告訴 webpack
// 自動將你的構建代碼切割成多個包,這些包
// 會通過 Ajax 請求加載
require(['./my-async-component'], resolve)
})
const AsyncComponent = () => ({
// 需要加載的組件 (應該是一個 `Promise` 對象)
component: import('./MyComponent.vue'),
// 異步組件加載時使用的組件
loading: LoadingComponent,
// 加載失敗時使用的組件
error: ErrorComponent,
// 展示加載時組件的延時時間。默認值是 200 (毫秒)
delay: 200,
// 如果提供了超時時間且組件加載也超時了,
// 則使用加載失敗時使用的組件。默認值是:`Infinity`
timeout: 3000
})
邊界情況
根實例 this.$root.
父組件 this.$parent.
自組件/子元素 this.$refs.usernameInput
依賴注入 provide inject
provide: function () {
return {
getMap: this.getMap
}
}
inject: ['getMap']
程式化偵聽 $emit $on $once $off
組件的遞歸調用 避免
組件循環引用 全局註冊 beforeCreate註冊 webpack異步import
內聯模板 inline-template <my-component inline-template>
<script type=“text/x-template” id=“hello-world-template”>
強制更新 $forceUpdate
靜態組件 v-once緩存降低開銷
第三方動畫庫 Animate.css Velocity.js
<transition name="fade">
<p v-if="show">hello</p>
</transition>
enter enter-active enter-to leave leave-active leave-to
自定義指令
Vue.directive('focus', {
// 當被綁定的元素插入到 DOM 中時……
inserted: function (el) {
// 聚焦元素
el.focus()
}
})
directives: {
focus: {
// 指令的定義
inserted: function (el) {
el.focus()
}
}
}
<input v-focus>
插件
Vue.use(MyPlugin, { someOption: true })
過濾器 |
filters: {
capitalize: function (value) {
if (!value) return ''
value = value.toString()
return value.charAt(0).toUpperCase() + value.slice(1)
}
}
{{value|capitalize}}
類型推斷
const Component = Vue.extend({
// 類型推斷已啓用
})
生產環境
webpack
module.exports={
mode:'production'
}
vue-router路由
<router-link :to="{ path: '/abc'}" replace></router-link>
<router-link :to="{ path: 'relative/path'}" append></router-link>
<router-link to="/foo" tag="li">foo</router-link>
<!-- 渲染結果 -->
<li>foo</li>
<router-link v-bind:to = "{ path: '/route1'}" active-class = "_active">Router Link 1</router-link>
<router-link v-bind:to = "{ path: '/route1'}" exact-active-class = "_active">Router Link 1</router-link>
<router-link v-bind:to = "{ path: '/route1'}" event = "mouseover">Router Link 1</router-link>
Ajax axios
axios.get('url').then(response=>()).catch(function(){})
axios.post('url',{}).then(response=>()).catch(function(){})
axios.all([get(),get2()]).then(axios.spread(function(acct,perms){}))
vue-resource
this.$http.get(url,{params:jsonData}).then((success)=>{},(fail)=>{})
get(url, [options])
head(url, [options])
delete(url, [options])
jsonp(url, [options])
post(url, [body], [options])
put(url, [body], [options])
patch(url, [body], [options])
this.$http.post('/someUrl', [body], [options]).then(successCallback, errorCallback);