置身世外只爲暗中觀察!!!Hello你們好,我是魔王哪吒!重學鞏固你的Vuejs知識體系,若是有哪些知識點遺漏,還望在評論中說明,讓我能夠及時更新本篇內容知識體系。歡迎點贊收藏!javascript
談談你對MVC、MVP和MVVM的理解?css
什麼是組件化,Vue組件化開發思想前端
axios的使用vue
vuejs原理相關:響應式原理,源碼。html5
對於基礎知識須要掌握,簡單寫寫✍java
直接CDN引入:node
代碼:<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
react
代碼:<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
linux
代碼:
# 最新穩定版
$ npm install vue
複製代碼
聲明式編程:
代碼:
<!DOCTYPE html>
<!-- 魔王哪吒 -->
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="vue.js" type="text/javascript" charset="UTF-8"></script>
<!-- <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> -->
</head>
<body>
<div id="app">
{{ a }}
</div>
<script type="text/javascript">
// 咱們的數據對象
var data = { a: 1 };
// 該對象被加入到一個 Vue 實例中
var vm = new Vue({
el: "#app",
data: data
});
// data.a = "dada"
vm.a = "qianduan";
data.a == vm.a;
</script>
</body>
</html>
複製代碼
methods
,該屬性是用於Vue
對象中定義的方法。@click
,該指令是用於監聽某個元素的點擊事件,而且須要指定當發生點擊時,執行的方法。代碼:
<div id="app">
<h1>當前計數{{counter}}</h1>
<button @click="increment">+</button>
<button @click="decrement">-</button>
</div>
<script src="../js/vue.js"></script>
<script>
let app = new Vue({
el: '#app',
data: {
counter: 0
},
methods: {
increment(){
this.counter++
},
decrement(){
this.counter--
},
}
})
</script>
複製代碼
MVVM的思想
它們之間是如何工做的呢?
el
:類型:string | HTMLElement
DOM
data
:類型:Object | Function
methods
:類型:{[key:string]:Function}
生命週期:☞ 事物從誕生到消亡的整個過程
release
穩定版本debug
版本v-once
指令的使用
<div id="app">
<h1>{{message}}</h1>
<h2 v-once>{{message}}</h2>
</div>
複製代碼
v-once
:
v-html
:
當咱們從服務器請求到的數據自己就是一個HTML代碼時
{{}}
來輸出,會將HTML
格式進行解析,而且顯示對應的內容。v-html
指令string
類型string
的html
解析處理而且進行渲染<h1 v-html="url"></h1>
複製代碼
v-text
的做用和Mustache
比較類似,獨使用於將數據顯示在界面中,通常狀況下,接受一個string
類型。
<div id="app">
<h2 v-text="message"></h2>
<h2>{{message}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
let vm = new Vue({
el: '#app',
data: {
message: '你好'
}
})
</script>
複製代碼
v-pre
用於跳過這個元素和它子元素的編譯過程,用於顯示本來的Mustache
語法。
<div id="app">
<p v-pre>{{message}}</p>
</div>
<script src="../js/vue.js"></script>
<script>
let app = new Vue({
el: '#app',
data: {
message: 'hello'
}
})
</script>
複製代碼
v-cloak
斗篷的意思。
<div id="app">
<h2 v-cloak>hello{{name}}</h2>
</div>
<script>
setTimeout(()=>{
let app = new Vue({
el: '#app',
data: {
name: 'web'
}
})
},10000)
</script>
<style>
[v-cloak] {
display: none;
}
</style>
複製代碼
v-bind
用於綁定一個或多個屬性值,或者向另外一個組件傳遞props
值。
<div id="app">
<a v-bind:href="link">vuejs</a>
<img v-bind:src="url" alt="">
</div>
<script>
let app = new Vue({
el: '#app',
data: {
}
})
複製代碼
v-bind
語法糖
v-bind
有一個對應的語法糖,就是簡寫方式
<div id = "app">
<a :href="link">vuejs</a>
<img :src="longURL" alt="">
</div>
複製代碼
v-bind
動態綁定class
<style>
.active{
color: red;
}
</style>
<div id="app">
<h1 class="active">{{message}}</h2>
</div>
<script>
const app = new Vue({
el: '#app',
data: {
message: 'hello'
}
})
</script>
複製代碼
綁定class
有兩種方式:
對象語法:
用法一:直接經過{}綁定一個類
<h2 :class="{'active': isActive}">hello</h2>
用法二,傳入多個值
<h2 :class="{'active': isActive, 'line': isLine}">hello</h2>
用法三:
<h2 class="title" :class="{'active': isActive}"></h2>
用法四:
能夠放在一個methods或者computed中
<h2 class="title" :class="classes">hello</h2>
複製代碼
v-bind
動態綁定class,數組語法
<div id="app">
<h2 class="title" :class="[active, line]">{{mesg}}</h2>
<h2 class="title" :class="getClasses()">{{mesg}}</h2>
</div>
<script>
const app = new Vue({
el: '#app',
data: {
message: 'hello',
active: 'aaa',
line: 'bbb',
},
methods: {
getClasses: function() {
return [this.active, this.line]
}
}
})
</script>
複製代碼
v-bind
動態綁定style
對象語法和數組語法兩種綁定。
綁定方法:對象語法:
:style="{ color: currentColor, fontSize: fontSize + 'px' }"
複製代碼
style
後面跟的是一個對象類型,對象的key
是css
屬性名稱,對象的value
是具體賦的值,值能夠來自於data
中的屬性。
綁定方法:數組語法:
<div v-bind:style="[baseStyles, overStyles]"></div>
複製代碼
style
後面跟的是一個數組的類型,多個值,分割便可。
計算屬性,寫在實例的computed
選項中:
<div id="app">
<h2>{{firstName}}{{lastName}}</h2>
</div>
<script>
const vm = new Vue({
el: '#app',
data: {
firstName: 'web',
lastName: 'it',
}
})
</script>
複製代碼
<div id="app">
<h2>{{fullName}}</h2>
</div>
<script>
const vm = new Vue({
el: '#app',
data: {
firstName: 'jeskson',
lastName: 'it',
},
computed: {
fullName() {
return this.firstName + ' ' + this.lastName
}
}
})
</script>
複製代碼
計算屬性的緩存:
爲何使用計算屬性這個東西?
緣由:計算屬性會進行緩存,若是屢次使用時,計算屬性只會調用一次。
每一個計算屬性都包含一個getter和一個setter
<div id="app">
<div>{{fullName}}</div>
<div>{{firstName}}</div>
<div>{{lastName}}</div>
</div>
<script>
let vm = new Vue({
el: '#app',
data: {
firstName: 'web',
lastName: 'it',
},
computed: {
fullName: {
get() {
rturn this.firstName+" "+this.lastName
},
set(newValue){
const names = newValue.split(' ')
this.firstName = names[0]
this.lastName = names[1]
}
}
}
})
</script>
複製代碼
computed: {
fullName: function() {
return this.firstName+" "+this.lastName
}
// 計算屬性通常是沒有set方法,只讀屬性。
fullName: {
get: function() {
return this.firstName + " " + this.lastName
}
}
}
複製代碼
const的使用,在JavaScript中使用const修飾的標識符爲常量,不能夠再次賦值。
在es6開發中,優先使用const,只有須要改變一個標識符的時候才使用let。
在使用cost定義標識符,必須進行賦值。
常量的含義是指向的對象不能修改,可是能夠改變對象內部的屬性。
何時使用const呢?
當咱們修飾的標識符不會被再次賦值時,就可使用const來保證數據的安全性。
const的使用:
const a=20;
a = 10; // 錯誤:不能夠修改
const name; // 錯誤,const修飾的標識符必須賦值
複製代碼
let和var
塊級做用域:
JS中使用var來聲明一個變量,變量的做用域主要是和函數的定義有關。
對於其餘塊定義來講是沒有做用域的,好比if/for等,開發中每每會引起一些問題。
// 監聽按鈕的點擊
var btns = document.getElementsByTagName('button');
for(var i=0; i<btns.length; i++) {
(function(i){
btns[i].onclick = function(){
alert('點擊了'+i+"個")
}
})(i)
}
複製代碼
let btns = document.getElementsByTagName('button');
for(let i=0;i<btns.length;i++){
btns[i].onclick = function(){
alert('點擊了'+i+'個')
}
}
複製代碼
變量做用域:變量在什麼範圍內是可用的。
var func;
if(true) {
var name = 'web';
func = function() {
console.log(name); // web
}
func(); // web
}
// name = 'it'
func(); // web -> it
console.log(name); // web -> it
複製代碼
沒有塊級做用域引發的問題,for的塊級
var btns = document.getElementsByTagName('button');
for(var i=0; i<btns.length; i++) {
btns[i].addEventListener('click', function(){
console.log('第'+i+'個按鈕被點擊');
})
}
複製代碼
閉包:
var btns = document.getElementsByTagName('button');
for(var i=0; i<btns.length;i++){
(function(i){
btns[i].addEventListener('click', function(){
console.log('第'+i+'個按鈕');
})
})(i)
}
複製代碼
爲何閉包能夠解決問題,由於函數是一個做用域。
屬性初始化簡寫和方法的簡寫:
// 屬性的簡寫
// es6前
let name = 'web'
let age = 12
let obj1 = {
name: name,
age: age,
}
console.log(obj1);
// es6後
let obj2 = {
name, age
}
console.log(obj2)
複製代碼
// 方法的簡寫
// es6以前
let obj1 = {
test: function() {
console.log('obj1')
}
}
obj1.test();
// es6後
let obj2 = {
test() {
console.log('obj2')
}
}
obj2.test();
複製代碼
v-on:click="counter++"
<div id="app">
<h2>點擊次數:{{counter}}</h2>
<button v-on:click="counter++">按鈕點擊</button>
<button v-on:click="btnClick">按鈕點擊2</button>
</div>
let app = new Vue({
el: '#app',
data: {
counter: 0
},
methods: {
btnClick(){
this.counter++
}
}
})
複製代碼
v-on修飾符的使用
<div id="app">
<div @click="divClick">
web
<button @click.stop="btnClick">按鈕</button>
</div>
複製代碼
Vue提供了一些修飾符:
.stop 調用event.stopPropagation()
.prevent 調用event.preventDefault()
.native 監聽組件根元素的原生事件
.once 只觸發一次回調
複製代碼
// 中止冒泡
<button @click.stop="doThis"></button>
// 阻止默認行爲
<button @click.prevent="doThis"></button>
// 阻止默認行爲,沒有表達式
<form @submit.prevent></form>
// 串聯修飾符
<button @click.stop.prevent = "doThis"></button>
// 鍵修飾符,鍵別名
<input @keyup.enter="onEnter">
// 鍵修飾符,鍵代碼
<input @keyup.13="onEnter">
// 點擊回調智慧觸發一次
<button @click.once="doThis"></button>
複製代碼
簡單使用:
<div id="app">
<p v-if="score>=90">優秀</p>
<p v-else-if="score>=80">良好</p>
<p v-else-if="score>=60">及格</p>
<p v-else="score<60">不及格</p>
</div>
複製代碼
登陸切換:
<div id="app">
<span v-if="type==='username'">
<label>用戶帳號:</label>
<input placeholder="用戶帳戶">
</span>
<span v-else>
<label>郵箱地址:</label>
<input placeholder="郵箱地址">
</span>
<button @click="handleToggle">切換類型</button>
</div>
<script>
let app = new Vue({
el: '#app',
data: {
type: 'username'
},
methods: {
handleToggle(){
this.type = this.type === 'email' ? 'username' : 'email'
}
}
})
</script>
複製代碼
<div id="app">
<span v-if="isUser">
<label for="username">用戶帳戶</label>
<input type="text" id="username" placeholder="用戶帳戶">
</span>
<span v-else>
<label for="email">用戶郵箱</label>
<input type="text" id="email" placeholder="用戶郵箱">
</span>
<button @click="isUser=!isUser">切換類型</button>
</div>
<script>
const app = new Vue({
el: '#app',
data: {
isUser: true
}
})
</script>
複製代碼
<div id="app">
<ul>
<li v-for="(value, key, index) in info">
{{value}}-{{key}}-{{index}}
</li>
</ul>
</div>
<script>
let app = new Vue({
el: '#app',
data: {
info: {
name: 'web',
age: 12,
}
}
})
</script>
複製代碼
使用v-for時,給對應的元素或組件添加上一個:key
屬性。
key的做用主要是爲了高效的更新虛擬dom。
數組中哪些方法是響應式的
push()
pop() 刪除數組中的最後一個元素
shift() 刪除數組中的第一個元素
unshift() 在數組最前面添加元素
splice()
sort()
reverse()
複製代碼
<div id="app">
<table>
<thead>
<tr>
<th></th>
<th>書籍名稱</th>
<th>出版日期</th>
<th>價格</th>
<th>購買數量</th>
<th>操做</th>
</tr>
</thead>
<tbody>
<tr v-for="item in books">
<td v-for="value in item">{{value}}</td>
</tr>
</tbody>
</table>
</div>
複製代碼
vue中使用v-model指令來實現表單元素和數據的雙向綁定。
<div id="app">
<input type="text" v-model="message">
<h2>{{message}}</h2>
</div>
複製代碼
reduce做用對數組中全部的內容進行彙總。
JavaScript reduce() 方法
var numbers = [65, 44, 12, 4];
function getSum(total, num) {
return total + num;
}
function myFunction(item) {
document.getElementById("demo").innerHTML = numbers.reduce(getSum);
}
複製代碼
定義和用法
reduce() 方法接收一個函數做爲累加器,數組中的每一個值(從左到右)開始縮減,最終計算爲一個值。
reduce() 能夠做爲一個高階函數,用於函數的 compose。
注意:
reduce()
對於空數組是不會執行回調函數的。
語法
array.reduce(function(total, currentValue, currentIndex, arr), initialValue)
複製代碼
<input type="text" :value="message" @input="message = $event.target.value">
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好啊'
},
methods: {
valueChange(event){
this.message = event.target.value;
}
}
})
</script>
複製代碼
v-model
是語法糖,本質:
v-bind
綁定一個value
屬性v-on
指令給當前元素綁定input
事件代碼:
<input type="text" v-model="message">
<input type="text" v-bind:value="message" v-on:input="message = $event.target.value">
複製代碼
複選框分爲兩種狀況,單個勾選框和多個勾選框。
單個勾選框:
v-model
即爲布爾值。input
的value
並不影響v-model
的值。
多個複選框:
當是多個複選框時,對應的data
中屬性是一個數組。
當選中某一個時,就會將input
的value
添加到數組中。
<div id="app">
<label for="check">
<input type="checkbox" v-model="checked" id="check">贊成協議
</label>
<label><input type="checkbox" v-model="hobbies" value="籃球">籃球</label>
<label><input type="checkbox" v-model="hobbies" value="檯球">檯球</label>
</div>
複製代碼
select
分單選和多選兩種狀況
單選:只能選中一個值,多選:能夠選擇多個值。
v-model
結合select
類型和checkbox
同樣,select
分單選和多選兩種狀況。
單選,只能選擇一個值,v-model
綁定的是一個值。當咱們選中option
中的一個時,會將它對應的value
賦值到mySelect
中。
多選,能夠選中多個值。v-model
綁定的是一個數組。當選中多個值時,就會將選中的option
對應的value
添加到數組mySelects
中。
// 選擇一個值
<select v-model="mySelect">
<option value="web">web</option>
<option value="it">it</option>
</select>
<p>您最喜歡的{{mySelect}}</p>
// 選擇多個值
<select v-model="mySelects" multiple>
<option value="web">web</option>
<option value="it">it</option>
</select>
<p>您最喜歡的{{mySelects}}</p>
複製代碼
<label v-for="item in origin">
<input type="checkbox" :value="item" v-model="hobbies">
{{item}}
</label>
複製代碼
lazy
修飾符:
v-model
默認是在input
事件中同步輸入框的數據的。data
中的數據就會自動發生改變。lazy
修飾符可讓數據在失去焦點或者回車時纔會更新。number
修飾符:
number
修飾符可讓在輸入框中輸入的內容自動轉成數字類型。trim
修飾符:
trim
修飾符能夠過濾內容左右兩邊的空格示例:
<div id="app">
<input type="text" v-model.lazy="message">
<h2>{{message}}</h2>
</div>
複製代碼
註冊組件的基本步驟:
示例:
調用Vue.extend()方法建立組件構造器
調用Vue.component()方法,註冊組件
在Vue實例的做用範圍內使用組件
複製代碼
組件示例:
<div id="app">
<my-cpn></my-cpn>
</div>
<script src="../js/vue.js"></script>
<script>
// 建立組件構造器
const myComponent = Vue.extend({
template: `
<div>
<h2>組件標題</h2>
<p>組件段落</p>
</div>`
});
// 註冊組件
Vue.component('my-cpn',myComponent);
</script>
複製代碼
Vue.extend()
調用Vue.extend()
建立一個組件構造器。template
表明咱們自定義組件的模板。html
代碼。Vue2.x
的文檔幾乎看不到了。Vue.component()
是將剛纔的組件構造器註冊爲一個組件,而且給它起一個組件的標籤名稱。示例:
組件標題
<div id="app">
<my-cpn><my-cpn>
<div>
<my-cpn><my-cpn>
</div>
</div>
複製代碼
示例:
<div id="app1">
<my-cpn></my-cpn>
</div>
<div id="app2">
<my-cpn></my-cpn>
</div>
<script src="../js/vue.js"></script>
<script>
// 建立組件構造器
const myComponent = Vue.extend({
template: `
<div>
<h2>web</h2>
</div>
`
})
// 註冊組件
Vue.component('my-cpn',myComponent);
let app1 = new Vue({
el: '#app1'
})
let app2 = new Vue({
el: '#app2'
})
複製代碼
<div id="app1">
<my-cpn></my-cpn>
</div>
<div id="app2"> // 沒有被渲染出來
<my-cpn></my-cpn>
</div>
<script src="../js/vue.js"></script>
<script>
// 建立組件構造器
const myComponent = Vue.extend({
template: `
<div>
<h2>web</h2>
</div>
`
})
let app1=new Vue({
el: '#app1',
components: {
'my-cpn': myComponent
}
})
let app2 = new Vue({
el: '#app2'
})
</script>
複製代碼
組件樹
示例:
<div id="app">
<parent-cpn></parent-cpn>
</div>
<script src="../js/vue.js"></script>
<script>
// 建立一個子組件構造器
const childComponent = Vue.extend({
template: `
<div>我是子組件的內容</div>
`
})
// 建立一個父組件的構造器
const parentComponent = Vue.extend({
template: `
<div>
我是父組件的內容
<child-cpn></child-cpn>
</div>
`
components: {
'child-cpn': childComponent
}
})
let app = new Vue({
el: '#app',
components: {
'parent-cpn': parentComponent
}
})
複製代碼
註冊組件的語法糖
示例:全局組件
<div id="app">
<cpn1></cpn1>
</div>
<script>
// 全局組件註冊的語法糖
// 註冊組件
Vue.component('cpn1', {
template: `
<div>
<h2>web</h2>
</div>
`
})
const app = new Vue({
el: '#app',
data: {
message: 'web',
}
})
</script>
複製代碼
<div id="app">
<cpn2></cpn2>
</div>
// 註冊局部組件的語法糖
const app = new Vue({
el: '#app',
data: {
message: 'web'
},
components: {
'cpn2': {
template: `
<div>
<h1>web</h1>
</div>
`
}
}
})
</script>
複製代碼
vue
簡化了註冊組件的方式,提供了註冊的語法糖。
vue
提供了兩種定義html
模塊內容:
<script>
標籤<template>
標籤示例:
<div id="app">
<my-cpn></my-cpn>
</div>
<script type="text/x-template" id="myCpn">
<div>
<h2>web</h2>
</div>
</script>
<script src="../js/vue.js"></script>
<script>
let app = new Vue({
el: '#app',
components: {
'my-cpn': {
template: '#myCpn'
}
}
})
</script>
複製代碼
template
標籤
<template id="cpn">
<div>
<h2>web</h2>
</div>
</template>
// 註冊一個全局組件
Vue.component('cpn', {
template: '#cpn'
})
複製代碼
組件能夠訪問vue實例數據嗎
組件是一個單獨的功能模塊封裝,有屬於本身的html
模板和本身的數據data
。
組件對象有一個data
屬性,methods
屬性,這個data
屬性必須是一個函數,函數返回一個對象,對象內部保存着數據。
<div id="app">
<my-cpn></my-cpn>
</div>
<template id="myCpn">
<div>{{message}}</div>
</template>
<script src="..."></script>
<script>
let app = new Vue({
el: '#app',
components: {
'my-cpn': {
template: 'myCpn',
data() {
return{
message: 'web'
}
}
}
}
})
複製代碼
如何進行父子組件間的通訊呢?
props
向子組件傳遞數據
props
基本用法
在組件中,使用props
來聲明從父級接收到的數據
props
的值:
camelCase
(駝峯命名法) 的 prop
名須要使用其等價的 kebab-case
(短橫線分隔命名) 命名:
Vue.component('blog-post', {
// 在 JavaScript 中是 camelCase 的
props: ['postTitle'],
template: '<h3>{{ postTitle }}</h3>'
})
<!-- 在 HTML 中是 kebab-case 的 -->
<blog-post post-title="hello!"></blog-post>
複製代碼
重申一次,若是你使用字符串模板,那麼這個限制就不存在了。
prop
各自的名稱和類型:
props: {
title: String,
likes: Number,
isPublished: Boolean,
commentIds: Array,
author: Object,
callback: Function,
contactsPromise: Promise // or any other constructor
}
複製代碼
<!-- 動態賦予一個變量的值 -->
<blog-post v-bind:title="post.title"></blog-post>
<!-- 動態賦予一個複雜表達式的值 -->
<blog-post
v-bind:title="post.title + ' by ' + post.author.name"
></blog-post>
<!-- 即使 `42` 是靜態的,咱們仍然須要 `v-bind` 來告訴 Vue -->
<!-- 這是一個 JavaScript 表達式而不是一個字符串。-->
<blog-post v-bind:likes="42"></blog-post>
<!-- 用一個變量進行動態賦值。-->
<blog-post v-bind:likes="post.likes"></blog-post>
複製代碼
傳入一個對象的全部屬性
若是你想要將一個對象的全部屬性都做爲 prop 傳入,你可使用不帶參數的 v-bind (取代 v-bind:prop-name)
:
post: {
id: 1,
title: 'My Journey with Vue'
}
<blog-post v-bind="post"></blog-post>
<blog-post
v-bind:id="post.id"
v-bind:title="post.title"
></blog-post>
複製代碼
一個簡單的props
傳遞:
<div id="app">
<child-cpn :message="message"></child-cpn>
</div>
<template id="childCpn">
<div> 顯示信息:{{message}}</div>
</template>
<script>
let app = new Vue({
el: '#app',
data: {
message: 'hello'
},
components: {
'child-cpn': {
templte: '#childCpn',
props: ['message']
}
}
})
</script>
複製代碼
在 Vue
中,父子組件的關係
props
向下傳遞,事件向上傳遞。
父組件經過 props
給子組件下發數據,子組件經過事件給父組件發送消息。
props
支持的數據類型:
String
Number
Boolean
Array
Object
Date
Function
Symbol
複製代碼
示例:
Vue.component('my-component',{
props: {
// 基礎的類型檢查
propA: Number,
// 多個可能的類型
propB: [String, Number],
// propC: {
type: String,
required: true
},
// 帶有默認值的數字
propD: {
type: Number,
default: 100
},
// 帶有默認值的對象
propE: {
type: Object,
default: function(){
return {message: 'web'}
}
},
// 自定義驗證函數
propF: {
vfunc: function(value) {
return value > 1
}
}
}
})
複製代碼
子傳父
代碼:
this.$emit('item-click',item)
複製代碼
props
用於父組件向子組件傳遞數據,還有一種比較常見的是子組件傳遞數據或事件到父組件中。
自定義事件:
$emit()
來觸發事件。v-on
來監聽子組件事件。自定義事件代碼:
<div id="app">
<child-cpn @increment="changeTotal" @decrement="changeTotal"></child-cpn>
<h2>點擊次數</h2>
</div>
<template id="childCpn">
<div>
<button @click="increment">+1</button>
<button @click="decrement">-1</button>
</div>
</template>
let app = new Vue({
el: '#app',
data: {
total: 0
},
methods: {
changeTotal(counter) {
this.total = counter
}
},
components: {
'child-cpn': {
template: '#childCpn',
data(){
return{
counter: 0
}
},
methods: {
increment(){
this.counter++;
this.$emit('increment', this.counter)
},
decrement(){
this.counter--;
this.$emit('decrement',this.counter)
}
}
}
}
})
複製代碼
$children
有時候須要父組件直接訪問子組件,子組件直接訪問父組件,或者是子組件訪問父組件。
$children
或者$refs
$parent
對於$children
的訪問:
this.$children
是一個數組類型,它包含全部子組件對象。message
狀態。示例:
<div id="app">
<parent-cpn></parent-cpn>
</div>
// 父組件template
<template id="parentCpn">
<div>
<child-cpn1></child-cpn1>
<child-cpn2></child-cpn2>
<button @click="showChildCpn">顯示全部子組件信息</button>
</div>
</template>
// 子組件
<template id="childCpn1">
<h2>我是子組件1</h2>
</template>
// 子組件
<template id="childCpn2">
<h2>我是子組件2</h2>
</template>
Vue.component('parent-cpn',{
template: '#parentCpn',
methods: {
showChildCpn(){
for(let i=0; i<this.$children.length; i++){
console.log(this.$children[i].message)
}
}
}
})
複製代碼
$parent
子組件中直接訪問父組件,能夠經過$parent
$parent
來訪問父組件,可是儘可能不要這樣作父子組件的訪問方式
$refs
$children
的缺陷:
$children
訪問子組件,是一個數組類型,訪問其子組件要經過索引值。$refs
$refs
的使用:
$refs
和ref
指令一般一塊兒使用ref
給某個子組件綁定一個特定的id
this.$refs.id
能夠訪問到該組件示例:
<child-cpn1 ref="child1"></child-cpn1>
<child-cpn2 ref="child2"></child-cpn2>
<button @click="show">經過refs訪問子組件</button>
show() {
console.log(this.$refs.child1.message);
console.log(this.$refs.child2.message);
}
複製代碼
看看一個
.vue
文件項目
<template>
<div class="xxx">
<div class="xxx"
:class="{active: currentIndex === index}"
@click="itemClick(index)"
v-for="(item,index) in titles">
<span>{{item}}</span>
</div>
</div>
</template>
<script>
export default {
name: 'xxx',
props: {
titles: {
type: Array,
default() {
return []
}
}
},
data: function() {
return {
currentIndex: 0
}
},
}
</script>
<style scoped>
.xxx {
xxx: xxx;
}
</style>
複製代碼
三層部分:
vue
中的代碼slot
是什麼呢,它叫插槽,<slot>
元素做爲組件模板之中的內容分發插槽,傳入內容後<slot>
元素自身將被替換。
v-slot
用法:
slot
以及slot-scope
的用法:子組件編寫,父組件編寫默認插槽
子組件:
// 子組件
<template>
<div class="content">
// 默認插槽
<content-box class="text">
<slot>默認值</slot>
<content-box>
</div>
</template>
複製代碼
slot
基本使用
<slot>
能夠爲子組件開啓一個插槽。子組件定義一個插槽:
<slot>
中的內容表示,若是沒有在該組件中插入任何其餘內容,就默認顯示改內容。示例:
<div id="app">
<my-cpn></my-cpn>
<my-cpn>
<p>web</p>
</my-cpn>
</div>
<template id="myCpn">
<div>
<slot>我是誰</slot>
</div>
</template>
<script>
Vue.component('my-cpn',{
template: '#myCpn'
})
let app = new Vue({
el: '#app'
})
</script>
複製代碼
使用具名插槽
slot
元素添加一個name
屬性<slot name="web"></slot>
示例:
<div id="app">
// 沒有任何內容
<my-cpn></my-cpn>
// 傳入某個內容
<my-cpn>
<span slot="left">left</span>
</my-cpn>
<my-cpn>
<span slot="left">left</span>
<span slot="center">center</span>
<span slot="right">right</span>
</div>
<template id="myCpn">
<div>
<slot name="left">1</slot>
<slot name="center">2</slot>
<slot name="right">3</slot>
</div>
</template>
<script>
Vue.component('my-cpn', {
template: '#myCpn'
})
let app = new Vue({
el: '#app'
})
</script>
複製代碼
編譯做用域
Vue
實例屬性:
父組件模板的全部東西都會在父級做用域內編譯,子組件模板的全部東西都會在子級做用域內編譯。
父組件替換插槽的標籤,可是內容由子組件來提供。
什麼是模塊化,將一組模塊以正確的順序拼接到一個文件中的過程,模塊是實現特定功能的一組屬性和方法的封裝。
利用構造函數封裝對象
function web() {
var arr = [];
this.add = function(val) {
arr.push(var)
}
this.toString = function() {
return arr.join('')
}
}
var a = new web();
a.add(1); // [1]
a.toString(); // "1"
a.arr // undefined
複製代碼
示例:
var ModuleA = (function(){
// 定義一個對象
var obj = {}
// 在對象內部添加變量和方法
obj.flag = true
obj.myFunc = function(info) {
console.log(info)
};
// 將對象返回
return obj
}
複製代碼
if(ModuleA.flag) {
console.log('web')
}
ModuleA.myFunc('webweb')
複製代碼
常見的模塊化規範:
CommonJS
,AMD
,CMD
,ES6
中的Modules
什麼是AMD
,異步模塊定義,它是在瀏覽器端實現模塊化開發的規範,可是該規範不是原生js
支持的,使用AMD
規範進行開發的時候須要引入第三方的庫函數,就是RequireJS
。
RequireJS
解決了多個js
文件可能有依賴的關係,被依賴的文件須要早於依賴它的文件加載到瀏覽器;js
加載的時候瀏覽器會中止頁面渲染,加載文件越多,頁面就會失去響應時間越長。
CMD
是什麼,它是通用模塊定義,解決的問題和AMD
同樣,不過在模塊定義方式和模塊加載時機上不一樣,CMD
須要額外的引入第三方的庫文件SeaJS
。
JavaScript模塊化編程
那麼什麼是模塊化呢
將一個項目按照功能劃分,理論上一個功能一個模塊,互不影響,在須要的時候載入,儘可能遵循高內聚低耦合。
瞭解CommonJS
CommonJS 是一種思想,本質上是可複用的JavaScript,它導出特定的對象,提供其它程序使用。
使用module.exports
和exports.obj
來導出對象,並在須要它的程序中使用require('module')
加載。
模塊化的核心就是:導入和導出
導出:CommonJS
module.exports = {
flag: true,
test(a,b) {
return a+b
},
demo(a,b) {
return a*b
}
}
複製代碼
導入:CommonJS
// CommonJS模塊
let {test, demo, flag} = require('moduleA');
// =>
let ma = require('moduleA');
let test = ma.test;
let demo = ma.demo;
let flag = ma.flag;
複製代碼
由於網站開發愈來愈複雜,js文件又不少,就會出現一些問題:
CommonJS
,定義模塊,一個單獨的js
文件就是一個模塊,每一個模塊都有本身單獨的做用域,在該模塊內部定義的變量,沒法被其餘模塊讀取,除了定義爲global
對象的屬性。
模塊的導出:exports
和module.exports
模塊的導入:require
node
中,每一個模塊內部都有要給本身的module
對象module
對象中,有一個成員exports
也是一個對象exports
對象導出當前方法或變量,也可經過module.exports
導出node
簡化了操做,exports
等於module.exports
,至關於var exports = module.exports
es模塊的導入和導出
export function add(num1, num2) {
return num1 + num2
}
複製代碼
export function accString(param) {
if (param == 0) {
return '關'
}else if(param == 1) {
return '開'
}
}
import {
accString
} from '../../utils'
複製代碼
const name = 'web'
export default name
複製代碼
export default
一個模塊中包含某個功能,若是不但願給功能命名,可讓導入者本身來定:
export default function(){
console.log('web')
}
複製代碼
使用:
import myFunc from '../web.js'
myFunc()
複製代碼
export default
在同一個模塊中,不容許同時存在多個
import
使用
export
指令導出了模塊對外提供的接口
import
指令用於導入模塊中的內容
import {name, age} from './web.js'
複製代碼
經過*
能夠導入模塊中全部全部的export
變量
import * as web from './web.js'
console.log(web.name);
複製代碼
首先:new Vue()
,new
一個Vue
的實例,Observe data
數據查看,init Events
綁定事件,created
執行created
方法,判斷是否有el
屬性,若是沒有,vm.$mount(el)
表示處於未掛載狀態,能夠手動調用這個方法來掛載。判斷是否有template
屬性。
若是有el
屬性,判斷是否有template
屬性。
實例化期和加載期 建立期間的生命週期函數:beforeCreate
和 created
,beforeMount
和 mounted
。
beforeCreate
在實例初始化後,數據觀測data observer
和event/watcher
事件配置以前被調用。
更新期
運行期間的生命週期函數:beforeUpdate
和 updated
created
實例已經建立完成後被調用。
實例已完成如下的配置:數據觀測data observer
,屬性和方法的運算,watch/event
事件回調。
掛載階段還沒開始,$el
屬性目前不可見。
beforeMount
在掛載開始以前被調用,相關的render
函數首次被調用。mounted
,vm.$el
已經掛載在文檔內,對已有dom
節點的操做能夠在期間進行。beforeUpdate
數據更新時調用,發生在虛擬dmo
從新渲染和打補丁以前。updated
當這個鉤子被調用時,組件dom
已經更新,因此你如今能夠執行依賴於dom
的操做。activated
,deactivated
,beforeDestroy
,destroyed
。實例銷燬以前調用,vue
實例銷燬後調用。
卸載期
銷燬期間的生命週期函數:beforeDestroy
和 destroyed
實例生命週期鉤子
每一個vue實例在被建立時都要通過一系列的初始化過程,須要設置數據監聽,編譯模板,將實例掛載到dom
並在數據變化時更新dom
等,同時在這個過程當中也會運行一些叫作生命週期鉤子的函數。
用於給用戶在不一樣階段添加本身代碼的機會。
beforeCreate
,此時的data
是不可見的
data() {
return {
a: 1
}
},
beforeCreate() {
// red
console.log(this.a); // 看不見
}
複製代碼
created
實例已經建立完成後被調用,這個時候你看不見你頁面的內容,實例已完成表示:數據觀測data observer
,屬性和方法的運算,watch/event
事件回調。
這個時候掛載階段還沒開始,$el
屬性目前不可見。
export default {
data() {
return {
a: 1
}
},
beforeCreate() {
console.log(this.a);
},
created() {
// red
console.log(this.a);
console.log(this.$el);
// 此時data數據裏面的a可見,this.$el不可見
}
}
複製代碼
beforeMount
在掛載開始以前被調用,相關的render
函數首次被調用。
export default{
data() {
return {
a: 1
}
},
beforeCreate() {
console.log(this.a); // 不可見
},
created() {
console.log(this.a);
console.log(this.$el); // 不可見
},
beforeMount() {
console.log(this.$el); // 不可見
}
}
複製代碼
mounted
:
export default {
data() {
return {
a: 1
}
},
mounted() {
console.log(this.$el); // 此時$el 可見
}
}
複製代碼
beforeUpdate
鉤子,dom
更新以前調用:
beforeUpdate() {
console.log(this.a);
}
// document.getElementById("web").innerHTML
複製代碼
updated
鉤子,dom
更新以後調用:
updated() {
console.log(this.a);
}
// document.getElementById("web").innerHTML
複製代碼
activated
和deactivated
(組件)
activated() {
console.log("組件使用了");
},
deactivated() {
console.log("組件停用了");
Data to Drag},
複製代碼
keep-alive
是vue
的內置組件,能在組件切換過程當中將狀態保留在內存中,防止重複渲染dom
。
<keep-alive>
包裹動態組件時,會緩存不活動的組件實例,而不會銷燬它們。和<transition>
類似,<keep-alive>
是一個抽象組件:它自身不會渲染一個DOM
元素,也不會出如今父組件鏈中。
當組件在<keep-alive>
內被切換,它的activated
和deactivated
這兩個生命週期鉤子函數將會被對應指定。
它的使用是由於咱們不但願組件被從新渲染而影響使用體驗,或者是性能,避免屢次渲染下降性能。緩存下來,維持當前得狀態。
場景:
keep-alive
生命週期:
初次進入時:created > mounted > activated;退出後觸發 deactivated
;再次進入:會觸發activated
;事件掛載的方法等,只執行一次的放在mounted
中;組件每次進去執行的方法放在 activated
中。
app.vue
父組件:
<template>
<div>
<button @click="myBtn"> myBtn </button>
<keep-alive>
<range v-if="isShow"></range>
</keep-alive>
</div>
</template>
<script>
import range from './components/range.vue'
export default {
data() {
return {
a: 1,
isShow: true
}
},
methods: {
myBtn() {
this.isShow = !this.isShow
}
},
components: {
range
}
}
</script>
複製代碼
beforeDestroy
和destroyed
beeforeDestroy
類型爲function
,詳細:實例銷燬以前調用,在這一步,實例仍然徹底可用。
該鉤子在服務器端渲染期間不被調用。
destroyed
類型爲function
,詳細:vue
實例銷燬後調用,調用後,vue
實例指示的全部東西都會解綁定,全部的事件監聽器會被移除,全部的子實例也會被銷燬。
該鉤子在服務器端渲染期間不被調用。
beforeRouteEnter
和beforeRouteLeave
beforeRouteEnter() {
console.log('beforeRouteEnter')
},
beforeRouteLeave() {
console.log('beforeRouteLeave')
}
複製代碼
vue路由使用的,路由進去和路由離開的時候添加的。
created() {
console.log('開始執行created鉤子函數')
// 獲取data數據
console.log('獲取created屬性'+this.value)
// 獲取頁面元素
console.log(this.$refs['example'])
this.$nextTick(()=>{
console.log('執行created建立的this.$nextTick()函數')
})
},
mounted() {
console.log('開始執行mounted鉤子函數')
// 獲取掛載數據
console.log('獲取掛載數據--'+this.$refs['example'].innerText)
this.$nextTick(()=>{
console.log('執行mounted建立的this.$nextTick()函數')
})
},
methods: {
// 更新數據
updateDate(){
},
get(){
this.value='更新data內的value屬性值'
// 獲取頁面元素數據
console.log(this.$refs['example').innerText)
this.$nextTick(()=>{
console.log(this.$refs['example'].innerText)
})
}
}
複製代碼
var vm=new Vue({})
表示開始建立一個Vue
的實例對象,init events&liftcycle
表示剛初始化了一個vue
空的實例對象,這個時候,對象身上,只有默認的一些生命週期函數和默認事件,其餘東西都沒有建立,beforeCreate
生命週期函數執行的時候,data
和methods
中的數據都沒有初始化。在created
中,data
和methods
都已經被初始化好了,若是要調用methods
中的方法,或者操做data
中的數據,只能在created
中操做。而後vue
開始編輯模板,把vue
代碼中的那些指令進行執行,最終在內存中生成一個編譯好的最終模板字符串,渲染爲內存中的dom
,此時只是在內存中,渲染好了模板,並無把模板掛載到真正的頁面中去。beforeMount
函數執行的時候,模板已經在內存中編譯好了,可是還沒有掛載到頁面中去。create vm.$el and replace 'el' with it
這一步是將內存中編譯好的模板,真實的替換到瀏覽器的頁面中去。mounted
,只要執行完了mounted
,就表示整個vue
實例已經初始化完了。此時,組件從建立階段進入到了運行階段。
beforeUpdate
執行的時候,頁面中顯示的數據還舊的,而data
數據是最新的,頁面還沒有和最新的數據保持同步。updated
事件執行的時候,頁面和data
數據已經保持同步了,都是新的。virtual dom re-render and patch
執行,先根據data
中最新的數據,在內存中,從新渲染出一份最新的內存dom
樹,當最新的內存dom
樹被更新以後,會把最新的內存dom
樹,從新渲染到真實的頁面中,完成數據從data
到view
的跟新。
beforeDestroy
鉤子函數執行時,vue
實例就從運行階段,進入到了銷燬階段。此時的實例仍是可用的階段,沒有真正執行銷燬過程。destroyed
函數執行時,組件已經被徹底銷燬了,都不可用了。
mvvm
的理解雙向綁定的過程
視圖view
,路由-控制器Controller
,數據Model
view
->dom
,viewModel
,Model
數據
傳統的mvc
指用戶操做會請求服務器端路由,路由會調用對應的控制器來處理,控制器會獲取數據,將結果返回給前端,讓頁面從新渲染。
mvvm
,對於傳統的前端會將數據手動渲染到頁面上,mvvm
模式不須要用戶收到操做dom
元素,將數據綁定到viewModel
層上,會自動將數據渲染到頁面中,視圖變化會通知viewModel
層更新數據。
vue
內部是如何監聽message
數據的改變vue
是如何知道要通知哪些人,界面發生刷新核心:
Object.defineProperty
,監聽對象屬性的改變代碼:
Object.keys(obj).forEach(key => {
let value = obj[key]
Object.defineProperty(obj, key, {
set(newValue) {
// 監聽改變
value = newValue
},
get() {
return value
}
})
})
obj.name = 'web'
複製代碼
發佈者訂閱者
class Dep {
constructor() {
this.subs = []
}
}
class Watcher {
constructor(name) {
this.name = name;
}
}
複製代碼
對象的Object.defindeProperty
中的訪問器屬性中的get
和set
方法
getter
和setter
,創建watcher
並收集依賴。說明:
watcher
經過回調函數更新view
;observer
觀測data
數據,經過get
通知dep
收集watcher
,dep
經過notify()
通知watcher
數據更新,watcher
經過addDep()
收集依賴。
Observer
:用於監聽劫持全部data
屬性,dep,watcher,view
,Compile
解析el
模板中的指令。
依照下圖(參考《深刻淺出vue.js
》)
首先從初始化data
數據開始,使用Observer
監聽數據,個體每一個數據屬性添加Dep
,而且在Data
,有兩個getter
,setter
。在它的getter
過程添加收集依賴操做,在setter
過程添加通知依賴的操做。
在解析指令或者給vue
實例設置watch選項或者調用$watch
時,生成對應的watcher
並收集依賴。
Data
經過Observer
轉換成了getter/setter
的形式,來對數據追蹤變化。
修改對象的值的時候,會觸發對應的setter
,setter
通知以前依賴收集獲得的 Dep
中的每個Watcher
,告訴它們值改變了,須要從新渲染視圖。
數據雙向綁定原理
Object.defineProperty
vue
在初始化數據時,會給data
中的屬性使用Object.defineProperty
從新定義全部屬性,當頁面取到對應屬性時,會進行依賴收集,若是屬性發生變化會通知相關依賴進行更新操做。initData
初始化用戶傳入的data
數據,new Observer
將數據進行觀測,this.walk(value)
進行對象的處理,defineReactive
循環對象屬性定義響應式變化,Object.defineProperty
,使用Object.defineProperty
從新定義數據。
使用使用Object.defineProperty
從新定義數據的每一項。
Object.defineProperty(obj,key,{
enumerable: true,
configurable: true,
get: function reactiveGetter(){
const value=getter?getter.call(obj):val
if(Dep.target){
dep.depend()
if(childOb){
childOb.dep.depend()
if(Array.isArray(value)){
dependArray(value)
}
}
}
return value
},
set: function reactiveSetter(newVal) {
const value=getter?getter.call(obj).val
if(newVal === value || (newVal !== newVal && value !==value)){
return
}
if(process.env.NODE_ENV !== 'production' && customSetter){
customSetter()
}
val = newVal
childOb = !shallow && observe(newVal)
dep.notify()
}
})
複製代碼
使用函數劫持的方式,重寫了數組的方法,vue
將data
中的數組進行了原型鏈的重寫,指向了本身定義的數組原型方法,這樣當調用數組api
時,能夠通知依賴跟新,若是數組中包含着引用類型,會對數組中的引用類型再次進行監控。
initData
初始化用戶傳入的data
數據,new Observer
將數據進行觀測,protoAugment(value,arrayMethods)
將數據的原型方法指向重寫的原型。
observerArray
深度觀察數組中的每一項代碼:
if(Array.isArray(value)){
// 判斷數組
if(hasProto){
protoAugment(value, arrayMethods)// 改寫數組原型方法
}else{
copyAugment(value,arrayMethods,arrayKeys)
}
this.observeArray(value)
//深度觀察數組中的每一項
}else{
this.walk(value)
// 從新定義對象類型數據
}
function protoAugment(target, src: Object){
target.__proto__ = src
}
export const arrayMethods = Object.create(arrayProto)
const methodsToPatch=[
'push',
'pop',
'shift',
'unshift',
'splice',
'sort',
'reverse'
]
methodsToPatch.forEach(function (method){
const original = arrayProto[method]
def(arrayMethods, method, function mutator(...args){
const result = original.apply(this.args)
const ob = this.__ob__
let inserted
switch(method) {
case 'push':
case 'unshift':
inserted = args
break
case 'splice':
inserted = args.slice(2)
break
}
if(inserted) ob.observerArray(inserted)
// 對插入的數據再次進行觀測
ob.dep.notify()
// 通知視圖更新
return result
}
}
observeArray(items: Array<any>) {
for(let i=0, l = items.length; i<1; i++) {
observe(item[i])
// 觀測數組中的每一項
}
}
複製代碼
若是不採用異步更新,每次更新數據都會對當前組件進行從新渲染,爲了性能考慮。
dep.notify()
通知watcher
進行更新操做,subs[i].update()
依次調用watcher
的update
,queueWatcher
將watcher
去重放到隊列中,nextTick(flushSchedulerQueue)
異步清空watcher
隊列。
微任務高於宏任務先執行
nextTick
方法主要使用了宏任務和微任務,定義了一個異步方法,屢次調用了nextTick
會將方法存入到隊列中,經過這個異步方法清空當前隊列。
nextTick
方法是異步方法。
原理:nextTick(cb)
調用nextTick
傳入cb
,callbacks.push(cb)
將回調存入數組中,timerFunc()
調用timerFunc
,返回promise
支持promise
的寫法。
什麼是webpack,webpack是一個現代的JavaScript應用的靜態模塊打包工具。
webpack是前端模塊化打包工具
安裝webpack須要安裝node.js,node.js自帶有軟件包管理工具npm
全局安裝
npm install webpack@3.6.0 -g
複製代碼
局部安裝
npm install webpack@3.6.0 --save-dev
複製代碼
webpack.config.js
固定名文件:
const path = require("path")
module.exports = {
entry: './src/main.js',
output: {
patch: './dist',
filename: ''
},
}
複製代碼
package.json
{
"name": 'meetwebpack',
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo ..."
},
"author": "",
"license": "ISC"
}
複製代碼
什麼是loader
loader
是webpack
中一個很是核心的概念
loader
使用過程:
npm
安裝須要使用的loader
webpack.config.js
中的moudules
關鍵字下進行配置package.json
中定義啓動
{
"name": "meetwebpack",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"build": "webpack"
},
"author": "",
"license": "ISC",
"devDependencies": {
"webpack": "^3.6.0"
}
}
複製代碼
webpack
的介紹webpack
能夠看作是模塊打包機,它能夠分析你的項目結構,找到JavaScript模塊以及其它的一些瀏覽器不能直接運行的拓展語言,將其打包爲合適的格式以供瀏覽器使用。
能夠實現代碼的轉換,文件優化,代碼分割,模塊合併,自動刷新,代碼校驗,自動發佈。
安裝本地的webpack
webpack webpack-cli -D
複製代碼
初始化:
yarn init -y
複製代碼
yarn add webpack webpack-cli -D
複製代碼
webpack能夠進行0配置,它是一個打包工具,能夠輸出後的結果(Js模塊),打包(支持js的模塊化)
運行webpack命令打包
npx webpack
複製代碼
webpack.config.js
,webpack
是node
寫出來的node
的寫法:
let path = require('path')
console.log(path.resolve('dist');
module.exports = {
mode: 'development',
// 模式,默認兩種,production,development
entry: '' // 入口
output: {
filename: 'bundle.js',
// 打包後的文件名
path: path.resolve(__dirname, 'build'),
// 把相對路徑改寫爲絕對路徑
}
}
複製代碼
自定義,webpack.config.my.js
使用命令:
npx webpack --config webpack.config.my.js
複製代碼
package.json
:
{
"name": 'webpack-dev-1',
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"scripts": {
"build": "webpack --config webpack.config.my.js"
},
"devDependencies": {
"webpack": "^4.28.3",
"webpack-cli": "^3.2.0"
}
}
複製代碼
使用命令:
npm run build
// npm run build -- --config webpack.config.my.js
複製代碼
開發服務器的配置
代碼:
let path = require('path')
let HtmlWebpackPlugin = require('html-webpack-plugin')
console.log(path.resolve('dist');
module.exports = {
devServer: {
// 開發服務器的配置
port: 3000,
// 看到進度條
progress: true,
contentBase: "./build",
compress: true
},
mode: 'development',
// 模式,默認兩種,production,development
entry: '' // 入口
output: {
filename: 'bundle.js',
// 打包後的文件名
path: path.resolve(__dirname, 'build'),
// 把相對路徑改寫爲絕對路徑
},
plugins: [
// 數組,全部的webpack插件
new HtmlWebpackPlugin({
template: './src/index.html',
filename: 'index.html',
minify:{
removeAttributeQuotes: true,//刪除「」
collapseWhitespace: true, // 變成一行
},
hash: true
})
],
module: {
// 模塊
rules: [
// 規則
{test: /\.css$/, use: [{
loader: 'style-loader',
options: {
insertAt: 'top'
}
},'css-loader'] },
]
}
}
複製代碼
output: {
filename: 'bundle.[hash:8].js',// 打包文件名後只顯示8位
}
複製代碼
{
"name": 'webpack-dev-1',
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"scripts": {
"build": "webpack --config webpack.config.my.js",
"dev": "webpack-dev-server"
},
"devDependencies": {
"webpack": "^4.28.3",
"webpack-cli": "^3.2.0"
}
}
複製代碼
yarn add css-loader style-loader -D
複製代碼
樣式:
style-loader
將模塊的導出做爲樣式添加到dom
中css-loader
解析css
文件後,使用import
加載,而且返回css
代碼less-loader
加載和轉譯less
文件sass-loader
加載和轉譯sass/scss
文件postcss-loader
使用PostCSS
加載和轉譯css/sss
文件stylus-loader
加載和轉譯Stylus
文件style-loader
安裝:
npm install style-loader --save-dev
複製代碼
用法:
建議將style-loader
與css-loader
結合使用
component.js
import style from './file.css'
複製代碼
css-loader
只負責將css文件進行加載style-loader
負責將樣式添加到dom
中loader
時,是從右到左代碼:
// webpack.config.js
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}
]
}
複製代碼
css
文件處理:style-loader
安裝style-loader
npm install --save-dev style-loader
複製代碼
style-loader
須要放在css-loader
的前面,webpack
在讀取使用的loader
的過程當中,是按照從右向左的順序讀取的。
webpack.config.js
的配置以下:
const path = require('path')
module.exports = {
// 入口:能夠是字符串/數組/對象,這裏咱們入口只有一個,因此寫一個字符串便可。
entry: './src/main.js',
// 出口:一般是一個對象,裏面至少包含兩個重要屬性,path和filename
output:{
path: path.resolve(__dirname, 'dist'), // 注意:path一般是一個絕對路徑
filename: 'bundle.js'
},
module: {
rules: {
{
test: /\.css$/,
use: ['style-loader','css-loader']
}
}
}
}
複製代碼
webpack
less文件處理安裝:
npm install --save-dev less-loader less
複製代碼
示例:
將css-loader
,style-loader
,less-loader
鏈式調用,能夠把全部樣式當即應用於dom
。
// webpack.config.js
module.exports = {
...
rules: [{
test: /\.less$/,
use: [{
loader: 'style-loader'
},{
loader: 'css-loader'
},{
loader: 'less-loader'
}]
}]
}
複製代碼
圖片文件處理
css normal
代碼:
body {
background: url("../img/test.jpg")
}
複製代碼
url-loader
npm install --save-dev url-loader
複製代碼
用法
url-loader
功能相似於file-loader
,可是在文件大小低於指定的限制時,能夠返回一個DataURL
import img from './image.png'
複製代碼
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'url-loader',
options: {
limit: 8192
}
}
]
}
]
}
}
複製代碼
img
,文件要打包到的文件夾
name
,獲取圖片原來的名字,放在該位置
hash:8
,爲了防止圖片名稱衝突,依然使用hash
,可是咱們只保留8位
ext
,使用圖片原來的擴展名
若是但願es6轉成es5,那麼就須要使用babel
npm install --save-dev babel-loader@7 babel-core babel-preset-es2015
複製代碼
配置webpack.config.js
文件:
{
test: /\.m?js$/,
use: {
loader: 'babel-loader',
options: {
presets: ['es2015']
}
}
}
複製代碼
如何在咱們的webpack
環境中集成vue.js
代碼:
npm install vue --save
複製代碼
runtime-only
代碼中,不能夠有任何的template
runtime-compiler
代碼中,能夠有template
由於有compiler
能夠用於編譯template
spa
(simple age web application
)->vue-router
(前端路由)
.vue
文件封裝處理
安裝vue-loader
和vue-template-compiler
npm install vue-loader vue-template-compiler --save-dev
複製代碼
plugin
是什麼?plugin
是插件的意思,一般用於對某個現有的架構進行擴展。webpack
中的插件,是對webpack
現有功能的各類擴展。loader
和plugin
的區別loader
主要用於轉換某些類型的模塊,它是一個轉換器。plugin
是插件,它是對webpack
自己的擴展,是一個擴展器。plugin
的使用過程:npm
安裝須要使用的plugins
webpack.config.js
中的plugins
中配置插件webpack.config.js
的文件:
查看bundle.js
文件的頭部:
什麼是vue cli
,Command-Line Interface
,命令行界面,俗稱腳手架,vue cli
是一個官方發佈的項目腳手架。使用vue-cli
能夠快速搭建vue
開發環境以及對應的webpack
配置。
vue cli
的使用
安裝vue
腳手架
npm install -g @vue/cli
複製代碼
代碼:
vue init webpack vuecli2test
複製代碼
Project name
項目名稱,不能包含大寫Project description
項目描述Author
做者信息Vue build``runtime
Install vue-router``no
是否安裝等目錄結構詳解
build``config
是 webpack
相關配置,node_modules
是依賴的node
相關的模塊,src
是寫代碼地方。 .babelrc
是es代碼相關轉換配置,.editorconfig
項目文本相關配置,.gitignore``git
倉庫忽略的文件夾配置,.postcssrc.js
爲css
相關轉化的配置。
.editorconfig
前端模塊化:
爲何使用模塊化,簡單寫js代碼帶來的問題,閉包引發代碼不可複用,本身實現了簡單的模塊化,es
中模塊化的使用:export
和import
。
npm install @vue/cli -g
複製代碼
npm clean cache -force
複製代碼
vue cli2
初始化:
vue init webpack my-project
複製代碼
vue cli3
初始化項目:
vue create my-project
複製代碼
箭頭函數,是一種定義函數的方式
function
const a = function(){
}
複製代碼
const obj = {
b: function() {
},
b() {
}
}
複製代碼
const c = (參數列表) => {
}
const c = () => {
}
複製代碼
箭頭函數參數和返回值
代碼:
const sum = (num1, num2) => {
return num1 + num2
}
const power = (num) => {
return num * num
}
const num = (num1,num2) => num1 + num2
複製代碼
const obj = {
a() {
setTimeout(function() {
console.log(this); // window
})
setTimeout(()=>{
console.log(this); // obj對象
})
}
}
複製代碼
路由,,vue-router
基本使用,vue-router
嵌套路由,vue-router
參數傳遞,vue-router
導航守衛。
路由是一個網絡工程裏面的術語,路由就是經過互聯的網絡把信息從源地址傳輸到目的地址的活動。
路由器提供了兩種機制:路由和轉送。路由是決定數據包歷來源到目的地的路徑,轉送將輸入端的數據轉移到合適的輸出端。路由中有一個很是重要的概念叫路由表。路由表本質上就是一個映射表,決定了數據包的指向。
後端路由:後端處理url和頁面之間的映射關係。
vue-router
和koa-router
的區別:
vue-router
是前端路由,koa-router
是後端路由。
vue-router
前端路由原理:
前端路由主要模式:hash
模式和history
模式。
路由的概念來源於服務端,在服務端中路由描述的是 URL 與處理函數之間的映射關係。
先後端渲染之爭
hash
和html5
的history
前端路由的核心是改變url
,可是頁面不進行總體的刷新。單頁面,其實spa
最重要的特色就是在先後端分離的基礎上加了一層前端路由。就是前端來維護一套路由規則。
url
的hash
url
的hash
是錨點#
,本質上是改變window.location
的href
屬性。直接賦值location.hash
來改變href
,可是頁面不發生刷新。
html5
的history
模式:pushState
html5
的history
模式:replaceState
html5
的history
模式:go
history.go()
history.back()
等價於history.go(-1)
history.forward()
等價於history.go(1)
安裝vue-router
npm install vue-router --save
複製代碼
Vue.use(VueRouter)
Vue
實例中掛載建立的路由實例代碼:
// 配置路由相關的信息
import VueRouter from 'vue-router'
import vue from 'vue'
import Home from '../components/Home'
import About from '../components/About'
// 經過Vue.use(插件),安裝插件
Vue.use(VueRouter)
// 配置路由和組件之間的應用關係
const routes = [
{
path: '/home',
component: Home
},
{
path: '/about',
component: About
}
]
// 建立VueRouter對象
const router = new VueRouter({
routes
})
// 將router對象傳入到`Vue`實例
export default router
複製代碼
main.js
import Vue from 'vue'
import App from './App'
import router from './router'
Vue.config.productionTip = false
new Vue({
el: '#app',
router,
render: h => h(App)
})
複製代碼
使用vue-router
的步驟
<router-link>
和<router-view>
代碼:
組件components
// home
<template>
<div>
<h2>我是首頁</h2>
</div>
</template>
<script>
export default {
name: 'Home'
}
</script>
<style scoped>
</style>
複製代碼
<template>
<div>
<h2>我是關於</h2>
</div>
</template>
<script>
export default {
name: 'Aboout'
}
</script>
<style scoped>
</style>
複製代碼
App.vue
<template>
<div id="app">
<router-link to="/home">首頁</router-link>
<router-link to="/about">關於</router-link>
<router-view></router-view>
</div>
</div>
<script>
export default {
name: 'App'
}
</script>
<style>
</style>
複製代碼
main.js
import Vue from 'vue'
import App from './App'
import router from './router'
Vue.config.productionTip = false
new Vue({
el: '#app',
router,
render: h => h(App)
})
複製代碼
路由的偶然值和修改成
history
模式
建立router
實例
代碼:
router->index.js
import Vue from 'vue'
import VueRouter from 'vue-router'
// 注入插件
Vue.use(VueRouter)
// 定義路由
const routes = []
// 建立router實例
const router = new VueRouter({
routes
})
// 導出router實例
export default router
複製代碼
main.js
代碼:
import Vue from 'vue'
import App from './App'
import router from './router'
new Vue({
el: '#app',
router,
render: h=>h(App)
})
複製代碼
router->index.js
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../components/home'
import About from '../components/about'
// 注入插件
Vue.use(VueRouter)
// 定義路由
const routes = [
{
path: '/home',
component: Home
},
{
path: '/about',
component: About
}
]
複製代碼
使用App.vue
代碼
<template>
<div id="app">
<router-link to="/home">首頁</router-link>
<router-link to="/about">關於</router-link>
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'App',
components: {
}
}
複製代碼
<router-link>
該標籤是一個vue-router
已經內置的組件,它會被渲染成一個<a>
標籤<router-view>
該標籤會根據當前的路徑,動態渲染出不一樣的組件。<router-view>
處於同一個等級。<router-view>
掛載的組件,其餘內容不會發生改變。路由的默認路徑
默認狀況下,進入網站的首頁,<router-view>
渲染首頁的內容,可是默認沒有顯示首頁組件,必須讓用戶點擊才能夠。
那麼如何讓路徑默認跳轉到首頁,而且<router-view>
渲染首頁組件呢,只須要配置一個映射就能夠:
const routes = [
{
path: '/',
redirect: '/home'
}
]
複製代碼
配置解析:在routes
中又配置了一個映射,path
配置的是根路徑:/
,redirect
是重定向,就是咱們將根路徑重定向到/home
的路徑下。
// main.js
const router = new VueRouter({
// 配置路由和組件之間的應用關係
routes,
mode: 'history'
})
複製代碼
改變路徑的方式:
url
的hash
html5
的history
url
的hash
使用html5
的history
模式:
// 建立router實例
const router = new VueRouter({
routes,
mode: 'history'
})
複製代碼
router-link
,使用了一個屬性:to
,用於指定跳轉的路徑。tag
能夠指定<router-link>
以後渲染成什麼組件。
replace
屬性不會留下history
記錄,指定replace
的狀況下,後退鍵返回不能返回到上一個頁面中。
active-class
屬性,當<router-link>
對應的路由匹配成功時,會自動給當前元素設置一個router-link-active
的class
,設置active-class
能夠修改默認的名稱。
const router = new VueRouter({
routes,
mode: 'history',
linkActiveClass: 'active'
})
複製代碼
App.vue
代碼:
// app.vue
<template>
<div id="app">
<button @click="linkToHome">首頁</button>
<button @click="linkToAbout">關於</button>
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'App',
methods: {
linkToHome() {
this.$router.push('/home')
},
linkToAbout() {
this.$router.push('/about')
}
}
}
</script>
複製代碼
<img :src="imgURL" alt="">
<router-link :to="'/uer/' + userId"> 用戶 </router-link>
<script>
export default {
name: 'User',
computed: {
userId() {
return this.$route.params.userId
}
}
}
</sript>
複製代碼
const Home = () => import('../components/Home')
const HomeNews = () => import('../components/HomeNews')
const HomeMessage = () => import('../components/HomeMessage')
{
path: '/home',
component: Home,
children: [
{
path: 'news',
component: HomeNews
},
{
path: 'news',
component: HomeMessage
}
]
}
複製代碼
<router-link to = "/home/news">新聞</router-link>
<router-link to = "/home/message">信息</router-link>
複製代碼
默認選中:
傳遞參數主要有兩種類型,params
和query
params
的類型:
/router/:id
path
後面跟着對應的值/router/123
vue-router
傳遞參數代碼
<router-link :to="{path: '/profile'}">用戶</router-link>
複製代碼
統一資源定位符
統一資源定位符,統一資源定位器,統一資源定位地址,Url地址等,網頁地址。如同在網絡上的門牌,是因特網上標準的資源的地址。
userClick() {
this.$router.push('/user/' + this.userId)
}
btnClick() {
this.$router.push({
path: '/user',
query: {
name: 'web',
age: 12,
height: 1.2
}
})
}
複製代碼
$route
和$router
是有區別的
獲取參數經過$route
對象獲取的,在使用vue-router
的應用中,路由對象會被注入每一個組件中,賦值爲this.$route
,而且當路由切換時,路由對象會被更新。
<template>
<div>
<p> {{$route.params}} </p>
</div>
</template>
複製代碼
query
的類型:
/router
也是普通配置query
的key
做爲傳遞方式router?id=123
,/router?id=abc
$route
和$router
是有區別的
const router = new VueRouter({
routes,
mode: 'history',
linkActiveClass: 'active'
})
複製代碼
Vue.config.productionTip = false
Vue.prototype.test = function() {
console.log('test')
}
Vue.prototype.name = 'web'
複製代碼
$route
和$router
是有區別的
$router
爲VueRouter
實例,想要導航到不一樣url
,則使用$router.push
方法。$route
爲當前router
跳轉對象裏面能夠獲取name
,path
,query
,params
等。vue-router
全局導航
meta:元數據
router.beforeEach((to,from,next) => {
// from 跳轉到to
document.title = to.matched[0].meta.title
console.log(to);
next()
})
複製代碼
// 後置鉤子hook
router.afterEach((to,from) => {
console.log();
})
複製代碼
導航守衛:導航表示路由正在發生改變。
vue-router
提供的導航守衛主要用來經過跳轉或取消的方式守衛導航。有多種機會植入路由導航過程當中,全局的,單個路由獨享的,或者組件級的。
全局守衛
可使用router.beforeEach
,註冊一個全局前置守衛:
const router = new VueRouter({..})
router.beforeEach((to,from,nex)=>{
})
複製代碼
當一個導航觸發時,全局前置守衛按照建立順序調用。守衛是異步解析執行,此時導航在全部守衛resolve
完以前一直處於等待中。
to:Route
,即將要進入的目標路由對象from:Route
,當前導航正要離開的路由next:Function
,必定要調用該方法來resolve
這個鉤子。vue-router-keep-alive
keep-alive
和vue-router
router-view
是一個組件,若是直接被包含在keep-alive
裏面,全部路徑匹配到的視圖組件都會被緩存。
keep-alive
是Vue
內置的一個組件,可使被包含的組件保留狀態,或避免從新渲染。
屬性:
include
字符串或正則表達式,只有匹配的組件會被緩存exclude
字符串或正則表達式,任何匹配的組件都不會被緩存<keep-alive>
<router-view>
// 全部路徑匹配到的視圖組件都會被緩存
</router-view>
<keep-alive>
複製代碼
Promise
的使用es6
的特性Promise
,它是異步編程的一種解決方案。
定時器的異步事件:
setTimeout(function() {
let data = 'web'
console.log(content)
},1000)
new Promise((resolve, reject) => {
setTimeout(function(){
resolve('web')
reject('error')
},1000)
}).then(data=>{
console.log(data)
}).catch(error=> {
console.log(error)
})
複製代碼
Promise
三種狀態:
pending
等待狀態,好比正在進行網絡請求,或定時器沒有到時間。fulfill
,知足狀態,主動回調resolve
時,而且回調.then()
reject
,拒絕狀態,回調reject
時,而且回調.catch()
vuex
是一個專門爲vue.js
應用程序開發的狀態管理模式
它採用集中式存儲管理應用的全部組件的狀態,,並以相應的規則保證狀態以一種可預測的方式發生變化。
View components -> actions(dispatch方式) -> mutations(commit方式) -> state -> View components
複製代碼
Vuex
核心概念5個:
State
,Getters
,Mutation
,Action
,Module
State
單一狀態樹,單一數據源。
Mutation
狀態更新
Vuex
的store
的更新惟一方式,提交Mutation
Mutation
的主要包括兩部分:
state
mutation
的定義:
mutations: {
increment(state) {
state.count++
}
}
複製代碼
經過mutation
更新
increment: function() {
this.$store.commit('increment')
}
複製代碼
參數被稱爲是mutation
的載荷payload
Vuex
的store
中的state
是響應式的,當state
中的數據發生改變時,Vue
組件會自動更新。
store
中初始化好所需的屬性state
中的對象添加新屬性時:使用Vue.set(obj,'newObj',123)
Mutation
常量類型
// mutation-types.js
export const UPDATE_INFO = 'UPDATE_INFO'
import Vuex from 'vuex'
import Vue from 'vue'
import * as types from './mutation-types'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
info: {
name: 'web',
age: 12
}
},
mutations: {
[types.UPDATE_INFO](state, payload) {
state.info = {...state.info, 'height': payload.height
}
}
})
複製代碼
<script>
import {UPDATE_INFO} from './store/mutation-types';
export default{
name: 'App',
components: {
},
computed: {
info(){
return this.$store.state.info
}
},
methods: {
updateInfo(){
this.$store.commit(UPDATE_INFO,{height:1.00})
}
}
}
</script>
複製代碼
注意:不要再mutation
中進行異步操做,mutation
同步函數,在其中的方法必須時同步方法。
action
的基本定義,若是有異步操做,好比網絡請求,
// 不能再mutation中使用異步操做,不能再這裏進行異步操做
update(state) {
setTimeout(()=>{
state.info.name = 'web'
},1000)
}
mutations: {
// 方法
[INCREMENT](state){
state.counter++
}
}
複製代碼
actions: {
// context:上下文,=》store
<!--aUpdateInfo(context) {-->
<!-- setTimeout(()=>{-->
<!-- state.info.name = 'web'-->
<!-- },1000)-->
<!--}-->
}
複製代碼
actions: {
aUpdateInfo(context) {
setTimeout(()=>{
context.commit('updateInfo')
},1000)
}
}
// xx.vue
updateInfo(){
this.$store.dispatch('aUpdateInfo')
}
複製代碼
updateInfo(){
<!--this.$store.commit('updateInfo')-->
this.$store.dispatch('aUpdateInfo',{
message: 'web',
success: () => {
console.log('web')
}
})
}
複製代碼
aUpdateInfo(context, payload) {
return new Promise((resolve, reject) => {...})
}
複製代碼
modules時模塊的意思
getters: {
stu(){
},
stuLength(state, getters) {
return getters.stu.length
}
}
複製代碼
使用根數據:
getters: {
fullName(state) {
return state.name + '1'
},
fullName1(state, getters) {
return getters.fullName + '2'
},
fullName3(state, getters, rootState) {
return getters.fullName2+rootState.counter
}
}
複製代碼
在模塊中actions
打印console.log(context)
actions
接收一個context
參數對象,局部狀態經過context.state
暴露出來,根節點狀態爲context.rootState
import mutations from './mutations'
import actions from './actions'
import getters from './getters'
import moduleA from './modules/moduleA'
import Vuex from 'vuex'
import Vue from 'vue'
Vue.use(Vuex)
const state = {
}
const store = new Vuex.Store({
state,
mutations,
actions,
getters,
modules: {
a: moduleA
}
})
export default store
複製代碼
axios網絡模塊的封裝
ajax
是基於XMLHttpRequest(XHR)
;jQuery-Ajax
相對於傳統的ajax
很是好用。
axios
特色:
XMLHttpRequests
請求node.js
中發送http
請求Promise API
axios
請求方式:
axios(config)
axios.request(config)
axios.get()
axios.delete()
axios.head()
axios.post()
axios.put()
axios.patch()
複製代碼
安裝
npm install axios --save
複製代碼
axios({
// 默認get
url: '',
method: 'get'
}).then(res=>{
console.log(res)
})
複製代碼
// import request from "../utils/request.js"
import {request} from './network'
export function getHome() {
return request({
url: '/home/xxx'
})
}
export function getXX(type, page) {
return request({
url: '/home/xx',
params: {
type,
page
}
})
}
複製代碼
併發請求
代碼:
axios.all([axios({
url: ''
}), axios({
url: '',
params: {
type: '',
page: 1,
}
})]).then(results => {
})
// then(axios.spread((res1,res2)=>{...}))
複製代碼
全局配置
axios.defaults.baseURL=''
axios.all ..{
url: '/home'
}
axios.defaults.baseURL = 'https://api.example.com';
axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
axios.defaults.baseURL = global.HOST;
複製代碼
request.js
import axios from 'axios'
export function request(config,success,failure){
// 建立axios實例
const instance = axios.create({
baseURL: '',
timeout: 5000
})
// 發送網絡請求
instance(config)
.then(res=>{
success(res)
})
.catch(err=>{
failure(err)
})
}
複製代碼
main.js
import {request} from './xx/request'
request({
url: ''
},res=>{
),err=>{
}
複製代碼
也可使用promise
方法,不過自己返回的就是promise
import axios from 'axios'
export function request(config) {
const instance = axios.create({
baseURL: '',
timeout: 2000
})
return instance(config)
}
複製代碼
axios
攔截器的使用
// 配置請求和響應攔截
instance.interceptors.request.use(config => {
console.log('request攔截success中')
return config
},err => {
console.log('request攔截failure中')
return err
})
instance.interceptors.response.use(response => {
console.log('response攔截success中')
return response.data
},err => {
console.log('response攔截failure中')
return err
})
複製代碼
封裝axios
// request.js
import axios from 'axios'
cosnt service = axios.create({
baseURL: process.env.BASE_API,
timeout: 2000
})
service.interceptors.request.use(config=>{
//發請求前作的一些處理,數據轉化,配置請求頭,設置token,設置loading等
config.data=JSON.stringify(config.data);
config.headers = {
'Content-Type':'application/x-www-form-urlencoded'
}
return config
},error=>{
Promise.reject(error)
})
// 響應攔截器
service.interceptors.response.use(response => {
return response
}, error => {
if (error && error.response) {
switch (error.response.status) {
case 400:
error.message = '錯誤請求'
break;
case 401:
error.message = '未受權,請從新登陸'
break;
case 403:
error.message = '拒絕訪問'
break;
case 404:
error.message = '請求錯誤,未找到該資源'
window.location.href = "/NotFound"
break;
case 405:
error.message = '請求方法未容許'
break;
case 408:
error.message = '請求超時'
break;
case 500:
error.message = '服務器端出錯'
break;
case 501:
error.message = '網絡未實現'
break;
case 502:
error.message = '網絡錯誤'
break;
case 503:
error.message = '服務不可用'
break;
case 504:
error.message = '網絡超時'
break;
case 505:
error.message = 'http版本不支持該請求'
break;
default:
error.message = `鏈接錯誤${error.response.status}`
}
} else {
if (JSON.stringify(error).includes('timeout')) {
Message.error('服務器響應超時,請刷新當前頁')
}
error.message('鏈接服務器失敗')
}
Message.error(err.message)
return Promise.resolve(error.response)
})
// 導入文件
export default service
複製代碼
封裝請求http.js
import request from './request'
const http ={
/**
* methods: 請求
* @param url 請求地址
* @param params 請求參數
*/
get(url,params){
const config = {
methods: 'get',
url:url
}
if(params){
config.params = params
}
return request(config)
},
post(url,params){
const config = {
methods: 'post',
url:url
}
if(params){
config.data = params
}
return request(config)
},
put(url,params){
const config = {
methods: 'put',
url:url
}
if(params){
config.params = params
}
return request(config)
},
delete(url,params){
const config = {
methods: 'delete',
url:url
}
if(params) {
config.params = params
}
return request(config)
}
}
export default http
複製代碼
// api.js
import http from '../utils/http'
let resquest = "/xx/request/"
// get請求
export function getListAPI(params){
return http.get(`${resquest}/getList.json`,params)
}
// js
//建立新的axios實例,
const service = axios.create({
baseURL: process.env.BASE_API,
timeout: 3 * 1000
})
複製代碼
建立項目:
vue create webMall
npm run serve
複製代碼
// .editorconfig
root = true
[*]
charset = utf-8
indent_style=space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
複製代碼
項目在
window
下部署
main.js
代碼:
import store from './store'
import FastClick from 'fastclick'
import VueLazyLoad from 'vue-lazyload'
import toast from 'components/common/toast'
Vue.config.productionTip = false
// 添加事件總線對象
Vue.prototype.$bus = new Vue()
// 安裝toast插件
Vue.use(toast)
// 解決移動端300ms延遲
FastClick.attach(document.body)
// 使用懶加載的插件
Vue.use(VueLazyLoad,{
loading: require('./xx.png')
})
複製代碼
windows
安裝nginx
,linux
部署,centos
上安裝nginx
linux ubuntu
Ubuntu
是一個以桌面應用爲主的Linux
操做系統,其名稱來自非洲南部祖魯語或豪薩語的「ubuntu"
一詞。
操做系統:Window10 + Centos6.5(虛擬機)
yum install nginx
systemtl start nginx.service
systemctl enable nginx.service
複製代碼
經過Xftp將vue項目文件上傳至雲服務器
使用Xshell鏈接雲服務器
主機就是阿里雲上建立的實例的公網ip
輸入登陸名和密碼,登陸名就是購買服務器時輸入的登陸名和密碼。
運行npm run build
命令,有一個dist文件夾,這就是vue項目打包後的文件。
nginx安裝配置
在Xshell
終端輸入命令yum install nginx
,當須要確認時輸入」y「
回車。
安裝完成後,輸入service nginx start
啓動nginx
服務。
經過命令nginx -t
查看nginx
所在的安裝目錄。
在命令行輸入命令cd/etc/nginx
切換到nginx
目錄下,再輸入cat nginx.conf
可查看當前nginx
配置文件。
輸入命令 wget https://nodejs.org/dist/v10.8.0/node-v10.8.0-linux-x64.tar.xz
回車,等待安裝。
輸入命令tar xvf node-v10.8.0-linux-x64.tar.xz
回車進行解壓操做。
stop
,prevent
,.enter
,.once
,.native
等,lazy
,number
,trim
等。script
,template
props
,子傳父,$emit
npm install
,npm run serve
webStorm
開發vue
在Plugins
安裝插件vue.js
2.6.0
版本中,Vue
爲具名插槽和做用域插槽引入了一個新的統一的語法 (即 <v-slot>
指令)。它取代了 slot
和 slot-scope
這兩個目前已被廢棄、還沒有移除,仍在文檔中的特性。v-slot
用法,分爲三類:默認插槽、具名插槽以及做用域插槽。做用域插槽,經過 slot-scope
屬性來接受子組件傳入的屬性集合
代碼:
// 子組件
<template>
<div>
<header>
<slot>默認值</slot>
</header>
</div>
</template>
複製代碼
任何沒有被包裹在帶有v-slot
的<template>
中的內容都會被視爲默認插槽的內容。當子組件只有默認插槽時,<v-slot>
標籤能夠直接用在組件上
// 父組件
<template>
<div>
<child>
內容1
<template>內容2</template>
內容3
</child>
<child v-slot="web">
插槽<br>
插槽<br>
</child>
</div>
</template>
複製代碼
v-slot
重複定義一樣的 name
後只會加載最後一個定義的插槽內容// 子組件
<template>
<div>
<main>
<slot name="main"></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
</template>
複製代碼
// 子組件
<template>
<div>
<footer>
<slot name="footer" :user="user" :testBtn="testBtn">
{{user.name}}
</slot>
</footer>
</div>
</template>
<script>
exportdefault {
name: 'child',
data () {
return {
user: {
title: 'web',
name: 'web'
}
};
},
methods:{
testBtn(){
alert('web');
}
}
};
</script>
複製代碼
Vue
如何直接調用Component
裏的方法
<template>
<div>
<b-component ref="BComponent"></b-component>
</div>
</template>
<script>
import BComponent from './BComponent'
export default {
name: 'A',
data () {
},
components: {
BComponent
},
methods: {
callACompoentFunction () {
this.$refs.BComponent.sayHi()
}
}
}
</script>
<style scoped>
</style>
複製代碼
<template>
<div></div>
</template>
<script>
export default {
name: 'B',
data () {
},
methods: {
sayHi () {
console.log('web!')
}
}
}
</script>
<style scoped>
</style>
複製代碼
歡迎加我微信Jeskson(xiaoda0423
),拉你進技術羣(掘金前端羣,達達前端技術社羣⑥),長期交流學習。