Vuehtml
腳手架 3 的版本 ---- webpack 4vue
cnpm install -g @vue/cli-----全局安裝組件webpack
vue create myapp-----命令行建立項目git
或者使用 vue ui--------界面UI建立項目github
腳手架 2 的版本 ---- webpack 3web
npm install -g @vue/cli-init 算法
vue init webpack myapp2vue-router
數據的雙向綁定npm
原理編程
1.實現一個監聽器Observer,用來劫持並監聽全部屬性,若是有變更的,就通知訂閱者。
2.實現一個訂閱者Watcher,能夠收到屬性的變化通知並執行相應的函數,從而更新視圖。
3.實現一個解析器Compile,能夠掃描和解析每一個節點的相關指令,並根據初始化模板數據以及初始化相應的訂閱器。
基礎用法
<div>
{{ msg }} --- {{ num }} --- {{ flag }} --- {{ obj.a }} ---- {{ obj.b }} // 在dom中使用雙大括號包裹變量,視圖中就會渲染數據
</div>
<div v-html="msg"></div> mag爲data中申明的變量,是一個html格式
<div v-text="msg"></div> mag爲data中申明的變量,是一個html格式
{{ sex == 0 ? '女' : '男' }} 三目運算符,sex爲在data中申明的變量
vue中的指令
v-html,就會把它的值插入到該標籤內部
v-text
v-if 條件判斷 渲染仍是不渲染 ---- 運行時消耗更大,適用於少許的切換使用
v-else-if
v-else
v-show 條件判斷 元素始終會被渲染並保留在 DOM中。v-show只是簡單地切換元素的CSS的display屬性。適用於頻繁的切換時使用
v-for 遍歷循環使用
v-on 綁定事件 縮寫使用@
v-bind 綁定屬性,給變量使用,
不經常使用的
v-slot
v-pre
v-cloak
v-once
v-for = 「item of/in list」 :key="惟一性的值"
v-for = 「(item, index) of/in list」 :key="index"
能夠遍歷數組,能夠遍歷對象,還能夠遍歷字符串,必定要記得加 key值(鑰匙與鎖的故事 -- 詳細介紹 --- 虛擬DOM算法)
<li v-for="(item,index) of arr" :key="index">
{{item.name}}
<ul>
<li v-for="(ite,ind) of item.type" :key="ind">
{{ite}}
</li>
</ul>
</li>
v-model 數據的雙向綁定 原理是onchange 和oninput事件
v-model.lazy 失去焦點或者按回車鍵時纔會運算
v-model.trim 獲得的值去除兩端空格
v-model.number 喚起數字鍵盤
<style>
.active {
font-size: 40px;
color: #f66;
}
</style>
<!- ->
<div :class="{active: flag}">若是vue項目中的active樣式是由flag的值控制的</div> 將active賦值給class,經過flag爲真或假來實現
data: {
flag: true
}
一樣也能夠給一個class綁定多個屬性 使用數組的方式
<div :class="[activeClass, testClass]">數組寫法就是先把數據定義好,直接數組包裹便可</div>
data: {
activeClass: 'active', active 是class的類名
testClass: 'test' test 是class的類名
}
<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div> // 各類樣式能夠直接寫在style中
-------------------------
const vm = new Vue({
data: {
activeColor: 'red', fontSize: 30
}
<div v-bind:style="styleObject"></div> 也能夠將樣式放在一個變量中,經過變量將樣式賦值
-----------
data: {
styleObject: {
color: 'red',
fontSize: '13px'
}
}
})
事件修飾符
阻止冒泡 v-on:click.stop="fn()"
阻止默認事件 v-on:click.prevent="fn"
阻止冒泡阻止默認事件 v-on:click.stop.prevent="fn"
.capture 添加事件監聽器時使用事件捕獲模式 即元素自身觸發的事件先在此處理,而後才交由內部元素進行處理
.self 只當在 event.target 是當前元素自身時觸發處理函數 即事件不是從內部元素觸發的
.once 點擊事件將只會觸發一次
.passive 不要把 .passive 和 .prevent 一塊兒使用,由於 .prevent 將會被忽略,同時瀏覽器可能會向你展現一個警告。
按鍵修飾符
之前若是有一個表單輸入框,當你輸入以後敲回車想要打印值
<input onchange="fn(event)" id="name" />
if (event.keyCode === 13) {name.value}
vue
<input @change.enter="fn()" id="name" />
.tab
.delete
.esc
.space
.up
.down
.left
.right
系統修飾符
.ctrl
.alt
.shift
.meta
初始化階段
beforeCreate(){} // 準備懷孕
created(){} // 懷上了 *******************************************
beforeMount(){} // 準備生
mounted(){} // 生下來了 *************************************************
運行時階段
beforeUpdate(){} // 天天都在長大
updated(){} ************************
銷燬階段
beforeDestroy(){} // 立刻 game over
destroyed(){} // game over gg ************
-----------------------------------------------------------------------------------------------------------------
在 created 或者 mounted 中請求數據,建議在mounted中請求數據
能夠在 mounted 和 updated 中操做dom
動態組件默認狀況下切換時都是先銷燬掉原來的組件,再建立新的組件
避免組件的從新渲染,可使用<keep-alive></keep-alive>,可是會緩存全部的加載過的組件
定義組件時添加name選項,keep-alive 添加include屬性,值爲name選項,須要緩存的寫進去,經過include和name值,就能夠只緩存須要的組件
首先在data中定義type,而且賦值,值就是默認顯示的組件 <body> <div id="app"> <button @click="type = 'v-aaa'">A組件</button> // 經過事件改變type <button @click="type = 'v-bbb'">B組件</button> // 經過事件改變type <button @click="type = 'v-ccc'">C組件</button> // 經過事件改變type <component :is="type"></component> // 經過type來實現切換不一樣的組件 </div> </body> ---------------------------------------------------------------------------------------- 緩存全部加載的組件 <body> <div id="app"> <button @click="type = 'v-aaa'">A組件</button> <button @click="type = 'v-bbb'">B組件</button> <button @click="type = 'v-ccc'">C組件</button> <keep-alive> // 保留全部加載過的組件 <component :is="type"></component> </keep-alive> </div> </body> --------------------------------------------------------------------------------------- 緩存須要的組件。須要的組件加載過就緩存,其它組件加載了也不緩存 <body> <div id="app"> <button @click="type = 'v-aaa'">A組件</button> <button @click="type = 'v-bbb'">B組件</button> <button @click="type = 'v-ccc'">C組件</button> <keep-alive include="aaa,bbb"> // 當aaa bbb只要加載了就會被緩存下來 <component :is="type"></component> </keep-alive> </div>
router-view 告訴頁面在哪裏渲染組件。
components: {
default: home
footer: Footer
}
<router-view> </router-view>渲染默認的default組件
<router-view name="footer"> </router-view> 渲染名字爲footer的組件
聲明式跳轉
<!-- 使用 router-link 組件來導航. --> <!-- 經過傳入 `to` 屬性指定連接. --> <!-- <router-link> 默認會被渲染成一個 `<a>` 標籤 -->
1 <router-link to="/foo">Go to Foo</router-link>
2 <router-link to="/foo" tag="li">Go to Foo</router-link>
3 <router-link to="{name: 'user', params: { userId: '123' }}" tag="li">Go to Foo</router-link>
編程式跳轉
router.push('home'
router.push({ path: 'home' })
router.push({ path: `/user/${userId}` }) // -> /user/123
router.push({ name: 'user', params: { userId: '123' }}) router.push({ path: 'register', query: { plan: 'private' }})
注意:
使用path 後面傳參要使用query,使用 name 搭配 params
path: '/detail/:id', // :表明此處的值爲參數,id爲參數的名字 -------------------------- 這個必須設置
{ path: '/user', // 瀏覽器地址輸入/home時 name: 'user', // 路由的名字----命名路由 // component: () => import('./views/user/index.vue') components: { default: () => import('./views/user/index.vue'), footer: Footer // 爲何不用懶加載,由於多出須要調用,先引入再使用 }, children: [ // 定義子路由,即路由中嵌套路由 { path: 'nologin', // /user/nologin component: () => import('@/components/user/NoLogin.vue') }, { path: 'login', // /user/login component: () => import('@/components/user/Login.vue') } ] }
導航守衛
全局導航守衛
router.beforeEach((to, from, next) => { // ... })
router.afterEach((to, from) => { // ... }) 全局後置的導航守衛
路由導航守衛
beforeEnter: (to, from, next) => { // ... }
組件內導航守衛
beforeRouteEnter // 注意this的問題,裏面沒有this 使用vm代替
beforeRouteUpdate
beforeRouteLeave
beforeRouteEnter (to, from, next) { // 在渲染該組件的對應路由被 confirm 前調用 // 不!能!獲取組件實例 `this` // 由於當守衛執行前,組件實例還沒被建立 }, beforeRouteUpdate (to, from, next) { // 在當前路由改變,可是該組件被複用時調用 // 舉例來講,對於一個帶有動態參數的路徑 /foo/:id,在 /foo/1 和 /foo/2 之間跳轉的時候, // 因爲會渲染一樣的 Foo 組件,所以組件實例會被複用。而這個鉤子就會在這個狀況下被調用。 // 能夠訪問組件實例 `this` }, beforeRouteLeave (to, from, next) { // 導航離開該組件的對應路由時調用 // 能夠訪問組件實例 `this` }
beforeRouteEnter (to, from, next) { next(vm => { // 經過 `vm` 訪問組件實例 }) }
重定向
{ // 路由的重定向 path: '/', redirect: '/home' 當輸入 / 定向到 /home }
路由的別名
path: '/home', // 瀏覽器地址輸入/home時 name: 'home', // 路由的名字----命名路由 alias: '/ho', // 別名 --- 當你訪問 /ho 時,其實和訪問 /home是一致的
component: () => import('./views/home/index.vue') // 路由的懶加載
UI庫
PC端項目
iview (http://v1.iviewui.com/)
element-ui (https://element.eleme.cn/#/zh-CN)
移動端
mint-ui (http://mint-ui.github.io/#!/zh-cn)
vant (https://youzan.github.io/vant/)
狀態管理器
state 初始化狀態管理器
getter state的計算屬性,負責邏輯的運算
mutation 惟一改變state的方法,mutation 必須是同步函數
this.$store.commit('定義的事件','數據')
action 相似mutation 不過這裏是處理異步的
module 分割狀態管理器,模塊化管理,好比一個大的狀態管理器,能夠分解多個模塊每一個模塊都具備 state getter mutation action
export default new Vuex.Store({ state: { // 須要管理的組件的狀態 login: '', number: '' }, getters: { // 能夠看作是 state 的計算屬性,相似於組件中的 data 與 computed }, mutations: { // 惟一改變狀態的地方 change (state,data) { state.number = data } }, actions: { // 異步操做 } }) -------------------------------------------------------- this.$store.state.login 獲取狀態管理器的值 this.$store.commit('','') 改變狀態管理器的值
組件中的內容是不能顯示的,只有經過slot才能添加內容
<header class="header"> <ul> <li @click="back"> <slot name="left"><p>返回</p></slot> // 定義slot </li> <li> <slot></slot> // 定義slot </li> <li> <slot name="right"></slot> // 定義slot </li> </ul> </header> ------------------------------ <header> <div solt="right">分享</div> // 使用 </header>
做用相似於id,具備惟一性 ---- 實際上操做的就是DOM
<div ref="tip">{{msg}}</div> -------------- this.$refs.tip.innerText // 可使用this.$refs獲取
組件中相同的選項可使用混入簡化代碼 ---- 提升組件的複用性 -----
import Header from '@/components/Header'
export default { // 暴露出去這個組件
components: { // 共同的部分
Header
}
}
-----------------------
import mymixins from '@/mixins/mymixins' // 引入組件
export default {
mixins: [mymixins] 調用引入的組件
}
局部定義的過濾器
<div> {{ sex | sexFilter}} ---- {{ money | moneyFilter}} // 加 | 而後使用 過濾函數 </div> ---------------------------------------- filters: { moneyFilter (val) { // 聲明過濾函數 val就是money值 return '¥' + val // 返回的就是顯示的值 } }
狀態改變,視圖渲染,實際上DOM節點的值並未及時發生改變,使用nextTick能夠解決此問題
// console.log(this.$refs.tip.innerText) // 打印結果沒有,實際視圖已經渲染 this.$nextTick(function () { console.log(this.$refs.tip.innerText) // 使用nextTick包裹實現同步 })