20200115pm

 20200115

 筆試

 輸入一堆人名,而後輸出格式化的名字好比:list([{name:'Bart'},{name:'Lisa'},{name:'Maggie'}]) return 'Bert,Lisa & Maggie';list([]) return ''

    function list(arr){

        if(Object.prototype.toString.call(arr) !== '\[object Array\]') return 'arr is not an Array';

        let newArr=\[\];

        arr.forEach(element=>{

            if(element.name){

                newArr.push(element.name)

            }else{

                console.log('arr is not contained name');

            }

        });

        let last=newArr.pop();

        let str=newArr.join(',');

        if(last===undefined) return '';

        if(newArr.length===0) return last;

        str+=' & '+last;

        return str;

    }

 輸入一個字符串,找出其中最長的不重複的子字符串,並返回子字符串長度。例如:字符長'abcabcbb',最長的不重複的子字符串是'abc',長度是3 寫一個函數,參數是一個字符串,返回值是其中最長的不重複的子字符串的長度

    function maxStrLength(str){

        let i=0,res=0,n=0;

        for(let j=0;j<str.length;j++){

            n=str.slice(i,j).indexOf(str\[j\]);

            if(n==-1){

                res=Math.max(res,j+1-i);

            }else{

                i+=n+1;

            }

        }

        return res;

    }

 行內元素有哪些?塊級元素有哪些?空(void)元素有哪些?

行內元素:a、b、span、img、input、strong、select、label、em、button、textarea

  
  

塊級元素:div、ul、li、dl、dt、dd、p、h1-h六、blockquote

  
  

空元素:即系沒有內容的HTML元素,例如:br、meta、hr、link、input、img

 css選擇符有哪些?優先級如何計算?

\- 選擇器類型:

    - ID  #id

    - class  .class

    - 標籤  p

    - 通用  \*

    - 屬性  \[type="text"\]

    - 僞類  :hover

    - 僞元素  ::first-line

    - 子選擇器、相鄰選擇器

  

\- 權重計算規則:

    - 第一等:表明內聯樣式,如: style=」」,權值爲1000。

    - 第二等:表明ID選擇器,如:#content,權值爲0100。

    - 第三等:表明類,僞類和屬性選擇器,如.content,權值爲0010。

    - 第四等:表明類型選擇器和僞元素選擇器,如div p,權值爲0001。

    - 通配符、子選擇器、相鄰選擇器等的。如\*、>、+,權值爲0000。

    - 繼承的樣式沒有權值。

 使用原生方式或熟悉的JS庫寫一個AJAX調用,請用JSON數據格式傳輸和返回

    function getXHR() { //html元素事件觸發的函數

        var myXMLHttpRequest = null;

        if (window.ActiveXObject) {

            myXMLHttpRequest = new ActiveXObject("Microsoft.XMLHTTP");

        } else {

            myXMLHttpRequest = new XMLHttpRequest();

        }

        var url = "xxx.php";

        var data = "key=val"; //val通常是從某個html元素中取出的value值

        myXMLHttpRequest.open("post", url, true);

        myXMLHttpRequest.setRequestHeader("Content-Type","application/x-www-form-urlencoded");

        myXMLHttpRequest.onreadystatechange = function(){

            if (myXMLHttpRequest.readyState == 4 && myXMLHttpRequest.status == 200) {

                var res = myXMLHttpRequest.responseText;

                var jsonObj = eval("("+res+")");

                //接下來就可使用jsonObj這個json對象取出其中的屬性值,作一些修改html元素value值等操做了。

            }        

        }

        myXMLHttpRequest.send(data);

    }

jQueryjavascript

 response.write("{ username : '"+username+"' , content : '"+content+"'}") 

 因爲服務器端返回的數據格式是JSON文檔,所以也須要對文檔的數據進行處理,可是JSON文檔比較XML文檔更容易解析。

 $.ajax({

    type:"POST",

    url:"Handler.ashx",

    dataType:json,

    data:{username:$("#name").val(),password:$("#pwd").val()},

    success:function(data){

      var username = data.username;

      var content = data.content;

      var txtHtml = "<div class='comment'><h6>"+      username+":</h6><p class='para'>"+content+"</p></div>";

      $("#result").html(txtHtml)

    }

 }

\`\`\`

  

#### 請用僞代碼描述一個排序算法

快速排序

\`\`\`

function quickSort(arr,left,right){

    let len=arr.length,

        partitionIndex,

        left=typeof left != 'number' ? 0 : left,

        right=typeof right != 'number' ? len-1 : right;

    if(left<right){

        partitionIndex=partition(arr,left,right);

        quickSort(arr,left,partitionIndex-1);

        quickSort(arr,partitionIndex+1,right);

    }

    return arr;

}

function partition(arr,left,right){

    let pivot=left,

        index=pivot+1;

    for(let i=index;i<=right;i++){

        if(arr\[i\]<arr\[pivot\]){

            swap(arr,i,index);

            index++;

        }

    }

    swap(arr,pivot,index-1);

    return index-1;

}

function swap(arr,i,j){

    let temp=arr\[i\];

    arr\[i\]=arr\[j\];

    arr\[j\]=temp;

}

 JavaScript建立對象的方式有哪幾種?

https://www.jianshu.com/p/1fb...php

{}

new Object()

使用字面量

工廠模式

構造函數模式(constructor)

原型模式(prototype)

構造函數+原型模式

\`\`\`

  

### 原生js

  

#### 請簡述一下js的原型和原型鏈

\`\`\`

什麼是原型鏈:只要是對象就有原型, 而且原型也是對象, 所以只要定義了一個對象, 那麼就能夠找到他的原型, 如此反覆, 就能夠構成一個對象的序列, 這個結構就被稱爲原型鏈

全部的實例有一個內部指針(prototype),指向它的原型對象,而且能夠訪問原型對象上的全部屬性和方法。

 js繼承有幾種方式?

6種css

方式一:藉助構造函數實現繼承

  

這裏使用的原理就是在Child裏面,把Parent的this指向改成是Child的this指向,從而實現繼承

  

function Parent(name){

    this.name=name;

    }

    Parent.prototype.saiHi=function(){

        console.log("hello")

    }

    function Child(name,age,gender){

        Parent.call(this,name)

        this.age=age;

        this.gender=gender;

    }

    let child=new Child("王磊",20,"男")

    console.log(child.name);// 王磊

    child.sayHi(); // Uncaught TypeError:child.sayHi is not a function

缺點:只能解決屬性的繼承,使用屬性的值不重複,可是父級類別的方法不能繼承

  

方式二:藉助原型鏈實現繼承

  

第二種方式就是把Child的原型改成是Parent的實例,從而實現繼承

  

     function Parent(name,gender){

            this.name=name;

            this.gender=gender;

            this.list=\[1,2,3\]

        }

        Parent.prototype.eat=function(){

            console.log("晚餐時間到")

        }

        function Child(age){

            this.age=age;

        }

        Child.prototype=new Parent("李白","男");

        var child=new Child(20);

        var child2=new Child(30);

        child.eat();

        console.log(child.list,child2.list);// \[1,2,3\] \[1,2,3\]

        child.list.push(4)

        console.log(child.list);// \[1,2,3,4\]        

        console.log(child2.list);// \[1,2,3,4\]

缺點:由於Child的原型對象都是New Parent,因此實例化出來的對象的屬性都是同樣的,並且Parent上面的引用類型只要有一個實例對象修改了,其餘也會跟着修改.由於他們原型對象都是共用的

  

方式三:組合型

  

方式三的話是結合了方式一和方式二來實現繼承

  

function Person(school){

            this.school=school;

        }

        Person.prototype.skill=function(){

            console.log("學習");

        }

        function Student(school,name,age,gender){

            Parent.call(this,school);

            this.name=name;

            this.age=age;

            this.gender=gender;

        }

        Student.prototype=Person.prototype;

        let student=new Student("廣鐵一中","王菲菲",14,"女");

        console.log(Student.prototype===Person.prototype)

        console.log(student.constructor)

缺點:父類的原型對象調用了兩次,沒有必要,並且student實例的構造函數是來自於Person

  

方式四:組合方式優化

  

function Parent(name,play){

            this.name=name;

            this.play=play;

        }

        function Child(name,play,age){

            Parent.call(this,name,play);

            this.age=age;

        }

        Child.prototype=Parent.prototype;

        let child=new Child("張三","玩",20);

        let child2=new Child("李四","吃",10)

        console.log(child,child2)

        console.log(child.prototype===child2.prototype); true

        console.log(child.constructor); // 構造函數指向的是Parent

缺點:child實例的構造函數來自於Parent

  

方式五: 組方式優化

  

只是這種方式的話,你必須得理解Object.create()方法的使用,他建立的對象是在原型上面的

  

function Parent(name,play){

            this.name=name;

            this.play=play;

        }

        function Child(name,play,age){

            Parent.call(this,name,play);

            this.age=age;

        }

        Child.prototype=Object.create(Parent.prototype);// 隔離了父類和子類的構造函數,父類的添加到了\_\_proto\_\_屬性上

        Child.prototype.constructor=Child

        let child=new Child("張三","玩",20);

        let child2=new Child("李四","吃",10)

        console.log(child.constructor)

 如何實現promise

完整版html

    const PENDING='pending';

    const FULFILLED='fulfilled';

    const REJECTED='rejected';

  

    function MyPromise(fn){

        const self=this;

        self.value=null;

        self.error=null;

        self.status=PENDING;

        self.onFulfilledCallbacks=\[\];

        self.onRejectedCallbacks=\[\];

  

        function resolve(value){

            if(value instanceof MyPromise){

                return value.then(resolve,reject);

            }

            if(self.status===PENDING){

                setTimeout(()=>{

                    self.status=FULFILLED;

                    self.value=value;

                    self.onFulfilledCallbacks.forEach((callback)=>callback(self.value));

                },0)

            }

        }

  

        function reject(error){

            if(self.status===PENDING){

                setTimeout(function(){

                    self.status=REJECTED;

                    self.error=error;

                    self.onRejectedCallbacks.forEach((callback)=>callback(self.error))

                },0)

            }

        }

        try{

            fn(resolve,reject);

        }catch(e){

            reject(e);

        }

    }

  

    function resolvePromise(bridgepromise,x,resolve,reject){

        if(bridgepromise===x){

            return reject(new TypeError('Circular reference'));

        }

  

        let called=false;

        if(x instanceof MyPromise){

            if(x.status===PENDING){

                x.then(y=>{

                    resolvePromise(bridgepromise,y,resolve,reject)

                },error=>{

                    reject(error);

                })

            }else{

                x.then(resolve,reject)

            }

        }else if(x!=null && ((typeof x === 'object') || (typeof x === 'function'))){

            try{

                let then=x.then;

                if(typeof then === 'function'){

                    then.call(x,y=>{

                        if(called) return;

                        called=true;

                        resolvePromise(bridgepromise,y,resolve,reject)

                    },error=>{

                        if(called) return;

                        called=true;

                        reject(error);

                    })

                }else{

                    resolve(x);

                }

            }catch(e){

                if(called) return;

                called=true;

                reject(e);

            }

        }else{

            resolve(x);

        }

    }

  

    MyPromise.prototype.then=function(onFulfilled,onRejected){

        const self=this;

        let bridgePromise;

        onFulfilled=typeof onFulfilled==='function'?onFulfilled:value=>value;

        onRejected=typeof onRejected==='function'?onRejected:error=>{throw error};

        if(self.status===FULFILLED){

            return bridgePromise=new MyPromise((resolve,reject)=>{

                setTimeout(()=>{

                    try{

                        let x=onFulfilled(self.value);

                        resolvePromise(bridgePromise,x,resolve,reject);

                    }catch(e){

                        reject(e);

                    }

                },0)

            })

        }

        if(self.status===REJECTED){

            return bridgePromise=new MyPromise((resolve,reject)=>{

                setTimeout(()=>{

                    try{

                        let x=onRejected(self.error);

                        resolvePromise(bridgePromise,x,resolve,reject);

                    }catch(e){

                        reject(e);

                    }

                },0)

            })

        }

        if(self.status===PENDING){

            return bridgePromise=new MyPromise((resolve,reject)=>{

                self.onFulfilledCallbacks.push((value)=>{

                    try{

                        let x=onFulfilled(value);

                        resolvePromise(bridgePromise,x,resolve,reject)

                    }catch(e){

                        reject(e);

                    }

                });

                self.onRejectedCallbacks.push((error)=>{

                    try{

                        let x=onRejected(error);

                        resolvePromise(bridgePromise,x,resolve,reject);

                    }catch(e){

                        reject(e);

                    }

                });

            });

        }

    }

    MyPromise.prototype.catch=function(onRejected){

        return this.then(null,onRejected);

    }

    MyPromise.deferred=function(){

        let defer={};

        defer.promise=new MyPromise((resolve,reject)=>{

            defer.resolve=resolve;

            defer.reject=reject;

        });

        return defer;

    }

    try{

        module.exports=MyPromise;

    }catch(e){}

簡版vue

    function myPromise(constructor){

        let self=this;

        self.status='pending';

        self.vlaue=undefined;

        self.reason=undefined;

        function resolve(value){

            if(self.status==='pending'){

                self.value=value;

                self.status='resolved';

            }

        }

        function reject(reason){

            if(self.status==='pending'){

                self.reason=reason;

                self.status='rejected';

            }

        }

        try{

            constructor(resolve,reject);

        }catch(e){

            reject(e);

        }

    }

    myPromise.prototype.then=function(onFullfilled,onRejected){

        let self=this;

        switch(self.status){

            case 'resolved':

                onFullfilled(self.value);

                break;

            case 'rejected':

                onRejected(self.reason);

                break;

            default:

        }

    }

 let和var的區別

\- const定義的變量不能夠修改,並且必須初始化

\- var定義的變量能夠修改,若是不初始化會輸出undefined,不會報錯。

\- let是塊級做用域,函數內部使用let定義後,對函數外部無影響。

 css

 水平垂直居中都有哪些方式?

\- 絕對定位水平垂直居中

<div color: rgb(212, 212, 212);">     width: 500px;

     height: 300px;

     margin: auto;

     top: 0;

     left: 0;

     bottom: 0;

     right: 0;

     background-color: green;">水平垂直居中</div>

  

\- 水平垂直居中

<div color: rgb(212, 212, 212);">     width:400px;

     height:200px;

     top: 50%;

     left: 50%;

     margin: -100px 0 0 -200px;

     background-color: red;">水平垂直居中</div>

  

\- 水平垂直居中

<div color: rgb(212, 212, 212);">     width:300px;

     height:200px;

     top: 50%;

     left: 50%;

     transform: translate(-50%, -50%);

     background-color: blue;">水平垂直居中</div>

  

\- flex 佈局居中

<div >

    <div >flex 佈局</div>

  </div>

 如何實現一個煙花爆炸的效果

<!doctype html>

<html>

<head>

<meta charset="utf-8">

<title>js煙花效果</title>

<script type="text/javascript">

document.onclick=function (ev)

{

    var oEvent=ev||event;

    var aDiv=\[\];

    var oDiv=null;

    var \_oDiv=document.createElement('div');

    var i=0;

    var x=oEvent.clientX;

    var y=oEvent.clientY;

    \_oDiv.style.position='absolute';

    \_oDiv.style.background='red';

    \_oDiv.style.width='3px';

    \_oDiv.style.height='30px';

    \_oDiv.style.left=oEvent.clientX+'px';

    \_oDiv.style.top=document.documentElement.clientHeight+'px';

    document.body.appendChild(\_oDiv);

    var t=setInterval(function (){

        if(\_oDiv.offsetTop<=y)

        {

            clearInterval(t);

            show();

            document.body.removeChild(\_oDiv);

        }

        \_oDiv.style.top=\_oDiv.offsetTop-30+'px';

    }, 30);

    function show()

    {

        var oDiv=null;

        for(i=0;i<100;i++)

        {

            oDiv=document.createElement('div');

            oDiv.style.width='3px';

            oDiv.style.height='3px';

            oDiv.style.background='#'+Math.ceil(Math.random()\*0xEFFFFF+0x0FFFFF).toString(16);

            oDiv.style.position='absolute';

            oDiv.style.left=x+'px';

            oDiv.style.top=y+'px';

            var a=Math.random()\*360;

            //oDiv.speedX=Math.random()\*40-20;

            //oDiv.speedY=Math.random()\*40-20;

            oDiv.speedX=Math.sin(a\*180/Math.PI)\*20\*Math.random();

            oDiv.speedY=Math.cos(a\*180/Math.PI)\*20\*Math.random();

            document.body.appendChild(oDiv);

            aDiv.push(oDiv);

        }

    }

    setInterval(doMove, 30);

    function doMove()

    {

        for(i=0;i<aDiv.length;i++)

        {

            aDiv\[i\].style.left=aDiv\[i\].offsetLeft+aDiv\[i\].speedX+'px';

            aDiv\[i\].style.top=aDiv\[i\].offsetTop+aDiv\[i\].speedY+'px';

            aDiv\[i\].speedY+=1;

            if(aDiv\[i\].offsetLeft<0 || aDiv\[i\].offsetLeft>document.documentElement.clientWidth || aDiv\[i\].offsetTop<0 || aDiv\[i\].offsetTop>document.documentElement.clientHeight)

            {

                document.body.removeChild(aDiv\[i\]);

                aDiv.splice(i, 1);

            }

        }

    }

};

</script>

</head>

<body >

</body>

</html>
<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <title>css3實現煙花特效</title>

    <style>

        \* {

            margin: 0;

            padding: 0;

        }

        html{

            width: 100%;

            height: 100%;

        }

        body{

            width: 100%;

            height: 100%;

        }

        #container{

            width: 100%;

            height: 100%;

            background-color: black;

            position: relative;

        }

        #fireworks{

            position: absolute;

            left: 50%;

            margin-left: -250px;

            bottom: 60%;

            margin-bottom: -180px;

            transform: scale(0);

            animation: fireworks 5s 3s;

        }

  

        @keyframes fireworks {

            0%{

                transform: scale(0);

            }

            80%{

                transform: scale(1);

            }

            100%{

                opacity: 0;

            }

        }

        #firecracker{

            position: absolute;

            left: 50%;

            bottom: 0%;

            margin-left: -4px;

            animation: firecracker 3s forwards;

        }

  

        @keyframes firecracker {

            0%{

                transform: scale(1);

                bottom: 0%;

            }

            100%{

                bottom: 60%;

                transform: scale(0);

            }

        }

    </style>

</head>

<body>

<div id="container">

    <div id="fireworks"><img src="imgs/fireworks.png" alt=""></div>

    <div id="firecracker"><img src="imgs/firecracker.png" alt="" width="8px"></div>

</div>

</body>

</html>

\`\`\`

  

### 框架

  

#### vue的生命週期都有哪些?

\`\`\`

Vue 實例從建立到銷燬的過程,就是生命週期。從開始建立、初始化數據、編譯模板、掛載Dom→渲染、更新→渲染、銷燬等一系列過程,稱之爲 Vue 的生命週期。

生命週期中有多個事件鉤子,以下:

\- beforeCreate(建立前) 在數據觀測和初始化事件還未開始

\- created(建立後) 完成數據觀測,屬性和方法的運算,初始化事件,$el屬性尚未顯示出來

\- beforeMount(載入前) 在掛載開始以前被調用,相關的render函數首次被調用。實例已完成如下的配置:編譯模板,把data裏面的數據和模板生成html。注意此時尚未掛載html到頁面上。

\- mounted(載入後) 在el 被新建立的 vm.$el 替換,並掛載到實例上去以後調用。實例已完成如下的配置:用上面編譯好的html內容替換el屬性指向的DOM對象。完成模板中的html渲染到html頁面中。此過程當中進行ajax交互。

\- beforeUpdate(更新前) 在數據更新以前調用,發生在虛擬DOM從新渲染和打補丁以前。能夠在該鉤子中進一步地更改狀態,不會觸發附加的重渲染過程。

\- updated(更新後) 在因爲數據更改致使的虛擬DOM從新渲染和打補丁以後調用。調用時,組件DOM已經更新,因此能夠執行依賴於DOM的操做。然而在大多數狀況下,應該避免在此期間更改狀態,由於這可能會致使更新無限循環。該鉤子在服務器端渲染期間不被調用。

\- beforeDestroy(銷燬前) 在實例銷燬以前調用。實例仍然徹底可用。

\- destroyed(銷燬後) 在實例銷燬以後調用。調用後,全部的事件監聽器會被移除,全部的子實例也會被銷燬。該鉤子在服務器端渲染期間不被調用。

 封裝組件須要考慮哪些內容?

開發通用組件是很基礎且重要的工做,通用組件必須具有高性能、低耦合的特性

  

1、數據從父組件傳入

  

爲了解耦,子組件自己就不能生成數據。即便生成了,也只能在組件內部運做,不能傳遞出去。

  

父對子傳參,就須要用到 props,可是通用組件的的應用場景比較複雜,對 props 傳遞的參數應該添加一些驗證規則

  

2、在父組件處理事件

  

在通用組件中,一般會須要有各類事件,

  

好比複選框的 change 事件,或者組件中某個按鈕的 click 事件

  

這些事件的處理方法應當儘可能放到父組件中,通用組件自己只做爲一箇中轉

  

3、記得留一個 slot

  

一個通用組件,每每不可以完美的適應全部應用場景

  

因此在封裝組件的時候,只須要完成組件 80% 的功能,剩下的 20% 讓父組件經過 solt 解決

  

4、不要依賴 Vuex

  

父子組件之間是經過 props 和 自定義事件 來傳參,非父子組件一般會採用 Vuex 傳參

  

可是 Vuex 的設計初衷是用來管理組件狀態,雖然能夠用來傳參,但並不推薦

  

由於 Vuex 相似於一個全局變量,會一直佔用內存

  

在寫入數據龐大的 state 的時候,就會產生內存泄露

  

5、合理運用 scoped 編寫 CSS

  

在編寫組件的時候,能夠在 <style> 標籤中添加 scoped,讓標籤中的樣式只對當前組件生效

  

可是一味的使用 scoped,確定會產生大量的重複代碼

  

因此在開發的時候,應該避免在組件中寫樣式

  

當全局樣式寫好以後,再針對每一個組件,經過 scoped 屬性添加組件樣式

 vue中數據傳遞都有哪些方式?

\- 父組件向子組件傳值 --Props傳遞數據

在父組件中使用兒子組件

<template>

  <div>

    父組件:{{money}}

    <Son1 :money="money"><Son1>

  </div>

</template>

<script>

  import Son1 from ''./Son1";

  export default{

    components:{

      Son1

    },

    data(){

      return { money: 100};

    }

  };

</script>

子組件接受數據

props:{

  value:{

    type:Number,

    default:1

  }

}

若是是數組

props:{

  value:{

    type:Array,

    default: ()=>\[\]

  }

}

  

\- 子組件通訊父組件 $emit使用

<template>

  <div>

    父組件:{{money}}

    <Son1 :money="money" @input="change"><Son1>

  </div>

</template>

<script>

  import Son1 from ''./Son1";

  export default{

    methods:{

     change(data){

       this.money = data

      } 

    },

    components:{

      Son1

    },

    data(){

      return { money: 100};

    }

  };

</script>

子組件觸發綁定本身身上的方法

<template>

  <div>

    子組件1:{{money}}

    <button @click="$emit('input',200)">修改父組件的值<Son1>

  </div>

</template>

<script>

  export default{

    props:{

     money:{

       type:Number

     }

    }

  };

</script>

  

\- $parent、$children(多層級傳遞)

<Grandson1 :value="value"></Grandson1>

<template>

  <div>

    孫子1:{{value}}

    <---調用父組件的input事件-->

    <button @click="$parent.$emit('input',200)">更改<Son1>

  </div>

</template>

<script>

  export default{

    props:{

     value:{

       type:Number

     }

    }

  };

</script>

  

\- $attrs、 $listeners:

$attrs批量向下傳入屬性:

<Son2 name="小明" age="18"></Son2>

<--能夠在son2組件中使用$attrs,能夠將屬性繼續向下傳遞-->

<div>

  兒子2:{{  $attrs.name }}

  <Grandson2  v-bind="$attrs"></Grandson2>

</div>

<tempalte>

  <div>孫子:{{$attrs}}</div>

</template>

$listeners批量向下傳入方法:

<Son2 name="小明" age="18" @click=「()=>{this.money  =500}」></Son2>

<--能夠在son2組件中使用$attrs,能夠將屬性繼續向下傳遞-->

<Grandson2  v-bind="$attrs" v-on="$listeners"></Grandson2>

<button @click="$listeners.click()">更改<Son1>

  

\- Provide&Inject

Provide 在父級中注入數據

provide(){

  return {parentMsg:'父親'};

}

Inject

在任意子組件中能夠注入父級數據

inject:\['parentMsg'\]//會將數據掛載在當前實例上

  

\- ref使用

<Grandson2  name="花花" ref="grand2"></Grandson2>

mounted(){

  console.log(this.$refs.grand2.name);

}

  

\- EventBus:用於跨組件通知

Vue.prototype.$bus = new Vue();

Son2組件和Grandson1互相通訊

mounted() {

  //父親組件註冊

  this.$bus.$on('my',data=>{

    console.log(data)

  })

}

mounted(){

  //侄子組件調用

  this.$nextTick(()=>{

    this.$bus.$emit('my',"我是小紅」);

  })

}

 vuex和eventBus的區別是什麼?

http://dongfanker.coding.me/2...java

爲何須要Bus

  

通常來講,都是利用父組件給子組件使用query或者params傳遞參數來實現子組件的數據顯示

不過,當出現子組件須要向父組件傳遞數據的時候,就須要用到bus,bus能夠本身建立,也能夠經過裝包來實現

  

直接建立Bus

  

在此處直接將Bus注入Vue對象中,成爲全局的組件。

在子組件中經過this.$root.Bus.$on(key,method),this.$root.Bus.$emit(key,data)來調用

將$on放在mounted,created這些鉤子函數中,相應的函數使用(e)=>{function}比較便捷

  

1

2

3

4

5

6

7

8

9

10

import Vue from 'vue'

const Bus = new Vue()

  

var app= new Vue({

    el:'#app',

   data:{

    Bus

    }  

  

})

使用vue-bus

  

使用yarn或者npm安裝vue-bus以後,在main.js中引用它

  

1

2

import VueBus from 'vue-bus';

Vue.use(VueBus);

因而調用直接能夠寫爲 this.$bus.on(key, this.method),this.$bus.emit(key, { text: …… }

其中第一個字符串參數表明key,每一個key都可以實現本身的獨立傳輸,this.method爲事先定義好的method,用於對傳入的數據進行處理

  

爲何使用vuex

  

當咱們的應用遇到多個組件共享狀態時,會須要:

  

多個組件依賴於同一狀態。

來自不一樣組件的行爲須要變動同一狀態。

通過個人觀察,vuex在其中的做用就是組件與狀態的捆綁剝離開來,使得組件狀態的改變依賴於某個行爲,這使得代碼變得易於調試。

Vuex採用集中式存儲管理應用的全部組件的狀態,這裏的關鍵在於集中式存儲管理。這意味着原本須要共享狀態的更新是須要組件之間通信的,而如今有了vuex,就組件就都和store通信了。

  

使用vuex

  

使用yarn或者npm安裝vuex以後,在main.js中引用它

  

1

2

3

4

5

6

7

import Vuex from 'vuex'

import store from './vuex/store'

Vue.use(Vuex)

new Vue({

  el: '#app',

  store

})

隨後建立vuex目錄,將store.js放在目錄下,定義state和mutation

  

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

import Vue from 'vue'

import Vuex from 'vuex'

  

Vue.use(Vuex)

  

const store = new Vuex.Store({

  state: {

    author: 'Wise Wrong'

  },

  mutations:{

      newAuthor(state,msg){

          state.author = msg

      }

  }

})

export default store

在使用的時候,不直接修改this.$store.state.author,而是使用this.$store.commit()來提交,可讓咱們更好的跟蹤每個狀態的變化,在大型項目中更爲適用
本站公眾號
   歡迎關注本站公眾號,獲取更多信息