快速上手Vue
官方文檔:點擊 javascript
1、npm
npm文檔:點擊 css
一、npm的安裝
-
去官網 https://nodejs.org/en/download/ 下載安裝,Node.js是運行在服務端的JavaScript,基於Chrome V8 引擎的。html
-
打開終端 cmd : 執行
node -v
若是出現版本號,證實安裝node成功前端 -
下載完node以後,會自帶包管理器npm,比如是python中 pip3包管理器。pip3 install xxxvue
-
查看安裝版本信息:java
-
node -v
查看Node.js 版本信息node -
npm -v
查看npm版本信息python -
npm install npm@5.3.0 -g
更新npm到指定版本react -
npm install npm@latest -g
更新最新版本jquery
-
二、npm 經常使用操做
以前用JQuery,Bootstrap的cdn或者直接手動下載並放入項目,並且要管理版本。 有了npm,咱們管理本身的依賴包以及版本更加簡單。
-
cd到項目目錄 :
-
初始化npm的項目 :
npm init --yes
使用默認配置項 生成package.json文件。 -yes可簡寫-y -
下載依賴包
npm install vue --save
npm install vue@1.0.1 --save
npm install vue-router -S
npm install axios -S
npm i webpack@3.12.0 -D
在項目下 npm init 後再下載webpack就是局部安裝 保存爲開發環境依賴
npm install css-loader -D
npm install style-loader -D
npm install html-webpack-plugin -D
npm install webpack-dev-server@2.9.0 -D
npm install vue-loader@14.1.1 -D
npm install vue-template-compiler@2.5.17 -D
npm i jquery --save
簡寫install 爲 i 下載依賴 不寫@ 默認最新版本npm i webpack@3.12.0 -g
全局安裝 -
卸載包
npm uninstall vue
-
更新包
npm update jquery
-
下載全部的依賴包
npm install
-
npm list
列出已安裝的依賴 -
老版本須要
--save
參數 如今不須要了
項目目錄下會生成一個 node_modules 目錄,npm下的包會在這個目錄中。
全部的依賴以及版本信息放在package.json文件中,
若是刪掉 node_modules目錄,可使用 npm i 來下載全部依賴。
三、npm 經常使用配置項
當咱們用npm init 的時候用了參數 -y,若是不用-y咱們能夠進行一些配置。
-
package.json文件中有不少配置項
-- name 項目名字 中間不能有空格只能用小寫
-- version 項目版本
-- description 項目描述信息
-- main 項目的入口文件
-- scripts 指定命令的快捷方式 npm run test test是scripts裏的鍵名 值爲具體命令
-- author 做者
-- license 許可證
-- dependencies 生成環境依賴的包以及版本信息
-- devDependencies 開發環境的依賴

<body> <div id="app"> <!-- 模板語法 主要的做用是插值{{}} angualr {{}} react {}--> <h3>{{ msg }}</h3> <h3>{{ msg+ 'hello'}}</h3> <h4>{{1< 1 ? '真的':'假的'}}</h4> <!-- 能夠插入字符串 --> <h5>{{'hello'}}</h5> <p>{{'hello world'.split('').reverse().join('')}}</p> <h3>{{ {name:'role'} }}</h3> <!-- 不能使用if - else --> <!-- {{}}模板語法的設計 只是爲了簡單的運算 --> </div> <!-- 1.先引包 --> <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script type="text/javascript"> // 2.建立vue實例化對象 var app = new Vue({ // 發生行爲的目的地, // 在vue的內部運行機制中,須要根據你傳遞的字符串進行判斷,好比看你傳遞的字符串是#xxx仍是.xxx仍是 div元素查找 // el:document.getElementById('#app'),使用這種方式更爲優化,將元素直接找到,避免vue來進行判斷 el:'#app', // 裝載的模板 template:``, // 先聲明數據屬性 data:{ // data在Vue實例化中能夠是一個對象,也能夠是一個函數,可是在組件中,data必須是一個函數 函數內容必定return 一個對象 // template中要使用的數據 // 數據驅動視圖 msg:'hello Vue', } }); app.a = 10; console.log(app.$el); console.log(app.a); console.log(app); //Vue對象 console.log(app.$el===document.getElementById('app')); //true // 在vue實例化對象以後,這個對象中屬性 前面會有$,主要是跟咱們本身定義的屬性區分 </script> </body>
2、指令系統
一、經常使用指令
Vue的指令directives很像咱們所說的自定義屬性,指令是Vue模板中最經常使用的功能, 它帶有v-前綴,功能是當表達式改變的時候,相應的行爲做用在DOM上。
-
v-test
至關與js中innerText -
v-html
至關與js中innerHTML -
v-if v-else-if v-else
v-if 是「真正」的條件渲染,由於它會確保在切換過程當中條件塊內的事件監聽器和子組件適當地被銷燬和重建。 -
v-for
v-for = '(item,index) in menuList'
v-for = '(value,key) in object' -
v-show
無論初始條件是什麼,元素老是會被渲染,而且只是簡單地基於 CSS 進行切換。 -
v-bind
使用v-bind:class = '{}||[]||變量名||常量' 對咱們的頁面中標籤的屬性進行綁定 全部的屬性均可以進行綁定
注意只要使用了v-bind 後面的字符串必定是數據屬性中的值.
:id 等價於v-bind:id -
v-on
v-on:click對當前DOM綁定click事件 注意:全部的原生js的事件使用v-on均可以綁定
v-on:click 等價於 @click = '方法名' -
v-model
二、$屬性
- $refs獲取組件內的元素
- $parent:獲取當前組件的父組件
- $children:獲取當前組件的子組件
- $root:獲取New Vue的實例化對象
- $el:獲取組件對象的DOM元素
-
獲取更新以後的dom添加事件的特殊狀況:
$nextTick 是在下次Dom更新循環結束以後執行的延遲迴調,在修改數據以後使用$nextTick ,則能夠在回調中獲取更新以後的DOM

<body> <div id="app"> <h3>{{msg}}</h3> <h2 v-text='msg2'></h2> <p v-html='msg2'></p> <div class="box" v-if='isShow'></div> <div class="box" v-show='isShow'></div> <button @mouseenter="on_mouse()" @mouseleave="on_mouse()">鼠標移入移出</button> <p v-show="show">提示文本</p> <!-- v-if --> <div v-if='Math.random() > 0.5'>此值大於0.5</div> <div v-else>此值小於0.5</div> <div> <div v-if="role == 'admin' || role=='super_admin' ">管理員你好</div> <div v-else-if="role == 'hr'">待查看簡歷列表</div> <div v-else> 沒有權限</div> </div> <ul> <li v-for='(item,index) in menuList'> <h3>{{index}}--菜名:{{item.name}}--價格{{item.price}}</h3> </li> </ul> <ul> <li v-for='item in menuList'> <h3>價格{{item.price}}--菜名:{{item.name}}</h3> </li> </ul> <ul> <li v-for='(value,key) in object'> {{key}}--{{value}} </li> </ul> <ul> <li v-for="hobby in hobby_list">{{hobby}}</li> </ul> <div class="wrap" v-bind:class='{active:isGreen}'></div> <a v-bind:href="href">路飛</a> <!-- v-on --> <button v-on="{mouseenter: onMouseenter, mouseleave: onMouseleave}" v-on:click="onClick(1)">點我</button> <input type="text" v-on="{keyup: onKeyup}"> </div> <script type="text/javascript" src="./node_modules/vue/dist/vue.js"></script> <script type="text/javascript"> // innerHTML innerText new Vue({ el: '#app', template: ``, data: { // 數據屬性 msg: 'hello 指令系統', msg2: '<a href="#">這是個人數據</a>', isShow: false, show: false, menuList: [ // 數據驅動視圖 { id: 1, name: '大腰子', price: 60 }, { id: 2, name: '宮保雞丁', price: 30 }, { id: 3, name: '炸黃花魚', price: 70 }, { id: 4, name: '炸黃花魚2', price: 30 } ], hobby_list: ["王者毒藥","LOL","吃雞"], object: { name: 'alex', age: 19, }, isGreen:true, href:'https://www.luffycity.com/course', role: 'hr', }, methods: { on_mouse: function () { this.show = !this.show }, onClick: function (a) { alert(a) }, onMouseenter: function () { console.log("mouse enter") }, onMouseleave: function () { console.log("mouse leave") }, onKeyup: function () { console.log("key up") } }, }); </script> </body>

<body> <div id="app"> <label> 足球 <input type="checkbox" v-model="hobby" value="football"> </label> <label> 籃球 <input type="checkbox" v-model="hobby" value="basketball"> </label> {{hobby}} <label> 男 <input type="radio" v-model="sex" value="male"> </label> <label> 女 <input type="radio" v-model="sex" value="female"> </label> {{sex}} <textarea v-model="article"></textarea> {{article}} <select v-model="color"> <option value="1">單選1</option> <option value="2">單選2</option> </select> {{color}} <select v-model="goods" multiple=""> <option value="1">多選1</option> <option value="2">多選2</option> <option value="3">多選3</option> </select> {{goods}} <!-- v-model這個指令很好理解,其實它就是一個語法糖 它是oninput事件和綁定value的實現 --> <input type="text" :value = 'text' @input = 'valueChange'> <h3>{{ text }}</h3> <input type="text" v-model="con"> <h3>{{ con }}</h3> <input type="text" v-model = 'alexDesc'> <h4>{{alexDesc}}</h4> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script type="text/javascript"> var app = new Vue({ el: '#app', data: { //sex: "male", sex: '', //hobby:['football'], hobby:['football','basketball'], article:'這是一段文本。', color:'1', goods: ['2'], text:'alex', con:'hello', myName:'', }, methods:{ valueChange(event){ console.log(event.target.value); this.text = event.target.value } }, computed:{ alexDesc:{ set:function(newValue) { this.myName = newValue; }, get:function() { return this.myName; } } } }); </script> </body>

<body> <div id="app"></div> <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script type="text/javascript"> Vue.component('subComp',{ template:`<div></div>` }) var App = { data(){ return{ isShow:false } }, template: `<div> <subComp ref = 'subc'></subComp> <button ref = 'btn'>我是按鈕</button> <p ref = 'sb'>alex</p> <input type="text" v-if = 'isShow' ref = 'fos'/> </div>`, beforeCreate() { console.log(this.$refs.btn);//undefined }, created() { console.log(this.$refs.btn);//undefined }, beforeMount() { console.log(this.$refs.btn); //undefined }, mounted() { console.log(this); // VueComponent 組件對象 console.log(this.$refs.btn); // <button>我是按鈕</button> // 若是是給組件綁定的ref = 'subc'屬性那麼this.$refs.subc取到的是組件對象 console.log(this.$refs.subc); // VueComponent 組件對象 var op = this.$refs.sb; this.$refs.btn.onclick = function() { console.log(op.innerHTML); }; // vue實現響應式並非數據發生變化以後DOM馬上發生變化,而是按必定的策略進行DOM的更新 // $nextTick 是在下次Dom更新循環結束以後執行的延遲迴調,在修改數據以後使用$nextTick ,則能夠在回調中獲取更新以後的DOM this.isShow = true; console.log(this.$refs.fos) // undefined this.$nextTick(function() { // 獲取更新以後的DOM this.$refs.fos.focus() }); } } new Vue({ el: '#app', data() { return { } }, template: `<App />`, components: { App } }); </script> </body> <!--ref <body> <div id="app"> <div class="box" ref="my_box"> 這是一個盒子 </div> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script type="text/javascript"> var app = new Vue({ el: "#app", mounted(){ this.$refs.my_box.style.color = "blue"; } }) </script> </body> -->

<body> <p> 在vue中方法和計算屬性達到的效果是同樣的 可是計算屬性是基於依賴進行緩存的,只有依賴的數據發生改變的時候, 纔會從新執行計算屬性的函數,每次調用都會從緩存中拿以前算好的數據。 而方法是每調用一次,執行一次。</p> <div id="app"> <table border="1"> <thead> <th>學科</th> <th>分數</th> </thead> <tbody> <tr> <td>數學</td> <td><input type="text" v-model.number="math"></td> </tr> <tr> <td>物理</td> <td><input type="text" v-model.number="physics"></td> </tr> <tr> <td>英語</td> <td><input type="text" v-model.number="english"></td> </tr> <tr> <td>總分</td> <!--<td>{{math+physics+english}}</td>--> <td>{{sum}}</td> </tr> <tr> <td>平均分</td> <!--<td>{{Math.round((math+physics+english)/3)}}</td>--> <td>{{average}}</td> </tr> </tbody> </table> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script type="text/javascript"> var app = new Vue({ el: '#app', data: { math: 90, physics:88, english: 78, }, computed: { sum: function () { var total = this.math + this.physics + this.english return total }, average: function () { var average_num = Math.round(this.sum/3) return average_num } } }); </script> </body>

<body> <div id="app"> <h4>{{alexDesc}}</h4> <!--alex它的年齡是18歲 點擊修改後 ALEX is SB!!!它的年齡是18歲--> <button @click='clickHandler'>修改</button> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script type="text/javascript"> new Vue({ el:'#app', template:``, data(){ return { myName:'alex', age:18 } }, methods:{ clickHandler(){ console.log(this.alexDesc); this.alexDesc = 'ALEX is SB!!!'; } }, computed:{ alexDesc:{ set:function(newValue) { console.log(newValue); this.myName = newValue; }, get:function() { var str = `${this.myName}它的年齡是${this.age}歲`; // 默認只有getter return str; } } } }); </script> </body>

<body> <div id="app"> <input type="text" v-model='myName'> <h3>{{ myName}}</h3> <button @click='clickHandler'>修改</button> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script type="text/javascript"> new Vue({ el:'#app', template:``, data(){ return { myName:'', firstName:'wusir' } }, methods:{ clickHandler(){ this.myName = 'alex'; } }, watch:{ // 檢測單個屬性 命令式 myName:function(value) { console.log(value); if (value === 'alex') { console.log(value +' '+this.firstName+'是sb') } } } }); </script> </body>

<body> <p>過濾器是在數據到達用戶的最後一步進行簡單的過濾處理,複雜的仍是要用計算屬性或者方法。</p> <div id="app"> <input type="text" v-model = 'price'> <h3>{{ price | currentPrice}}</h3> <h3>{{ price | rmb}}</h3> <h4>{{msg | reverse}}</h4> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script type="text/javascript"> // 註冊全局的過濾器 Vue.filter('reverse',function(value) { return value.split('').reverse().join(''); }); Vue.filter('rmb', function (value) { return value + "元" }); new Vue({ el: '#app', data() { return{ price:0, msg:"hello luffy" } }, // 局部過濾器 在當前組件中聲明過濾器 filters:{ currentPrice:function (value) { // 參數1就是純滌的元數據 console.log(value); return '$' + value; } } }); </script> </body>

<body> <div id="slider"> <img :src='currentImgSrc' alt=""> <ul> <li v-for = '(item,index) in imgArr' :class="{active:currentIndex==index}" @click='clickHandler(index)'> {{ index +1 }} </li> </ul> </div> <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script type="text/javascript"> // 數據驅動視圖 var imgArr = [ {id:1,imgSrc:'./images/1.png'}, {id:2,imgSrc:'./images/2.png'}, {id:3,imgSrc:'./images/3.png'}, {id:4,imgSrc:'./images/4.png'} ]; new Vue({ el:'#slider', template:``, data(){ return{ imgArr:imgArr, currentIndex:0, currentImgSrc:'./images/1.png' } }, methods:{ clickHandler(index){ this.currentIndex = index; this.currentImgSrc = this.imgArr[index].imgSrc; } } }); </script> </body>
3、Vue組件
組件 (Component) 是 Vue.js 最強大的功能之一。組件能夠擴展 HTML 元素,封裝可重用的代碼。是可複用的Vue實例。

<body> <div id="app"> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script type="text/javascript"> // 打油詩: 先聲子 掛子 用子 // 1.先聲明組件 // 局部組件 var Vheader = { template:` <header class='head'> <span>{{title}}</span> <span>{{count}}</span> <button @click = 'count+=1'>點擊</button> </header> `, data(){ return { count: 0 } }, //父組件向子組件傳遞數據:經過Prop props:['自定義的屬性1','自定義屬性2'] //當一個值傳遞給一個 prop 特性的時候,它就變成了那個組件實例的一個屬性,那麼咱們就能夠像訪問data中的值同樣 //在父組件中的子組件標籤中,綁定自定義的屬性 <Vheader :title = '父組件中data聲明的數據屬性'/> //一個組件默承認以擁有任意數量的 prop,任何值均可以傳遞給任何 prop。 props:['title'], methods:{ } }; var Vaside = { template:` <div class='aside'> 我是側邊欄 </div> ` }; var Vcontent = { template:` <div class='content'> <ul> <li v-for = 'post in posts' :key = 'post.id'> <h3>個人博客標題:{{post.title}}</h3> <p>個人博客內容:{{post.content}}</p> </li> </ul> <button @click='changeSize'>改變字體大小</button> </div> `, props:['posts'], methods:{ changeSize(){ // 如何從子組件傳遞數據到父組件 // 給子組件中的某個按鈕綁定原聲事件,能夠調用內建的 this.$emit('自定義的事件名','傳遞的數據'),來向父級組件觸發一個自定義的事件. // 在父組件中的子組件標籤中,綁定自定義的事件 // this指的vue實例化對象的子類 this.$emit('postChangeSize',3) } } }; // 局部組件 我是入口組件 var Vmain = { data(){ return{ fontsize:18 } }, // 3.使用子組件 template:` <div class='main' :style = '{fontSize:fontsize+"px"}'> <Vheader v-bind:title = 'title'></Vheader> //#######在父組件中的子組件標籤中,綁定自定義的屬性 <div class='wrap'> <Vaside /> <Vcontent v-bind:posts = "appPosts" @postChangeSize = 'clickHandler'/> //#######在父組件中的子組件標籤中,綁定自定義的事件 </div> </div> `, methods:{ clickHandler(value){ this.fontsize = this.fontsize+value; } }, components:{ // 2.掛載子組件 Vheader等價於Vheader:Vheader Vheader, Vaside, Vcontent }, props:['title','appPosts'] } new Vue({ el:"#app", // 3.使用子組件 template:`<Vmain :title = "text" :appPosts = "posts"/>`, //入口組件 data:{ text:"alex", posts:[ {id:1,title:"組件中的傳值",content:"經過Prop傳遞數據"}, {id:2,title:"組件中的傳值2",content:"經過Prop傳遞數據2"}, {id:3,title:"組件中的傳值3",content:"經過Prop傳遞數據3"}, ] }, components:{ // 2.掛載子組件 key表示組件名 value:組件對象 Vmain:Vmain } }); </script> </body>

<body> <div id="app"> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script type="text/javascript"> // 建立全局組件 第一個參數是公共組件的名字,第二個參數options /* Vue.component('全局組件的名字',{ 跟new Vue() 實例化對象中的options是同樣,可是要注意: 無論是公共組件仍是局部組件 data必須是個函數 函數必定要返回 {} }) */ Vue.component('Vbtn', { template: `<button class='defalut' :class='type'> <slot></slot> //元素做爲承載分發內容的出口 </button>`, props: ['type'] }); var Vheader = { data() { return { } }, template: `<div id='head'> <Vbtn>登陸</Vbtn> <Vbtn>註冊</Vbtn> <Vbtn>提交</Vbtn> <Vbtn>默認的按鈕</Vbtn> <Vbtn type='primary'>主要的按鈕</Vbtn> <Vbtn type='success' >成功的按鈕</Vbtn> </div>` }; var App = { template: `<div> <Vheader></Vheader> </div>`, components: { Vheader } } new Vue({ el: '#app', data() { }, template: `<App />`, components: { App } }); </script> </body>

<body> <div id="app"> <PopUp></PopUp> <ToolTip></ToolTip> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script type="text/javascript"> //混合Mixins 重複功能和數據的儲存器,能夠覆蓋Mixins的內容。 var base = { data: function () { return { visible: false, } }, methods: { show: function () { this.visible = true }, hide: function () { this.visible = false } } } Vue.component('popup', { template:` <div> <button @click="show">PopUp show</button> <button @click="hide">PopUp hide</button> <div v-if="visible"><p>hello everybody</p></div> </div> `, mixins: [base], data: function () { return { visible: true, } } }); Vue.component('tooltip', { template: ` <div> <div @mouseenter="show" @mouseleave="hide">ToolTip</div> <div v-if="visible"><p>ToolTip</p></div> </div> `, mixins: [base] }); new Vue({ el: "#app", }) </script> </body>
4、Vue生命週期(鉤子函數)
-
create 和 mounted 相關
beforecreated :el 和 data 並未初始化
created:完成了data數據的初始化 el 沒有
beforeMount:完成了el 和 data的初始化
mounted:完成了掛載
也就是說掛載前的狀態是虛擬DOM技術,先把坑站住了,掛載以後才真正的把值渲染進去.

<body> <div id="app"> <App></App> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script type="text/javascript"> var Test = { data(){ return{ message:"哈哈哈" } }, template:` <div> <div>{{message}}</div> <button @click = 'changeHandler'>修改</button> </div> `, methods:{ changeHandler(){ this.message = this.message + 'alex' } }, /* beforeCreate: function () { console.group("beforeCreate 建立實例以前==========="); console.log("el: " + this.$el); // undefined console.log("data: " + this.$data); // undefined console.log("message: " + this.message); // undefined }, */ beforeCreate(){ // 組件建立以前 console.group("beforeCreate 建立實例以前==========="); console.log("el: " + this.$el); // undefined console.log("data: " + this.$data); // undefined console.log("message: " + this.message); // undefined }, created(){ // 組件建立以後 // 使用該組件,就會觸發以上的鉤子函數,created中能夠操做數據,發送ajax,而且能夠實現vue==》頁面的影響 應用:發送ajax請求 console.group("Created: 建立實例完成==========="); console.log("el: " + this.$el); // undefined console.log("data: " + this.$data); // 已被初始化 console.log("message: " + this.message); // 已被初始化 this.message = '嘿嘿黑'; }, beforeMount(){ // 裝載數據到DOM以前會調用 console.group("beforeMount 掛載前狀態=========="); console.log("el: " + this.$el); // undefined console.log("data: " + this.$data); // 已被初始化 console.log("message: " + this.message); // 已被初始化 console.log(document.getElementById('app')); }, mounted(){ // 這個地方能夠操做DOM // 裝載數據到DOM以後會調用 能夠獲取到真實存在的DOM元素,vue操做之後的DOM console.group("Mounted 掛載結束狀態============="); console.log("el: " + this.$el); // 已被初始化 console.log("data: " + this.$data); // 已被初始化 console.log("message: " + this.message); // 已被初始化 console.log(document.getElementById('app')); }, beforeUpdate(){ // 在更新以前,調用此鉤子,應用:獲取原始的DOM console.group("beforeUpdate 更新前狀態========="); console.log("el: " + this.$el); console.log("data: " + this.$data); console.log("message: " + this.message); console.log(document.getElementById('app').innerHTML); }, updated(){ // 在更新以前,調用此鉤子,應用:獲取最新的DOM console.group("Updated 更新完成狀態"); console.log("el: " + this.$el); console.log("data: " + this.$data); console.log("message: " + this.message); console.log(document.getElementById('app').innerHTML); }, beforeDestroy(){ console.group("beforeDestroy 實例銷燬以前"); console.log("el: " + this.$el); console.log("data: " + this.$data); console.log("message: " + this.message); console.log('beforeDestroy'); }, destroyed(){ console.group("Destoryed 實例銷燬以後"); console.log("el: " + this.$el); console.log("data: " + this.$data); console.log("message: " + this.message); console.log('destroyed'); }, activated(){ console.log('組件被激活了'); }, deactivated(){ console.log('組件被停用了'); } } var App = { data(){ return { isShow : true } }, template:` <div> <keep-alive> <Test v-if = 'isShow'></Test> </keep-alive> <button @click = 'changeHandler'>改變組件的生死</button> </div> `, methods:{ changeHandler(){ this.isShow = !this.isShow; } }, components:{ Test } }; new Vue({ el:'#app', template:``, components:{ App } }); </script> </body>
5、Vue-Router
- vue-router是Vue的路由系統,定位資源的,咱們能夠不進行整頁刷新去切換頁面內容。
- $route爲當前router調轉對象,裏面能夠獲取name, path, query, params等
- $router爲VueRouter實例,有$router.push方法等
- 路由的生命週期就是從一個路由跳轉到另外一路由整個過程,兩個鉤子router.beforeEach() router.afterEach()

<body> <!-- SPA : Single Page Application 前端路由 1.錨點值 監視 2.ajax獲取動態的數據 3.核心點是錨點值的改變 前端中 vue|react|angular 都很適合作單頁面應用 --> <a href="#/login">登陸頁面</a> <a href="#/register">註冊頁面</a> <div id="app"> </div> <script type="text/javascript"> // onhashchange 事件 url上的錨點數據(#/xxx改變) var oDiv = document.getElementById('app'); window.onhashchange = function(){ console.log(location.hash); // 根據不一樣的錨點值,對頁面不一樣的切換。 switch (location.hash) { case '#/login': oDiv.innerHTML = '<h2>登陸頁面</h2>' break; case '#/register': oDiv.innerHTML = '<h2>註冊頁面</h2>' break; default: // statements_def break; } } </script> </body>

<body> <div id="app"></div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <!-- 1.引入vue.js--> <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script> <!-- 2.引入 vue-router的對象 --> <!-- 全局的VueRouter對象 vue-router 還給我們提供了兩個全局的組件 router-link router-view--> <script type="text/javascript"> // 3.讓Vue使用該VueRouter建立 Vue.use(VueRouter); var Login = {template:`<div>登陸頁面</div>`}; var Register = {template:`<div>註冊頁面</div>`}; var nameLogin = {template:`<div>命名登陸頁面</div>`}; var nameRegister = {template:`<div>命名註冊頁面</div>`}; var UserParams = {template:`<div>我是用戶{{$route.params.userId}}</div>`, created(){ console.log(this.$route.params.userId); // 1 獲取參數 // 發送ajax請求 console.log(this.$router); // VueRouter } }; var UserQuery = {template:`<div>我是用戶{{$route.query.userId}}</div>`, created(){ console.log(this.$route); // Object console.log(this.$route.query.userId); // 2 獲取參數 // 發送ajax請求 console.log(this.$router); // VueRouter } }; // 4.建立一個路由對象 var router = new VueRouter({ // 配置路由對象 routes:[ { path:'/login', component:Login }, { path:'/register', component:Register }, // 命名路由 { path:'/nlogin', name:'nlogin', component:nameLogin }, { path:'/nregister', name:'nregister', component:nameRegister }, // 路由參數 { // 動態的路由參數 以冒號開頭 path:'/user/:userId', name:'userp', component:UserParams }, { path:'/user', name:'userq', component:UserQuery } ], //mode: 'history', //路由去掉# }); var App = { template:` <div> <!--router-link默認會被渲染成a標籤 to屬性默認會被渲染成href屬性--> <router-link to="/login">登陸頁面</router-link> <router-link to="/register">註冊頁面</router-link> <!--命名路由 注意router-link裏to必定要v-bind--> <router-link :to="{name:'nlogin'}">命名登陸頁面</router-link> <router-link :to="{name:'nregister'}">命名註冊頁面</router-link> <!--路由參數 路由範式 (1)xxxx.html#/user/1 params (2)xxxx.html#/user?userId = 2 query --> <router-link :to="{name:'userp',params:{userId:1}}">用戶1</router-link> <router-link :to="{name:'userq',query:{userId:2}}">用戶2</router-link> <router-link to="/user?userId=99">用戶99</router-link> <router-link to="/user/88">用戶88</router-link> <!--編程式導航--> <button @click = 'paramsHandler'>用戶123</button> <button @click = 'queryHandler'>用戶321</button> <!--路由組件的出口--> <router-view></router-view> </div> `, methods:{ paramsHandler(){ // 編程式導航 this.$router.push({ name: 'userp', params: { userId: 123 }}) }, queryHandler(){ this.$router.push({ name: 'userq', query: { userId: 321 }}) } } }; new Vue({ el:'#app', components:{ App }, router, // 5.##掛載 template:`<App />` }); </script> </body>

<body> <div id="app"></div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script> <script type="text/javascript"> // 嵌套路由: // 需求:進入首頁以後 點擊 音樂 /home/music 電影 /home/movie Vue.use(VueRouter); var Home = { template: ` <div> <router-link to = '/home/music'>音樂</router-link> <router-link to = '/home/movie'>電影</router-link> <!--子路由組件的出口--> <router-view></router-view> </div> ` }; var Index = { template: ` <div> <router-link :to = "{name:'comDesc',params:{id:'android'}}">Android</router-link> <router-link :to = "{name:'comDesc',params:{id:'frontend'}}">前端</router-link> <router-view></router-view> </div> `, created() { console.log('首頁組件建立了'); }, mounted() { console.log('首頁組件DOM加載了') }, destroyed() { console.log('首頁銷燬了'); } }; var Pins = { template: `<div @click = 'clickHandler'>我是沸點</div>`, methods: { clickHandler(e) { e.target.style.color = 'red'; } }, created() { console.log('沸點組件建立了'); }, mounted() { console.log('沸點組件DOM加載了') }, destroyed() { console.log('沸點銷燬了'); } }; var Music = {template: `<div>我是音樂</div>`}; var Movie = {template: `<div>我是電影</div>`}; // 共同的子組件 var ComDesc = { data(){return {msg: ''}}, template: `<div>我是{{msg}}</div>`, created() { this.msg = 'andorid'; }, watch: { // 當使用路由參數時,例如從 /user/foo 導航到 /user/bar,原來的組件實例會被複用。由於兩個路由都渲染同個組件,比起銷燬再建立,複用則顯得更加高效。不過,這也意味着組件的生命週期鉤子不會再被調用。 '$route' (to, from) { // 對路由變化做出響應... console.log(to); console.log(from); this.msg = to.params.id; } } } var router = new VueRouter({ routes: [{ path: '/', //redirect:{name:'home'} //redirect: '/home' }, { path: '/home', //name:'home', component: Home, children: [ // 當訪問/home時,Home組件的出口是不會渲染任何內容,這是由於沒有匹配到合適的子路由 { path: '', //component: Music }, { path: 'music', component: Music, }, { path: 'movie', component: Movie } ] }, { path: '/index', component: Index, children: [{ path: "", component: ComDesc }, { // 動態的路由參數 以冒號開頭 path: '/index/:id', name: 'comDesc', component: ComDesc } ] }, { path: '/pins', name: 'pins', component: Pins, } ], //mode: 'history', //路由去掉# }); var App = { template: ` <div> <router-link to = "/home">home</router-link> <router-link to = "/index">index</router-link> <router-link to = "/pins">沸點</router-link> <!--路由組件的出口--> <keep-alive> <router-view></router-view> </keep-alive> </div> ` }; new Vue({ el: '#app', components: { App }, router, template: `<App />` }); </script> </body>

<body> <div id="app"> <div> <router-link to="/">首頁</router-link> <router-link :to="{name: 'about'}">關於咱們</router-link> <router-link to="/user/alex?age=19">alex</router-link> </div> <div> <router-view></router-view> <!--命名路由視圖,顯示不一樣區域,就須要對視圖進行命名--> <router-view name="content" class="content-view"></router-view> <router-view name="footer" class="footer-view"></router-view> </div> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script> <script type="text/javascript"> Vue.use(VueRouter); let routes = [ { path: '/', /* component: { template: `<h1>這是主頁</h1>` }*/ //命名路由視圖 components: { content: { template: `<div><h1>首頁1111</h1></div>`, }, footer: { template: `<div><h1>首頁2222</h1></div>`, } } }, { path: "/about", name: "about", component: { template: `<h1>關於咱們</h1>` } }, { path: "/user/:name", component: { template: `<div> <h1>我是:{{$route.params.name}}</h1> <h1>我年齡是:{{$route.query.age}}</h1> <router-link to="more" append>更多信息</router-link> <router-view></router-view> </div>`, }, children: [ { path: "more", component: { template: `<div> {{$route.params.name}}的詳細信息 </div>`, } } ] }, //錯誤路由的重定向 { path: "**", redirect: "/about" }, ]; let router = new VueRouter({ routes: routes, //mode: "history" }); const app = new Vue({ el: "#app", router: router, mounted(){ console.log(this.$route) console.log(this.$router) } }) </script> </body>

<body> <div id="app"></div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script> <script type="text/javascript"> Vue.use(VueRouter); // 1.點擊題庫時,檢測用戶是否登陸過,若是沒有,則跳轉登陸頁面。 // 2.當用戶點擊退出,該用戶直接刪除 var Home = {template: `<div>我是首頁</div>`}; var Questionbank = {template: `<div>我是題庫</div>`}; // 登陸組件 var Login = { data(){ return { name:'', pwd:'' } }, template:` <div> <input type="text" v-model = 'name' /> <input type="text" v-model = 'pwd' /> <input type="button" value = '登陸' @click = 'loginHandler'/> </div> `, methods:{ loginHandler(){ //用戶名和密碼保存到 localStorage 而後跳轉相應的路由(智能題庫) localStorage.setItem('user', {name:this.name,pwd:this.pwd}); // 編程式導航 this.$router.push({name:'questionbank'}); } } }; var router = new VueRouter({ routes: [{ path: '/home', component: Home }, { path: '/questionbank', name: 'questionbank', component: Questionbank, // 給將來的路由 作權限控制 meta:{ // 表名訪問該組件時須要登陸 required_login: true } }, { path:'/login', component:Login } ] }); // 全局的導航守衛 鉤子1 router.beforeEach(function(to,from,next){ console.log(to.meta.required_login); console.log(from); // 若是不調用next 那麼頁面會卡主 if(to.meta.required_login){ // 用戶點擊了智能題庫的導航,須要對用戶作登陸判斷 if (localStorage.getItem('user')) { // 不爲空 放行 next() }else{ // 爲空 進入登陸頁面 next({path:'/login'}); } }else{ // 直接放行 next(); } }); /* next:function 必定要調用這個方法來resolve這個鉤子函數。 執行效果依賴next方法的調用參數 next() 什麼都不作繼續執行到調轉的路由 next(false) 中斷當前導航 沒有跳轉 也沒有反應 next("/") 參數是路徑 調轉到該路徑 next(error) 若是next參數是一個Error實例 導航終止該錯誤 會傳遞給router.onError()註冊過的回調中 鉤子2 router.afterEach(function (to, from) { console.log(to) console.log(from) }); */ var App = { template: ` <div> <router-link to = "/home">首頁</router-link> <router-link to = "/questionbank">智能題庫</router-link> <router-link to = '/login'>登陸</router-link> <a href="javascript:void(0)" @click = 'clear'>退出</a> <!--路由組件的出口--> <keep-alive> <router-view></router-view> </keep-alive> </div> `, methods:{ clear(){ // 退出 localStorage.removeItem('user'); this.$router.push('/login'); } } }; new Vue({ el: '#app', components: { App }, router, template: `<App />` }); </script> </body>
6、axios
-
官方文檔:點擊
-
基於Promise的HTTP請求客戶端,能夠同時在瀏覽器和node.js使用。
- 從瀏覽器中建立 XMLHttpRequests
- 從 node.js 建立 http 請求
- 支持 Promise API
- 攔截請求和響應
- 轉換請求數據和響應數據
- 取消請求
- 自動轉換 JSON 數據
- 客戶端支持防護 XSRF
-
使用npm安裝axios:
-- npm install axios -D
-
基本的配置:
Vue.prototype.$axios = axios; 掛載,就能夠在任意組件中經過this.$axios獲取到當前的axios實例
axios.defaults.baseURL = 'http://127.0.0.1:8800' 默認配置URL

<body> <div id="app"></div> <script type="text/javascript" src="./node_modules/vue/dist/vue.js"></script> <script type="text/javascript" src="./node_modules/axios/dist/axios.js"></script> <!-- vue和axios都是全局的對象 將來 axios會成爲局部做用域--> <script type="text/javascript"> // 1.掛載 Vue.prototype.$axios = axios; // 2.配置公共的url axios.defaults.baseURL = 'http://127.0.0.1:8800'; var App = { data(){ return { msg:'', datas:[] } }, template:` <div> <button @click = 'sendAjax'>發Get請求</button> <div v-html = 'msg'></div> <button @click = 'sendAjaxByPost'>發post請求</button> {{datas}} </div> `, methods:{ sendAjax(){ // 發送get請求 /* 帶參數 this.$axios.get('/',{ params: { id: 123, } }) this.$axios.post(/create,{ course_title: "Python", course_price: "19.88" }) */ this.$axios.get('/') .then(res=>{ console.log(res.data); console.log(typeof res.data); this.msg = res.data; }) .catch(err=>{ console.log(err); }) }, sendAjaxByPost(){ // var _this = this; var params = new URLSearchParams(); params.append('name','alex'); this.$axios.post('/create',params).then((res)=>{ // 解決this的指向問題,在vue中用函數 建議使用箭頭函數 console.log(this); console.log(res); // 初學者容易犯的錯 // _this.datas = res; this.datas = res; }).catch(err=>{ console.log(err); }) } } } new Vue({ el:"#app", data(){ return { } }, components:{ App }, template:`<App />` }) </script> </body>

<script type="text/javascript"> // 1.掛載 Vue.prototype.$axios = axios; // 2.配置公共的url axios.defaults.baseURL = 'http://127.0.0.1:8800'; //發送多個併發請求 function getCourse(){ return this.$axios.get('/course/12') } function getCourse_all() { return this.$axios.get('/course') } this.$axios.all([getCourse_all(),getCourse()]) .then().catch() methods: { init(){ var that = this this.$axios.request({ url: that.$store.state.apiList.course, method: 'get' }).then(function (data) { if (data.status === 200){ that.courseList = data.data } }).catch(function (reason) { console.log(reason) }) } }, </script>
7、Vuex
官方文檔:點擊
-
vuex是一個專門爲Vue.js設計的集中式狀態管理架構。狀態? 理解爲在data中須要共享給其餘組件使用的部分。
-
Vuex和單純的全局對象有如下不一樣:
- Vuex 的狀態存儲是響應式的。當vue組件從store中讀取狀態的時候,若store中的狀態發生變化,那麼相應的組件也會相應的獲得高效更新。
- 不能直接改變store中的狀態。改變store中的狀態的惟一途徑就是顯示的提交(commit)mutation。
-
安裝:
-- npm install vuex

// 爲了方便維護,咱們一般把在src下面新建一個store文件夾,而後在裏面新建一個index.js // index.js import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex); const store = new Vuex.Store({ // 五大將 state getter mutation action module /* 一、state是保存咱們data中須要共享的數據。 因爲Vuex的存儲是響應式的,從store實例中讀取狀態的最簡單的方式就是在計算屬性中返回某個狀態。 經過:this.$store.state.count 二、Getter會接收state做爲其第一個參數,Getter也能夠接收getters爲第二個參數, 有時候咱們須要從store中的state中派生出一些狀態,例如對數據進行簡單的計算。 而且不少組件都須要用到此方法,咱們要麼複製這個函數,要麼抽取到一個公共函數,多處導入。 咱們vuex提供了更加方便的方法,getter ,它就像計算屬性同樣,getter的返回值會根據它的依賴被 緩存起來,只有它的依賴發生改變時,纔會從新計算。 三、更改Vuex中的store中的狀態的惟一方法是提交(commit) mutation。 每一個mutation都有一個字符串的事件類型(type),和一個回調函數handler。 也就是說咱們要觸發mutation中定義的方法(type),而後纔會執行這個方法(handler)。 這個方法就是咱們更改狀態的地方,它會接收state爲第一個參數,後面接收其餘參數: Mutation須要遵照Vue的響應規則, 既然vuex中的store中的狀態是響應式的,那麼當咱們狀態變動時,監視狀態的vue組件也會更新。 這就意味着vuex中的mutation也須要與使用vue同樣遵照一些注意事項: -- 1,最好提早在你的store中初始化好全部的所須要的屬性 -- 2,當對象須要添加屬性時,你應該使用 -- Vue.set(obj, 'newProp', 123) -- 以新對象代替老對象 state.obj = { ...state.obj, newProp: 123} 四、Action 相似於 mutation,不一樣在於: Action 提交 mutation,而不是直接變動狀態。 Action 能夠包含任意異步操做。 使用dispatch 和 commit的區別在於,前者是異步操做,後者是同步操做,因此 通常狀況下,推薦直接使用commit, 即 this.$store.commit(commitType, payload),以防異步操做會帶來的延遲問題。 Mutation 必須是同步函數,在vue中,只有mutation才能正真改變VUEX stroe中的state。 Action 提交的是 mutation,而不是直接變動狀態。 Action 能夠包含任意異步操做。 我的以爲這個action的產生就是由於mutation 不能進行異步操做,若是有異步操做那麼就用action 來提交mutation */ state:{ // 經過:this.$store.state.count count:1 }, getters: { // 經過:this.$store.getters.my_func my_func: function (state) { return state.count * 2 }, // 經過 this.$store.getters.my_func_count my_func_count: function (state, getters) { return getters.my_func.length } }, mutations:{ // 同步 // 須要經過 this.$store.commit('addCount', 10) addCount(state,val){ //變動狀態 state.count+=val; }, asyncHandler(state,val){ state.count+=val; } }, actions:{ // 異步 // 經過: this.$store.dispatch('addCount',3) addCount({commit},val){ setTimeout(()=>{ commit('addCount',val) },2000) }, asyncHandler({commit},val){ commit('asyncHandler',val) } } }); export default store; //src下面的main.js import Vue from 'vue' import App from './App' import store from './store' //就是導入上面的index.js Vue.config.productionTip = false new Vue({ el: '#app', store, //掛載 components: { App }, template: '<App/>' })
8、webpack
官方文檔:點擊
webpack: 對前端中的資源編譯打包、支持模塊化es6的module
webpack它裏面不少loader
webpack 是一個現代 JavaScript 應用程序的靜態模塊打包器(module bundler)。
當webpack處理應用程序時,它會遞歸地構建一個依賴關係圖(dependency graph),
其中包含應用程序須要的每一個模塊,而後將全部這些模塊打包成一個或多個bundle。
webpack (打包工具)把在後端開發的前端代碼(JS/CSS/TypeScript...)打包成前端瀏覽器能夠執行的JS代碼,
爲何要用webpack,由於按照後端模式開發寫的JS,瀏覽器不認識。 用webpack打包代碼成瀏覽器能認識的代碼
爲何要按照後端開發的方式寫JS,由於前端不支持模塊化,加載代碼是同步的(CDN掛了,後面的代碼都運行不了了,node.js支持模塊化的開發。)
一、webpack3
-
webpack是跑在Node.js環境下的,因此肯定有node環境。
-
安裝方式:
-
npm install webpack@3.12.0 -g
全局安裝 -
cd 目錄
-
npm install webpack
在項目下 npm init 後再下載webpack就是局部安裝 -
npm install webpack-dev-server@2.9.0 -D
-
webpack
<要打包文件> <打包後文件> 全局這種方式進行打包 -
若是在項目中配置了webpack.config.js 那麼在終端中直接輸入webpack,默認識別webpack.config.js項目配置文件
-
自定義命令在package.json 文件的 scripts下面自定義 npm run dev ,npm run build
-

{ "name": "02-module_deep", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "dev": "webpack-dev-server --open --hot --inline --config ./webpack.dev.config.js", "build": "webpack --config ./webpack.prod.config.js" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "css-loader": "^1.0.0", "html-webpack-plugin": "^3.2.0", "style-loader": "^0.23.1", "vue-loader": "^14.1.1", "vue-template-compiler": "^2.5.17", "webpack": "^3.12.0", "webpack-dev-server": "^2.9.0" }, "dependencies": { "vue": "^2.5.17" } }

//自帶nodejs環境 cmd規範 // module.exports = {} // var a = require('./webpack.config.js') // 若是在項目中配置了webpack.config.js 那麼在終端中直接輸入webpack,默認識別webpack.config.js項目配置文件 module.exports = { // 入口 entry:{ "main":'./main.js' }, // 出口 output:{ filename:'./bundle.js' }, watch:true }

//自帶nodejs環境 cmd規範 // module.exports = {} // var a = require('./webpack.config.js') // nodejs中內容模塊 var path = require('path'); var HtmlWebpackPlugin = require('html-webpack-plugin'); // html-webpack-plugin // 若是在項目中配置了webpack.config.js 那麼在終端中直接輸入webpack,默認識別webpack.config.js項目配置文件 module.exports = { // 入口 entry:{ "main":'./src/main.js' }, // 出口 output:{ path:path.resolve('./dist'),//相對轉絕對 filename:'./bundle.js' }, // 模塊中的loader loader加載器 它能對css、json png jpg mp3 mp4 es6的js代碼 module:{ loaders:[ { test:/\.css$/, loader:'style-loader!css-loader' }, { test:/\.vue$/, loader:'vue-loader' } ] }, watch:true, // 插件 plugins:[ new HtmlWebpackPlugin({ template:'./index.html',//參照物 }) ] }

//自帶nodejs環境 cmd規範 // module.exports = {} // var a = require('./webpack.config.js') // nodejs中內容模塊 var path = require('path'); var HtmlWebpackPlugin = require('html-webpack-plugin'); // html-webpack-plugin // 若是在項目中配置了webpack.config.js 那麼在終端中直接輸入webpack,默認識別webpack.config.js項目配置文件 module.exports = { // 入口 entry:{ "main":'./src/main.js' }, // 出口 output:{ path:path.resolve('./dist'),//相對轉絕對 filename:'./bundle.js' }, // 模塊中的loader loader加載器 它能對css、json png jpg mp3 mp4 es6的js代碼 module:{ loaders:[ { test:/\.css$/, loader:'style-loader!css-loader' } ] }, // 插件 plugins:[ new HtmlWebpackPlugin({ template:'./index.html',//參照物 }) ] }
二、webpack4
-
webpack不在單獨使用,須要webpack-cli
-
安裝方式:
-
npm install webpack webpack-cli -g -D
全局安裝 -
npm install webpack webpack-cli -D
局部安裝
-
-
增長了模式區分 (development, production):
-
webpack --mode development/production
進行模式切換 -
development
開發者模式 打包默認不壓縮代碼 -
production
生產者模式 上線時使用,壓縮代碼。 默認是這個模式
-
-
固定入口目錄爲src,與入口默認文件index.js,打包後文件在新增的dist目錄下:
-
當只有一個入口文件也就是src/index.js時,無需增長webpack.config.js
-