自己整理的前端开发面试题

前端开发面试题

文章目录

JavaScript面试题

1-JavaScript数据类型

基本类型

ES5 の 5 つのタイプ: Null、未定義、ブール、数値、文字列、ES6 新: シンボルは一意の値を表します ES10 新: BigInt は任意の大きな整数を表します

参照型

オブジェクト オブジェクト、配列 配列、日付 date、関数 function、通常の RegExp

nullと未定義の違い

if ステートメントの同じ点で、null と unknown の両方が false に変換されます。両方とも等価演算子 == を使用して等しいことを示します。

違いは、未定義は未定義の null が空のオブジェクトを意味することです。

ES10 は、任意の大きな整数を表す BIgInt を追加します

bigint データ型の目的は、数値データ型よりも広い範囲の整数値を取得することです。

データ型ストレージとスタックメモリ

基本データ型: スタックメモリに直接保存され、占有スペースが小さく、頻繁に使用されるデータに属します。

参照データ型: スタックとヒープメモリに同時に保存され、大きなスペースを占有し、サイズは固定されていません

スタックとヒープの違いは何ですか

スタック: 先入れ先出し、後入れ先出しの性質を持つ連続ストレージ データ構造です。

ヒープ: 先入れ先出し方式のキュー優先順位を備えた非連続ツリー ストレージ データ構造です。

2-JavaScriptのデータ型判定、条件分岐

if ステートメントと論理演算

すべての基本型で false となるブール値は 6 つだけです。つまり、0、null、unknown、false、NaN、empty です。

論理演算子

&& ロジックと両側が true で、条件が true の場合は true を返し、そうでない場合は false を返します。

|| ロジック or の 2 つの側面のうちの 1 つが true で、条件の 1 つが true の場合は true を返し、両方が false の場合は false を返します。

論理否定。ブール値を否定します。

データ型判定

typeof は基本的なデータ型を判断するのには適していますが、参照データ型に遭遇した場合には機能しません。

		console.log(typeof 2); //number
        console.log(typeof 'str'); //string
        console.log(typeof null); //object
        console.log(typeof undefined); //undefined
        console.log(typeof []);//object 
        console.log(typeof function fn() {
    
    }); //function

instanceof は参照データ型のみを正しく判断できますが、基本データ型は判断できません。その内部操作メカニズムは、この型のプロトタイプがそのプロトタイプ チェーン内で見つかるかどうかを判断することです。

      console.log([] instanceof Array)//true
      console.log(function () {} instanceof Function)//true
      console.log({} instanceof Object)//true
      console.log(new Date() instanceof Date)//true

コンストラクターは基本データ型と参照データ型を扱えるように見えますが、コンストラクターが宣言され、そのプロトタイプが配列のプロトタイプを指している場合、この場合、コンストラクターも無力であるように見えます。

  		 // 以下全为true
        console.log('str'.constructor === String) 
        console.log(true.constructor === Boolean)
        console.log([].constructor === Array)
        console.log(function() {}.constructor === Function)
        console.log({}.constructor === Object)
        console.log((2).constructor === Number)

JavaScriptのデータ型変換

JavaScript の型変換には 3 つのケースがあります

1. 数値に変換し、number()、parseint()、paraseFloat() メソッドを呼び出します。

数値法

 		Number('1') //1
        Number(true) //1
        Number(false)//0
        Number('12m')//NaN
        Number({})//NaN
        Number(null)//0
        Number(undefined)//NaN

parseint メソッド

        parseInt('2') //2
        parseInt('2',10) // 2
        parseInt('2',2)  // NaN
        parseInt('a123')  // NaN  如果第一个字符不是数字或者符号就返回NaN
        parseInt('123a')  // 123

parsefloat メソッド

        parseFloat('123a')//123
        parseFloat('123a.01')//123
        parseFloat('123.01')//123.01
        parseFloat('123.01.1')//123.01

2. 暗黙的な変換

暗黙的な変換: + の 2 つの辺の一方が文字列で、もう一方が別の型の場合、もう一方の型が最初に文字列に変換され、次に文字列が連結されて文字列が返されます。

        let str = '123'
        let res = str - 1 //122
        str+1 // '1231'
        +str+1 // 124

3、文字列に変換

toString() メソッド null および未定義ではこのメソッドを呼び出すことはできません

 		Number(1).toString()//'1'
        [1,2].toString()//'1','2'
        true.toString()//'true'

string()メソッドは転送可能

  		String(123) //'123'
        String(true) //'true'
        String([]) //''
        String(null) //'null'
        String(undefined) //'undefined'
        String({}) //'[object Object]'

データ型比較オブジェクト.is、==、===

=== は厳密な判定に属し、2 つのタイプが同じかどうかを直接判定します

== は値が等しいことを意味します

Object.is() は、=== に基づいて NaN、-0、+0 を特別に処理し、-0 は +0 と等しくないが、NaN は NaN と等しいことを保証します。

        '1' == 1 // true
        '1' === 1 // false
        NaN == NaN //false
        +0 == -0 //true
        +0 === -0 // true
        Object.is(+0,-0) //false
        Object.is(NaN,NaN) //true

typeof null の結果は何ですか、またその理由は何ですか

結果はオブジェクトです

JavaScript の最初のバージョンでは、すべての値は 32 ビット単位で保存され、各単位には小さな型タグ (1 ~ 3 ビット) と、現在保存されている値の実際のデータが含まれていました。型ラベルは各セルの下位ビットに格納され、次の 5 つのデータ型があります。

        000: object   - 当前存储的数据指向一个对象。
          1: int      - 当前存储的数据是一个 31 位的有符号整数。
        010: double   - 当前存储的数据指向一个双精度的浮点数。
        100: string   - 当前存储的数据指向一个字符串。
        110: boolean  - 当前存储的数据是布尔值

        null的类型标签也是000,和Object的类型标签一样,所以会被判定为Object

3-JavaScript イベント

イベントとは(バブリングイベントとデフォルトイベント)

イベントキャプチャ、Netscape が提案したイベントフローはイベントキャプチャフローと呼ばれ、イベントが発生する頂点から外側から内側に向​​かって、目的の要素まで段階的に探索していきます。

IE が提案するイベント フローはイベント バブリングと呼ばれ、特定のターゲット ノード要素から内部から外部にトリガーされ、ルート ノードまで段階的に渡されます。

イベント委任。イベント プロキシとも呼ばれます。イベント委任では、イベント バブリングを使用します。つまり、子要素のイベントを親要素にバインドします。子要素がイベントのバブリングを妨げている場合、委任は実現できません。

イベントのバブリングを防止するには、event.stopPropagation() .stop 修飾子を使用します。addEventListener('click', 関数名, true/false) デフォルト値は false (つまり、イベント バブリングを使用します) true イベント キャプチャ

利点: パフォーマンスの向上、イベント バインディングの削減、およびメモリ フットプリントの削減


<body>
    <div class="yeye">
        <div class="baba">
            <div class="erzi"></div>
        </div>
    </div>
    <script>
        var yeye = document.querySelector('.yeye')
        var baba = document.querySelector('.baba')
        var erzi = document.querySelector('.erzi')
        erzi.onclick = function(e) {
            alert('儿子')
                // e.stopPropagation() //第一种
                // e.cancelBubble = true//第二种
        }
        baba.onclick = function() {
            alert('爸爸')
        }
        yeye.onclick = function() {
            alert('爷爷')
        }
    </script>
</body>

デフォルトイベントをブロックする

 		 <a href="http://www.baidu.com">跳转百度</a>
  
        let a = document.querySelector('a')
        a.onclick = function(e) {
            e.preventDefault() //第一种
            e.returnValue = false //第二种
            return false//第三种
        }

JavaScript のスコープとスコープ チェーン

スコープ、スコープとは変数が使用できる範囲のことで、主にグローバルスコープと関数スコープに分かれます。

グローバル スコープは Js の最も外側のスコープであり、どこからでもアクセスできます。

関数スコープは、関数を通じて js によって作成される独立したスコープであり、関数内でのみアクセスできます。関数はネストできるため、スコープもネストできます。

Es6 では、ブロックレベルのスコープが追加されました (if(){}、for(){} などの中括弧で囲まれています)

手ぶれ補正スロットリング

アンチシェイク: いわゆるアンチシェイクとは、イベントがトリガーされた後、関数は n 秒以内に 1 回だけ実行できることを意味します。イベントが n 秒以内に再度トリガーされた場合、関数の実行時間は再計算されます (簡単に理解できる)エレベーターの入場時、座っているとき、エレベーター内で人がエレベーターに入場しているとき(連続トリガー)、エレベーターのドアは閉まらず、一定時間内に誰も入場しないと閉まります(停止連続トリガー)

スロットリング: いわゆるスロットリングとは、イベントを継続的にトリガーするが、関数は n 秒に 1 回だけ実行することを指します。これを実装するには、タイムスタンプ バージョンとタイマー バージョンの 2 つの方法があります。

手ぶれ補正機能は、頻繁にトリガーすると、n 秒に 1 回だけ実行されます。

機能スロットルは、n 秒ごとに一定時間内にイベントをトリガーします。

マウスイベントmouseenterとmouseoverの違い

Mouseenter: マウスがバインドされたイベント リスニング要素ノードに入ると 1 回トリガーされ、マウスがバインドされた要素の外に出て再び入ると再びトリガーされます。ただし、マウスがバインドされた要素ノードに入り、一度トリガーされると、マウスは移動せず、マウスが移動してもトリガーされなくなります。

Mouseover: マウスがバインドされたイベント リスニング要素ノードに入ると一度トリガーされます。ターゲット要素に子要素が含まれている場合は、マウスが子要素からターゲット要素に移動したときにもトリガーされます。

マウスエンターはイベントバブリングをサポートしません。マウスオーバーはバブリングします。

4-JavaScript アプリケーションのデータ型オブジェクト

オブジェクトのメソッド

Object.is() 是一种判断两个值是否相同的方法。
语法:Object.is(value1, value2);
参数:value1:要比较的第一个值。value2:要比较的第二个值。
返回值:一个布尔表达式,指示两个参数是否具有相同的值。
 
Object.assign() 方法用于将所有可枚举的自身属性从一个或多个源对象复制到目标对象。
语法:Object.assign(target, ...sources)
参数:target:目标对象——应用源属性的对象,修改后返回。sources:源对象——包含你要应用的属性的对象。
返回值:修改后的目标对象。
 
 
Object.entries() ES8的Object.entries是把对象转成键值对数组, [key, value] 对的数组。
语法:Object.entries(obj)
参数:obj:要返回其自己的可枚举字符串键属性 [key, value] 对的对象。返回值:给定对象自己的可枚举字符串键属性 [key, value] 对的数组。
Object.fromEntries则相反,是把键值对数组转为对象
 
Object.values() 方法返回给定对象自己的可枚举属性值的数组,其顺序与 for...in 循环提供的顺序相同。
语法:Object.values(obj)
参数:obj:要返回其可枚举自身属性值的对象。返回值:包含给定对象自己的可枚举属性值的数组。
 
Object.prototype.hasOwnProperty()
hasOwnProperty() 方法返回一个布尔值,指示对象是否具有指定的属性作为它自己的属性。
如果指定的属性是对象的直接属性,则该方法返回 true — 即使值为 null 或未定义。如果该属性是继承的或根本没有声明,则返回 false。
语法:hasOwnProperty(prop)
参数:prop:要测试的属性的字符串名称或符号。
返回值:如果对象将指定的属性作为自己的属性,则返回true;否则为false。
 
Object.keys()
Object.keys() 方法用于返回给定对象自己的可枚举属性名称的数组,以与普通循环相同的顺序迭代。
语法:Object.keys(obj)
参数:obj:要返回可枚举自身属性的对象。
返回值:表示给定对象的所有可枚举属性的字符串数组。
 
Object.prototype.toString()
toString() 方法返回一个表示对象的字符串。当对象将被表示为文本值或以期望字符串的方式引用对象时,将自动调用此方法 id。默认情况下,toString() 方法由从 Object 继承的每个对象继承。
语法:toString()
返回值:表示对象的字符串。
 
Object.freeze()
Object.freeze() 方法冻结一个对象,这意味着它不能再被更改。冻结对象可防止向其添加新属性,防止删除现有属性,防止更改现有属性的可枚举性、可配置性或可写性,并防止更改现有属性的值。它还可以防止其原型被更改。
语法:Object.freeze(obj)
参数:obj:要冻结的对象。返回值:传递给函数的对象。
 
Object.create()方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__。 (请打开浏览器控制台以查看运行结果。)
语法:const me = Object.create(person);
参数:
proto:新创建对象的原型对象。
propertiesObject
可选。需要传入一个对象,该对象的属性类型参照Object.defineProperties()的第二个参数。如果该参数被指定且不为 undefined,该传入对象的自有可枚举属性(即其自身定义的属性,而不是其原型链上的枚举属性)将为新创建的对象添加指定的属性值和对应的属性描述符。
返回值
一个新对象,带着指定的原型对象和属性。

深いコピーと浅いコピー

ディープ コピーとシャロー コピーは、複雑なデータ タイプ用です。シャロー コピーは 1 つのレイヤーのみをコピーしますが、ディープ コピーはレイヤーごとのコピーです。

1 - 浅いコピー

  • 元のオブジェクトまたは元の配列の参照を新しいオブジェクトまたは新しい配列に直接コピーします。新しいオブジェクトは、オブジェクト自体をコピーするのではなく、元のオブジェクトへの参照にすぎません。古いオブジェクトと新しいオブジェクトはメモリを共有します。
  • 属性が基本データ型の場合はデータ型の値がコピーされ、属性が参照型の場合はメモリ アドレスがコピーされます。

2 - ディープコピー

  • 新しいオブジェクトまたは配列を作成し、元のオブジェクトの各プロパティの値をコピーし、
  • ディープ コピーとは、メモリからオブジェクトを完全にコピーし、ヒープ メモリから新しい領域を開いて新しいオブジェクトを格納し、元のオブジェクトに影響を与えずに新しいオブジェクトを変更することです。

3- 割り当て

  • 当我们把一个对象赋值给一个新的变量时 赋的是该对象在栈内存的内存地址,而不是堆内存的数据 也就是两个对象
	浅拷贝的实现方式:
   1、object.assign()
   2、lodash 里面的 _.clone 
   3、...扩展运算符
   4、 Array.prototype.concat 
   5、 Array.prototype.clice
 
    深拷贝的实现方式
    1、JSON.parse(JSON.stringify())
    2、递归操作
    3、cloneDeep
    4、Jquery.extend()   

5-JavaScript数组

数组方法

  1. sort():排序,如果下面参数的正反,控制,升序,降序,返回从新排序的原数组,有一个可选参数(可指定排序条件),没写默认按各个字符的Unicode位点进行排序

  2. splice():向数组指定的index处插入,返回的是被删除的数组元素的集合,第一个参数表示开始截取的索引位,第二个参数表示截取的长度,返回截取的 数组,原数组改变;三个或者更多参数,第三个及以后的参数表示要从截取位插入的值,会改变原数组

    		let arr = [1, 2, 3, 4, 5]
         	//参数2为从下标为2开始,第二个参数为截取几个   
            let cutArr = arr.splice(2, 2, '我是被插入的数据')
            console.log(arr)//[1, 2, '我是被插入的数据', 5]
            console.log(cutArr)//[3, 4]
    
  3. pop():从数组尾部删除一个数据,返回被删掉的元素,会改变原数组

  4. push():从数组尾部添加数据,返回新的数组长度,会改变原数组

  5. shift():从数组头部删除一个元素,返回被删掉的元素,会改变原数组

  6. unshift():从数组头部添加数据,返回新的数组长度,会改变原数组

  7. reverse():反转数组,不会改变原数组

  8. concat():数组合并

  9. slice():截取数组,返回新截取的数组,不会改变原数组

     		 let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]
            let newArr = arr.slice(1, 3) //[2,3] 从第一位开始,但不包括第一位,从第三位结束
            console.log(newArr)
    
  10. join():讲数组分割为字符串,返回值为字符串和添加的内容,只能分割一层,不会改变原数组

    		let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]
            let res = arr.join('-')
            console.log(res)//1-2-3-4-5-6-7-8-9
    
  11. filter():对数组中的每一运行给定的函数,会返回满足该函数的项组成的数组。过滤

    		let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]
            let res = arr.filter(i => i > 4)
            console.log(res) //[5, 6, 7, 8, 9]
    
  12. every():当数组中每一个元素在callback上被返回true时就返回true

    		let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]
            let res = arr.every(i => i > 0)
            console.log(res) //true
    
  13. some():当数组中有一个元素在callback上被返回true时就返回true。

     		let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]
            let res = arr.some(i => i > 3)
            console.log(res) //true
    
  14. reduce( ):回调函数中有4个参数。prev(之前计算过的值),next(之前计算过的下一个的值),index,arr。把数组列表计算成一个

  15. isArray():判断是否为数组

  16. IndexOf 方法可返回某个指定的字符串值在字符串中首次出现的位置,如果没有找到匹配的字符串则返回 -1

       		let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]
            let res = arr.indexOf(4)
            let res1 = arr.indexOf(21)
            console.log(res) //3
            console.log(res1) //-1
    
  17. lastIndexOf 它是从最后一个值向前查找的 找索如果找到了就会返回当前的一个下标,若果没找到就会反回-1

  18. Array.of(),填充单个值

  19. find():查找这一组数 符合条件的第一个数 给他返回出来

  20. forEach():遍历原数组

  21. map():

6-JavaScript字符串

字符串方法

  1. chartAt( ):返回在指定位置的字符;

  2. concat( ):返回新的字符串**,将一个或多个字符串与原字符串连接合并

  3. indexOf( ):检索字符串,返回第一次出现的索引,没有出现则为-1

  4. lastIndexOf(searchValue[ fromIndex]) 返回从字符串尾部开始第一次出现的索引,没有则-1,fromIndex的值相对于从尾部开始的索引

  5. split( ):返回一个以指定分隔符出现位置分隔而成的一个数组,数组元素不包含分隔符

    		let str = '李-育-狗-是-个-狗'
            let res = str.split('-', 6)
            console.log(res)//[ '李', '育', '狗', '是', '个', '狗' ]
    
  6. substr( ):从起始索引号提取字符串中指定数目的字符

    		let str = 'hello'
            console.log(str.substr(1, 3))//ell
    
  7. substring( ):提取字符串中两个指定的索引号之间的字符

    		let str = 'hello'
            console.log(str.substring(1, 3)) //el
    
  8. toLowerCase( ):字符串转小写;

  9. toUpperCase( ):字符串转大写

  10. valueOf( ):返回某个字符串对象的原始值

  11. trim( ):删除字符串两边的空格

  12. trimeState 取出开始的空格

  13. trimeEnd 去除末尾空格

  14. includes(searchString[, position])返回boolean,判断一个字符串是否包含在另一个字符串中,从postition索引开始搜寻,默认0

     		let str = '张三李四王五'
            alert(str.includes('李四'))//true
    
  15. slice( ):提取字符串片段,并在新的字符串中返回被提取的部分

            let str = '张三李四王五'
            console.log(str.slice(2, 6)) //李四王五,从第二位截到第六位 但是不包含第二位
    
  16. search(regexp)返回首次匹配到的索引,没有则-1,执行正则表达式和 String 对象之间的一个搜索匹配

  17. toString()返回一个表示调用对象的字符串,该方法返回指定对象的字符串形式

  18. replace() 把指定的字符串替换成为别的字符

7-JavaScript函数

函数声明的几种方式

        函数声明
        function 函数名(参数1,参数2,...){   //要执行的语句 } 
        函数表达式
        var func2=function(b){}//函数表达式
        var func3=function func4(c){}//命名式函数表达式
        var func5=(function(n1,n2){})();//立即执行的函数表达式
        return function(){ };//作为返回值的函数表达式
        Function构造器
        var 变量名 = new Function("参数1","参数2",...,"参数n","函数体");  
        立即执行函数
        var func5=(function(n1,n2){})();//立即执行的函数表达式 ()()

函数声明与函数表达式的区别

関数宣言は、その関数を (コードを記述するときにコード ブロックの最後に関数を記述した場合でも) 前面に持ち上げて、グローバル関数にします。

関数宣言では関数名を指定する必要がありますが、関数式を匿名関数として使用する必要はありません。

これは質問を指します

グローバル環境では窓を指します。

通常の関数呼び出しではウィンドウを指し、厳密モードでは未定義の自己実行関数を指し、ウィンドウを指し、タイマーはウィンドウを指します。

オブジェクト内でこれを呼び出すと、関数を呼び出したオブジェクトを指します。

コンストラクターは、インスタンス化されたオブジェクトを指すために new とともに使用されます。

アロー関数は独自の this を持たず、外側の層の最初の通常関数の this を継承します。

呼び出し、適用、バインド

これらはすべて this が指すものを変更するために使用され、3 つのパラメータのうちの最初のパラメータは this が指すオブジェクトです。

call と apply の違いは、call のパラメータは直接入力されるパラメータのリストであり、apply は配列であることです。

bind が関数を返すことを除いて、そのパラメータは call と同じですが、実行前に呼び出す必要があります。bind によって返される関数はコンストラクタとして使用できません。

閉鎖

クロージャの概念、他の関数内の変数を読み取ることができる関数

クロージャの短所: クロージャは関数内の変数をメモリに格納するため、メモリの消費量が多く、クロージャを悪用することはできません。そうしないと、Web ページでパフォーマンスの問題が発生し、IE でメモリ リークが発生する可能性があります。解決策は、関数を終了する前に、未使用のローカル変数をすべて削除することです。

8-JavaScriptのスコープ、メカニズム

ガベージコレクションメカニズムとメモリメカニズム

ガベージ コレクション: ガベージ コレクション メカニズムは自動メモリ管理メカニズムでもあり、ガベージ コレクタは使用されなくなった変数を定期的に見つけてメモリを解放します。

メモリ リーク: 使用されなくなった変数によって占有されているメモリがクリアされないと、クロージャやタイム タイマー リークなどのメモリ リークが発生します。

範囲

スコープとは変数が使用できる範囲のことで、主にグローバルスコープと関数スコープに分かれます。

グローバルスコープはJsの最も外側のスコープです

関数スコープは関数を通じてjsによって作成される独立したスコープです関数はネストできるため、スコープもネストできます

Es6 では、ブロックレベルのスコープが追加されました (if(){}、for(){} などの中括弧で囲まれています)

自由変数

現在のスコープ外の変数は自由変数です。変数が現在のスコープで定義されていないが使用されている場合、変数は上位スコープに移動し、見つかるまでレイヤーごとに検索されます。グローバル スコープでこの変数が見つからない場合は、変数が見つかりません。エラーが報告されます。この自由な変数検索プロセスがスコープ チェーンです。

JavaScript の動作メカニズムに関する簡単な説明

シングルスレッド: JavaScript 言語の主な機能はシングルスレッドです。つまり、同時に実行できる処理は 1 つだけです。

JSイベントループと実行順序

js コードの実行には多くのタスクがあり、これらのタスクは 2 つのカテゴリに分類されます。

  • 同期タスク
  • 非同期タスク
  • タスクはさらにマイクロタスクとマクロタスクに細分化でき、JS エンジンはマイクロタスクの実行を優先します。

マイクロタスクには、Promise コールバック、ノード内の process.nextTick が含まれます

マクロ タスクには、スクリプトの実行、setTimeout、setInterval などが含まれます。

実行の順序

  1. まず、js は単一のスレッドで実行され、コードが実行されると、さまざまな関数の実行コンテキストが実行スタックにプッシュされ、コードが順序正しく実行されるようになります。

  2. 同期コードの実行中に非同期イベントが発生すると、JS エンジンは返される結果を待たずにイベントを一時停止し、実行スタック内の他のタスクの実行を継続します。

  3. 同期イベントの実行完了後、非同期イベントに対応するコールバックは、現在の実行スタックとは別のタスクキューに追加され、実行を待ちます。

  4. タスクキューはマクロタスクキューとマイクロタスクキューに分けられ、現在の実行スタックのイベントが実行されると、jsエンジンはまずマイクロタスクキューに実行可能なタスクがあるかどうかを判断します。実行のためにスタックにプッシュされます。

  5. マイクロタスクペアのタスクがすべて実行されると、マクロタスクペアのタスクが判定されます。

8-BOM ブラウザ オブジェクト モデル

JavaScript 操作 BOM

ウィンドウ:alert()、prompt()、confirm()、setInterval()、clearInterval()、setTimeout()、clearTimeout();

window.location.href = 'ジャンプしたいページ'; 2. window.open('ジャンプしたいページ'); 3. window.history.back(-1): 前のページに戻ります4 , window.history.go(-1/1): 前または次のページに戻ります 5, 5,history.go("baidu.com");

Math オブジェクトのメンバー

  • Math.PI パイ

  • Math.floor() は切り捨てます

  • Math.ceil() 切り上げ

  • Math.round() 最も近い整数に丸めたバージョン

  • Math.abs() 絶対値

  • Math.max()/Math.min() 最大値と最小値を求める

            console.log(Math.max(2, 3, 5)) //5
    
  • Math.random() 範囲 [0,1) のランダムな値を取得します。

setTimeout と setInterval の違いとメカニズム

setTimeout() と setInterval() は、遅延やタイミング タスクを処理するためによく使用されます。

setTimeout() メソッドは、指定されたミリ秒数が経過した後に関数を呼び出すか式を計算するために使用され、一度実行されます。

setInterval() は、clearInterval によってクリアされるまで、指定されたミリ秒数ごとに関数または式を呼び出すことができます。

Cookie、sessionStorage、localStorage の違い

Cookie: サイズが 4K 以下の小さなテキスト データで、通常はサーバーによって生成され、有効期限を設定できます。時間が設定されていない場合、ブラウザを閉じると Cookie は無効になります。 http リクエストが行われ、ヘッダーに Cookie が含まれます

localStorage: 5M 以上、永続的に有効で、手動または JS コードによって永続的にクリアされない限り、ウィンドウまたはブラウザを閉じると常に保存されるため、永続データとして使用され、サーバーとの通信には参加しません。

sessionStorage は、ページまたはブラウザを閉じるとクリアされます。保存されるデータのサイズは通常 5MB で、クライアント (つまりブラウザ) にのみ保存され、サーバーとの通信には関与しません。

9-ES6 面接の質問の一部

ES6の新機能

  1. ブロックレベルのスコープを追加しました (let const)

  2. クラス (クラス) を定義するための糖衣構文を提供します。

  3. 新しい基本データ型 (シンボル) を追加しました。

  4. 新しい変数の構造化代入

  5. アロー機能を追加

  6. isArray / from / of メソッドなどのいくつかの API を追加し、配列インスタンス用の events()、keys()、values() などのメソッドを追加しました。

  7. オブジェクトと配列の新しいスプレッド演算子

  8. モジュール性の追加

  9. セットとマップのデータ構造を追加しました

  10. プロキシ インスタンスを生成するためのプロキシ コンストラクターを追加しました

  11. 新しいジェネレーター (Generator) とトラバーサー (イテレーター)

requireとimportの違いと使い方

import は ES6 の文法標準であり、モジュールのロードにも使用されます。import 関数は JavaScript ファイルを読み取って実行し、変更されたファイルのエクスポート コマンドによって出力されたコードを返します。エクスポートとエクスポート デフォルトの両方で定数をエクスポートできます。関数、ファイル、モジュール、およびエクスポートは複数存在できますが、エクスポートのデフォルトは 1 つだけです

require はモジュールを定義します: module 変数は現在のモジュールを表し、exports 属性は外部インターフェイスです。モジュールは、exports を通じてモジュールからエクスポートでき、他のファイルはモジュールをロードして実際に modules.exports 変数を読み取ります。数量、関数、オブジェクトなどです。ノードでは、exports を使用してエクスポートする場合、システムはそれを module.exports に変換するのに役立ちますが、エクスポートではエクスポート名を定義する必要があります。

2つの違い

require は commonJS 仕様のモジュール構文であり、 import は ECMAScript6 仕様のモジュール構文です

require は実行時にロードされ、import はコンパイル時にロードされます。

require はコード内のどこにでも記述できますが、import はファイルの先頭にのみ記述でき、条件文や関数スコープでは使用できません。

modules.exports を介して require によってエクスポートされた値は変更できませんが、import によってエクスポートされた値は変更できます。

require は modules.exports を通じてエクスポート オブジェクトをエクスポートし、 import は指定された出力コードを export を通じてエクスポートします。

モジュールの属性は require が実行されている場合にのみ導入され、すべてのパフォーマンスは低くなりますが、インポート コンパイル中に導入されたモジュール属性のパフォーマンスはわずかに高くなります。

アロー関数

  1. アロー関数は匿名関数であり、コンストラクターとして使用できず、新しい関数も使用できません。
  2. アロー関数は引数をバインドせず、代わりに残りのパラメータを使用して解決します
  3. this の点が異なり、アロー関数の this は定義時に外層の最初の通常関数の this を継承します。
  4. アロー関数にはプロトタイプがなく、すべてのアロー関数には this がありません。
  5. アロー関数はジェネレーター関数として使用できません。また、yield キーワードは使用できません。
  6. アロー関数は関数を省略します。 => を使用します。リターンを省略することもできます。
  7. アロー関数は、call()、apply()、bind() を通じてこの方向を変更できません。

var let const と使用シナリオの違いを簡単に説明します

だった

var で宣言された変数には変数昇格があります。つまり、変数は宣言前に呼び出すことができ、値は未定義です。

変数は複数回宣言でき、後者は前者をオーバーライドします。

関数内で変数を宣言するには、var を使用します。変数はローカル スコープであり、関数内および関数外でのみグローバル変数となります。

させて

変数ホイスティングは存在しません

let はブロックレベルのスコープで有効であり、スコープは中かっこです

let は同じスコープ内での繰り返しの宣言を許可しません

定数

読み取り専用の定数を宣言します。宣言後の値は変更できませんが、オブジェクトやデータなどの参照型の場合、メモリアドレスの変更はできず、内部の値の変更は可能です。

他はletと同じ

知らせ

const を使用できる場合は const を使用し、ほとんどの場合は let を使用し、var の使用は避けてください。const > let > var const ステートメントの利点は、1 つはコードを読む人に変数を変更できないことを知らせること、もう 1 つはコード変更プロセス中に変数が誤って変更されてエラーが発生するのを防ぐことです。バグの発生を減らす

マップとforEachの違い

同じ点は、配列内の各項目をループし、3 つのパラメーター (item、index、arr) をサポートすることです。

forEach は空の配列に対してコールバック関数を呼び出しません。

また、map メソッドは空の配列をチェックしません。

違い

Map メソッドによって返される新しい配列。配列内の要素は元の配列の処理された値であり、元の配列は変更されません。

forEach メソッドは、配列の各要素を呼び出して要素をコールバック関数に渡すために使用されます。戻り値はありません。戻り値は未定義です。

約束の定義

  1. Promise は非同期プログラミングのソリューションです。主に非同期コンピューティングに使用されます。チェーン呼び出しをサポートし、コールバック地獄の問題を解決できます。all、reject、resolve、race などのメソッドを独自に備えています。then と catch があります。プロトタイプのメソッド
  2. 非同期操作をキューに入れ、希望の順序で実行し、期待した結果を返すことができます。
  3. Promise には、保留中 (保留中) の初期状態、実行済み (実装) 操作の成功、拒否 (否定) 操作失敗の 3 つの状態があります。
  4. Promise オブジェクトの状態は、保留中から履行済み、または保留中から拒否へ変化します。状態が固定化された場合、これら 2 つの状態のみが変化しません。
  5. コールバック関数を設定しない場合、Promise内でスローされたエラーは外部には反映されませんが、thenとcatchを書くとthenまたはcatchの第2パラメータでキャッチされます。

では、Promise がチェーンコールをサポートできる理由

その後、promise は新しい Promise オブジェクトを返します。これにより、その当事者がチェーン呼び出しを行うことができるようになります。

非同期と待機の原則

  • async と await は同期書き込みメソッドですが、非同期操作であるため、この 2 つは一緒に使用する必要があります。

  • 関数の前の async キーワードは、内部に非同期操作があることを示します。関数が呼び出されると、Promise オブジェクトが返されます。

  • await は式を形成するために使用される演算子です。

  • await は、Promise の実行結果を取得できます。await は async と併用する必要があります。async と await はブロックする非同期メソッドです。

  • await の後に Promise オブジェクトが続かない場合、対応する値が直接返されます。これは async 関数でのみ使用でき、通常の関数が直接使用されるとエラーが報告されます。

  • await ステートメントの後の Promise オブジェクトが拒否されると、非同期関数全体が中断され、後続のプログラムは実行を続行できなくなります。

代入の構造化

ES6 では、配列やオブジェクトから値を抽出し、特定のパターンに従って変数に値を割り当てることができます。これは、分割代入と呼ばれます。

一般的に使用されるいくつかの方法は、

  1. デフォルト
  2. 交換変数
  3. 残りの配列を変数に代入する

element-Ui は、オンデマンドで導入される場合、構造化代入を使用します。

for...in iteration と for...of はどう違いますか?

  1. オブジェクトのプロパティをループする場合は for...in を使用し、配列を走査する場合は for...of を使用することをお勧めします。

            let arr = [1, 2, 3, 4, 5]
            let obj = {
                name: '张三',
                age: 20
            }
            for (k of arr) {
                console.log(k) //1,2,3,4,5
            }
    		for (i in arr) {
                console.log(i) //0,1,2,3,4,
            }
            for (v in obj) {
                console.log(v) //name,age
            }
    
  2. for in は配列のインデックスとして便利ですが、for of は配列要素の値を走査します。

  3. for...of は通常のオブジェクトをループできません。Object.keys() と組み合わせて使用​​する必要があります。

  4. for…in の便宜上の順序は数値が先であり、シンボル属性をパブリックに列挙することはできません。

  5. オブジェクトを走査するという観点から見ると、for...in はオブジェクトのキーを走査しますが、for...of は直接エラーを報告します。

発生器

  • Generator ジェネレーターも ES6 によって提供される非同期プログラミング ソリューションであり、その文法的な動作は従来の関数 function *(){} とはまったく異なります。

  • Generator 関数は、複数の内部状態をカプセル化するステート マシンであり、ステート マシンに加えて、トラバーサー オブジェクト生成関数でもあります。

  • ジェネレーターはセグメントで実行され、yield (再び) を一時停止して、次のメソッドを開始できます。各戻り値は、yield の後の式の結果であるため、Generator 関数は非同期タスクの同期に非常に適しています。

  • ジェネレーターは非同期になるように設計されておらず、他の機能 (オブジェクトの反復、出力の制御、Interator インターフェースのデプロイなど) を備えています。

  • Generator 関数は Iterator オブジェクトを返すため、for...of を介してそれをトラバースすることもできます。ネイティブ オブジェクトにはトラバーサル インターフェイスがありません。Generator 関数を通じてこのインターフェイスをそれに追加すると、for...of を使用できます。横断する

Promise、Generator、比較のための async/await

  • Promise と async/await の両方を使用して非同期操作を処理します
  • ジェネレーターは非同期用に設計されておらず、他の機能 (オブジェクトの反復、制御出力、デプロイメント インターフェイス) を備えています。
  • ジェネレーターと比較すると、promise は async/await よりも複雑で読みにくくなります。
  • async は本質的にジェネレーターの糖衣構文です
  • Async は使用方法がより簡潔であり、同期形式で非同期コードを記述することが非同期プログラミングの究極のソリューションです。

インスタンスを生成するコンストラクターの実行プロセス: オブジェクト指向プログラミングを使用する場合、new キーワードは何をしますか?

  1. 新しいオブジェクトオブジェクトを作成しました
  2. 新しく作成された Object オブジェクトを指すようにコンストラクターのポインターを変更し、コンストラクターを実行します。
  3. proto属性が Object オブジェクトに追加され、コンストラクターのプロトタイプ属性を指します。
  4. この Object オブジェクトを返します

set和map数据结构有哪些常用的属性和方法?

set数据的特点是数据是唯一的

const set1 = new Set()
 
增加元素 使用 add
set2.add(4)
 
是否含有某个元素 使用 has
console.log(set2.has(2)) 
     
查看长度 使用 size
console.log(set2.size) 
 
删除元素 使用 delete
set2.delete(2)
 
size: 返回Set实例的成员总数。
add(value):添加某个值,返回 Set 结构本身。
delete(value):删除某个值。
clear():清除所有成员,没有返回值。

Set的不重复性

传入的数组中有重复项,会自动去重
const set2 = new Set([1, 2, '123', 3, 3, '123'])
 
Set`的不重复性中,要注意`引用数据类型和NaN
两个对象都是不用的指针,所以没法去重
const set1 = new Set([1, {name: '孙志豪'}, 2, {name: '孙志豪'}])
 
如果是两个对象是同一指针,则能去重
const obj = {name: '我们一样'}
const set2 = new Set([1, obj, 2, obj])
 
NaN !== NaN,NaN是自身不等于自身的,但是在Set中他还是会被去重
const set = new Set([1, NaN, 1, NaN])

map数据结构

Map对比object最大的好处就是,key不受类型限制

 
定义map
const map1 = new Map()
 
新增键值对 使用 set(key, value)
map1.set(true, 1)
 
判断map是否含有某个key 使用 has(key)
console.log(map1.has('哈哈')) 
 
获取map中某个key对应的value
console.log(map1.get(true)) 
 
删除map中某个键值对 使用 delete(key)
map1.delete('哈哈')
 
 
定义map,也可传入键值对数组集合
const map2 = new Map([[true, 1], [1, 2], ['哈哈', '嘻嘻嘻']])
console.log(map2) // Map(3) { true => 1, 1 => 2, '哈哈' => '嘻嘻嘻' }

proxy的理解

Proxy 对象用于创建一个对象的代理,从而实现基本操作的拦截和自定义(如属性查找、赋值、枚举、函数调用等)。

Proxy 可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。Proxy 这个词的原意是代理,用在这里表示由它来“代理”某些操作,可以译为“代理器”。

s6中新的数据类型symbol

symbol 是es6 加入的,是一个基本数据类型,它代表的是一个独一无二的值,SYMBOL 值是由 SYMBOL函数生成

symbol 不能用来四则运算,否则会报错,只能用显示的方式转为字符串

如果拿 symbol 对比的话 就是会返回 false

symbol 他是一个原始类型的值就,不可以使用 new 关键字,symbol不是对象 没有迭代器的接口 不能去添加属性值,他是类似于字符串的一种类型

symbol 参数里的 a 表示一种修饰符 对当前创建的 symbol 的一种修饰,作为区分 ,否则会混淆

iterator == iteration (遍历器的概念)

遍历器(Iterator)就是这样一种机制。它是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署 Iterator 接口,就可以完成遍历操作

Iterator 的作用有三个:一是为各种数据结构,提供一个统一的、简便的访问接口;二是使得数据结构的成员能够按某种次序排列;三是 ES6 创造了一种新的遍历命令for…of循环,Iterator 接口主要供for…of消费。

其实iteration == iterator 有三个作用:

  1. 为各种数据结构,提供一个统一的、简便的访问接口;

  2. 使得数据结构的成员能够按某种次序排列;

  3. 主要供for…of消费

Object.assign

object.assign可以实现对象的合并,它的语法是这样的: Object.assign(target, ...sources)

Object.assign会将source里面的可枚举属性复制到target。如果和target的已有属性重名,则会覆盖。同时后续的source会覆盖前面的source的同名属性

Object.assign复制的是属性值,如果属性值是一个引用类型,那么复制的其实是引用地址,就会存在引用共享的问题

Object.assign可以实现浅拷贝

Array.from()

Array.from()方法就是将一个类数组对象或者可遍历对象转换成一个真正的数组。

那么什么是类数组对象呢?所谓类数组对象,最基本的要求就是具有length属性的对象

        let arrayLike = {
            0: 'tom', 
            1: '65',
            2: '男',
            3: ['jane','john','Mary'],
            'length': 4
        }
        let arr = Array.from(arrayLike)
        console.log(arr) // ['tom','65','男',['jane','john','Mary']]

如果将上面代码中 length 属性去掉呢?实践证明,答案会是一个长度为0的空数组

这里将代码再改一下,就是具有 length 属性,但是对象的属性名不再是数字类型的,而是其他字符串型的,代码如下

        let arrayLike = {
            'name': 'tom', 
            'age': '65',
            'sex': '男',
            'friends': ['jane','john','Mary'],
            length: 4
        }
        let arr = Array.from(arrayLike)
        console.log(arr)  // [ undefined, undefined, undefined, undefined ]

会发现结果是长度为4,元素均为 undefined 的数组

由此可见,要将一个类数组对象转换为一个真正的数组,必须具备以下条件:

1、该类数组对象必须具有 length 属性,用于指定数组的长度。如果没有 length 属性,那么转换后的数组是一个空数组。

2、该类数组对象的属性名必须为数值型或字符串型的数字

谈谈你对模块化开发的理解

一个模块是实现一个特定功能的一组方法。在最开始的时候,js 只实现一些简单的功能,所以并没有模块的概念 ,但随着程序越来越复杂,代码的模块化开发变得越来越重要。

由于函数具有独立作用域的特点,最原始的写法是使用函数来作为模块,几个函数作为一个模块,但是这种方式容易造成全局变量的污 染,并且模块间没有联系

后面提出了对象写法,通过将函数作为一个对象的方法来实现**,**这样解决了直接使用函数作为模块的一些缺点,但是这种办法会暴露所 有的所有的模块成员,外部代码可以修改内部属性的值。

jsのいくつかのモジュール仕様

現在、js には 4 つの成熟したモジュール読み込みスキームがあります。

  • 1 つ目は CommonJS ソリューションです。これは、require を通じてモジュールをインポートし、module.exports を通じてモジュールの出力インターフェイスを定義します。このモジュール読み込みソリューションはサーバー側のソリューションです。同期的にモジュールを導入します。サーバー側のファイルはローカル ディスクに保存されるため、読み込みが非常に高速です。同期読み込みでも問題ありません。やり方。ただし、ブラウザ側の場合、モジュールのロードにはネットワーク リクエストが使用されるため、非同期ロードを使用する方が適切です。
  • 2 つ目は AMD スキームです。このスキームは、モジュールのロードに非同期ロードを使用します。モジュールのロードは、後続のステートメントの実行には影響しません。このモジュールに依存するすべてのステートメントはコールバック関数で定義され、コールバックはコールバック関数の後に実行されます。読み込みが完了しました。require.js は AMD 仕様を実装します。
  • 3 番目は CMD ソリューションです。このソリューションと AMD ソリューションは両方とも、非同期モジュールの読み込みの問題を解決するように設計されています。sea.js は CMD 仕様を実装しています。require.js との違いは、モジュール定義時の依存関係の処理の違いと、依存モジュールの実行タイミングの処理の違いにあります。
  • 4 番目のソリューションは ES6 によって提案されたソリューションで、インポートとエクスポートを使用してモジュールをインポートおよびエクスポートします。

VUEの面接での質問

1- 基本原則

MVVM

MVVM は Model-View-ViewModel の略で、MVVM はビューをビジネス ロジックから分離します。

ビュー: ビュー レイヤ、モデル: データ モデル、ViewModel は通信を確立するための 2 つの間のブリッジです。

MVVM フレームワークでは、View と Model の間に直接の接続はありませんが、ViewModel を通じて対話します。View と ViewModel の間、および Model と ViewModel の間の対話は双方向であるため、ビュー データの変更はモデルに同期され、モデル データの変更はすぐにビューに反映されます。両者はリアルタイムに更新され、相互に影響し合っていると言えます。ViewModel は、双方向のデータ バインディングを通じて View レイヤーと Model レイヤーを接続します。View と Model の間の同期は完全に自動であるため、開発者はビジネス ロジックに注意するだけでよく、DOM やデータの状態同期を手動で操作する必要はありません。問題はすべて MVVM によって管理されます

VUE の基本的な実装原理

Vue.js は、パブリッシャー/サブスクライバー モードと組み合わせたデータ ハイジャックを使用し、Object.defineProperty() を通じて各プロパティのセッターとゲッターをハイジャックし、データが変更されたときにサブスクライバーにメッセージをパブリッシュし、対応する監視コールバックをトリガーします。 MVVMフレームワーク、

オブザーバー (データ リスナー) : オブザーバーの中心は、object.defineProperty を通じてデータの変更を監視することです。この関数は内部でセッターとゲッターを定義できます。データが変更されるたびに、セッターがトリガーされます。このとき、オブザーバーは購読者、購読ウォッチャー

コンパイル (命令パーサー) : コンパイルの主な動作は、テンプレート命令を解析し、テンプレート内の変数をデータに置き換え、ページ ビューを初期化してレンダリングし、各命令に対応するノードを更新関数でバインドし、追加することです。識別データのサブスクライバーは、データが変更されると通知を受け取り、ビューを更新します

ウォッチャー (サブスクライバー) : ウォッチャー サブスクライバーは、オブザーバーとコンパイルの間の通信ブリッジとして機能します。主に行うことは次のとおりです。

  1. 自身をインスタンス化するときにプロパティ サブスクライバに自分自身を追加します
  2. それ自体に update() メソッドが必要です
  3. 待属性变动dep.notice()通知时,能调用自身的update方法,并触发Compile中绑定的回调

VUE模板编译原理

vue中的template无法被浏览器解析并渲染,因为不属于浏览器的标准,不是正确的HTML语法,所以需要将template转化为一个JavaScript函数,这样浏览器就可以执行这一个函数并渲染对应的HTML元素,就可以让视图跑起来了。这一个转化过程,就成为了模板编译

VUE的编译过程就是将template转化为render函数的过程,分为以下三步

第一步:将模板字符串转换为element ASTS(解析器)

第二步:对AST进行静态节点标记,主要是用来做虚拟DOM的渲染优化(优化器)

第三步:是使用element ASTS生成render函数代码字符串(代码生成器)

VUE虚拟DOM,diff算法

虚拟DOM,其实就是用对象的方式取代真实的DOM操作,把真实的DOM操作放在内存当中,在内存中的对象里做虚拟操作,当页面打开时浏览器会解析HTML元素,构建一个DOM树,两棵DOM树进行比较,根据diff算法比较两棵DOM树的不同,只渲染一次不同的地方

(个人理解)虚拟DOM并不是真是DOM,是根据模板生成的js对象(使用CreteElement方法),根据这个js对象再去生成真实的DOM,对复杂的文档DOM解构,提供一种方便的工具,进行最小化的DOM操作,是可以快速的渲染和高效的更新元素,提升浏览器性能,

我们在渲染页面的时候 会对新的虚拟dom和旧的虚拟dom进行对比 只渲染不同的地方,而不再是像之前只要发生变化,全部的真实dom都要重新渲染,所以提高了渲染的效率

缺点首次渲染大量DOM时,由于多了一层虚拟DOM的计算,会比innerHTML插入慢

diff算法

diff 算法是一种通过同层的树节点进行比较的高效算法,比较方式:diff整体策略为:深度优先,同层比较

データが変更された場合、新しいデータに基づいて新しい仮想 dom を生成し、古い仮想 dom と新しい仮想 dom を比較するこの比較プロセスが、異なる場所を見つけて異なる場所のみを描画する diff アルゴリズムです。一般的には、DOM を削減し、再描画し、リフローすることです。

実際の DOM を記述するために仮想 DOM を使用する理由

実際の DOM を作成するのは比較的コストがかかりますが、js オブジェクトを使用して dom ノードを記述するとコストは比較的低くなりますが、頻繁に dom を操作する場合はオーバーヘッドが比較的大きいため、仮想 dom を使用して実際の dom を記述する

応答原理

レスポンシブとは何か。「レスポンシブ」とは、データが変更されたときに、そのデータを使用するコードに Vue が通知することを意味します。たとえば、データはビューのレンダリングに使用され、データが変更されるとビューは自動的に更新されます。

Vue のレスポンシブ原則は、ES5 の保護されたオブジェクトの Object.defineProperty にあるアクセサー プロパティの get メソッドと set メソッドを介して行われることです。data で宣言されたプロパティはすべてアクセサー プロパティで追加されます。data でデータを読み取るときに、自動的に get メソッドが呼び出されます。データ内のデータが変更されると、set メソッドが自動的に呼び出されます。データ変更が検出されると、オブザーバー Wacher に通知され、オブザーバー Wacher は現在のコンポーネントの再レンダリングを自動的にトリガーします (サブコンポーネントは実行されません)。仮想 DOM ツリー、Vue フレームワークは、新しい仮想 DOM ツリーと古い仮想 DOM ツリーの各ノードの違いを走査して比較し、それを記録します。すべてのレコードの差分を実際の DOM ツリーにローカルに変更します。


	Object.defineProperty怎么用, 三个参数?,有什么作用啊?
    Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回		此对象。
     Object.defineProperty(obj, prop, {})
     obj:需要定义属性的对象
     prop:需要定义的属性
     {}:要定义或修改的属性描述符。
     value: "18",         // 设置默认值得
     enumerable: true,    //这一句控制属性可以枚举 enumerable 改为true 就可以参与遍历了,默认值false
     writable: true,      // 控制属性可以被修改   默认值false
     configurable: true,  // 控制属性可以被删除   默认值false
      get // 当有人读取 prop 的时候  get函数就会调用,并且返回就是 sss 的值
      set // 当有人修改 prop 的时候  set函数就会调用, 有个参数这个参数就是修改后的值
      
      
Object.defineProperty 能定义symbol类型吗? 
       在ES6中,由于 Symbol类型的特殊性,用Symbol类型的值来做对象的key与常规的定义或修改不同,而Object.defineProperty 是定        义key为Symbol的属性的方法之一。
    
vue2和vue3的响应式原理都有什么区别呢?
vue2 用的是 Object.defindProperty 但是vue3用的是Proxy 
Object.defindProperty虽然能够实现双向绑定了,但是还是有缺点,只能对对象的属性进行数据劫持,所以会深度遍历整个对象,不管层级有多深,只要数组中嵌套有对象,就能监听到对象的数据变化无法监听到数组的变化,Proxy就没有这个问题,可以监听整个对象的数据变化,所以用vue3.0会用Proxy代替definedProperty。
上面就是一个典型的例子,当我们点击按钮想要根据数组 arr 的下标改变其元素的时候,你会发现 data 中的数据改变了,但是页面中的数据并没有改变。
         我会用  this.$set( target, key, value ) 来解决
       参数:
         {Object | Array} target
         {string | number} propertyName/index
         {any} value 
         第一参数时指定要修改的数据 (target)
         第二个参数就是你要设置数据的下标或者是属性名
         第三个参数就是现在要修改的数据 (重新赋的值)
改变/添加 对象属性的时候:this.$set(data 实例,"属性名(添加的属性名)","属性值(添加的属性值)")
改变/添加 数组属性的时候:this.\$set(data 实例,数组下标,"改变后的元素(添加的元素)")
原因 : vue在创建实例的时候把data深度遍历所有属性,并使用 Object.defineProperty 把这些属性全部转为 getter/setter。让 Vue 追踪依赖,在属性被访问和修改时通知变化。所以属性必须在 data 对象上存在才能让 Vue 转换它,这样才能让它是响应的。
为什么要用  this.$set  呢? this.$set是干什么的?
      当你发现你给对象加了一个属性,在控制台能打印出来,但是却没有更新到视图上时,也许这个时候就需要用到this.$set()这个方法了,简单来说this.$set的功能就是解决这个问题的啦。官方解释:向响应式对象中添加一个属性,并确保这个新属性同样是响应式的,且触发视图更新。它必须用于向响应式对象上添加新属性,因为 Vue 无法探测普通的新增属性 (比如 this.myObject.newProperty = 'hi'),你会发现vue官网是vue.set,vue.set的用法
       
那 Vue.set 和 this.$set 有什么区别 ?
    Vue.set( ) 是将 set 函数绑定在 Vue 构造函数上,this.$set() 是将 set 函数绑定在 Vue原型上

Vue の双方向データ バインディングの原則

パブリッシャー/サブスクライバー モードと組み合わせたデータ ハイジャックを使用し、Object.defineProperty() を通じて各プロパティのセッターとゲッターをハイジャックし、データが変更されたときにサブスクライバーにメッセージをパブリッシュし、対応するモニタリング コールバックをトリガーしてデータとビューの同期を実現します。

大きく4つのパートに分かれています

  1. オブザーバーは Vue データの再帰的な利便性を主に担っており、データには get メソッドと set メソッドがあり、オブジェクトに値を代入するデータがある場合、setter がトリガーされてデータの変更を監視します。(変更があった場合、最新の値を取得して購読者に通知できます)

  2. コンパイル ディレクティブ パーサーは、データのバインドとディレクティブの解析を担当します。テンプレート内の変数をデータに置き換えてから、ページ ビューを初期化してレンダリングし、各命令に対応するノードに更新関数をバインドします。データが変更されたら、通知を受け取り、ビューを更新します

  3. サブスクライバー ウォッチャー: ウォッチャー サブスクライバーは、オブザーバーとコンパイルの間の通信ブリッジです。主に行うことは、データを監視することです。データが変更されると、独自の update() メソッドを呼び出し、コンパイルにバインドされた更新関数をトリガーできます。

  4. サブスクライバー デプロイメントの実装: パブリッシャー/サブスクライバー モードを採用してサブスクライバーのウォッチャーを収集し、リスナー オブザーバーとサブスクライバー ウォッチャーを統合的に管理します。

vue2 のdefinePropertyに対するvue3のプロキシの利点

在vue3 中
Vue3是通过Object.define.proxy 对对象进行代理,从而实现数据劫持。使用Proxy 的好处是它可以完美的监听到任何方式的数据改变,唯一的缺点是兼容性的问题,因为 Proxy 是 ES6 的语法
Vue3.0 摒弃了 Object.defineProperty,改为基于 Proxy 的观察者机制探索。
首先说一下 Object.defineProperty 的缺点:
① Object.defineProperty 无法监控到数组下标的变化,导致直接通过数组的下标给数组设置值,不能实施响应。 this.$set()解决
② Object.defineProperty 只能劫持对象的属性,因此我们需要对每个对象的每个属性进行遍历。Vue2.X 里,是通过递归 + 遍历 data 对象来实现对数据的监控的,如果属性值也是对象那么需要深度遍历,显然如果能劫持一个完整的对象才是更好的选择。


而要取代它的 Proxy 有以下两个优点
可以劫持整个对象,并返回一个新对象。有多种劫持操作(13 种)
补充:
Proxy 用于创建一个对象的代理,从而实现基本操作的拦截和自定义(如属性查找、赋值、枚举、函数调用等)。 mdn
Proxy 是 ES6 新增的一个属性,翻译过来的意思就是代理,用在这里表示由它来“代理”某些操作。Proxy 让我们能够以简洁易懂的方式控制外部对象的访问,其功能非常类似于设计模式中的代理模式。


1、vue 中数组中的某个对象的属性发生变化,视图不更新如何解决?
 Object.defineProperty 无法监控到数组下标的变化,导致直接通过数组的下标给数组设置值,不能实施响应。 this.$set()解决
 问题原因:因为 vue 的检查机制在进行视图更新时无法监测 数组中的对象的某个属性值的变化。解决方案如下
方案一:利用  this.set(this.obj,key,val)
例:this.set(this.obj,‘k1’,‘v1’)
方案二:就利用 Object.assign({},this.obj)创建新对象  
如果是数组就 Object.assign([],this.obj)
如果是对象就 Object.assign({},this.obj)。

vue.js コア

柔軟なコンポーネント アプリケーション、効率的なデータ バインディング

プログレッシブフレームワークの理解、vue データドリブンの理解

プログレッシブの意味は次のとおりです。最小限のアサーション - すべきことだけを行い、すべきでないことは行わない軽量のフレームワークです。

それぞれのフレームワークには必然的に特徴があり、利用者にとっての要件があり、その要件は命題であり、その命題の強さによって事業展開が左右されます。

ここでの vue データはビュー、つまり DOM 要素を駆動します。これは、DOM の内容がデータの変更に応じて変化するという理解を指します。

VueのSSRとは何ですか?メリットは何ですか?

SSRはサーバーサイドレンダーの略です

SEOに良い: サーバー側にあるため、データはHTMLに埋め込まれてからブラウザにプッシュされるため、SEOのクロールに適しています。

最初の画面のレンダリングが速い

SSRのデメリット:

開発条件は制限されており、サーバー側レンダリングでは beforeCreate と created の 2 つのフックのみがサポートされます。

一部の外部拡張ライブラリが必要な場合は特別な処理が必要で、サーバー側のレンダリング アプリケーションも Node.js オペレーティング環境にある必要があります。

サーバー負荷が増加します。

vue2.0とvue3.0の違い

1.性能提升

更小巧,更快速;支持摇树优化。支持 Fragments (支持多个根节点)和跨组件渲染;支持自定义渲染器。

2.API 变动

Vue2使用 选项类型API(Options API) 对比Vue3 合成型API(Composition API)

optionsApi 使用传统api中,新增一个需求,要在data,methods,computed中修改

compositionApi 我们可以更加优雅的组织我们的代码,函数,让我们的代码更加有序的组合在一起

3.重写虚拟 DOM (Virtual DOM Rewrite)

随着虚拟 DOM 重写,减少 运行时(runtime)开销。重写将包括更有效的代码来创建虚拟节点。

vue3 没有了过滤器

双向数据绑定 从 Object.defineProperty() 变成了 proxy,通过下标修改数组变化了试图数据没发生变化 this.$set() vue3不需要

双向数据绑定原理发生了改变,使用proxy替换Object.defineProerty,使用Proxy的优势:

可直接监听数组类型的数据变

监听的目标为对象本身,不需要像Object.defineProperty一样遍历每个属性,有一定的性能提升

可直接实现对象属性的新增/删除

setup 函数

3.0新加入了TypeScript以及PWA支持

默认使用懒加载

可以不用加上key

vue3 的watch监听可以进行终止监听

生命周期有了一定的区别 Vue2--------------vue3
beforeCreate  -> setup()    开始创建组件之前,创建的是data和method
created    -> setup()
beforeMount  -> onBeforeMount   组件挂载到节点上之前执行的函数。
mounted    -> onMounted 组件挂载完成后执行的函数
beforeUpdate  -> onBeforeUpdate 组件更新之前执行的函数。
updated    -> onUpdated 组件更新完成之后执行的函数。
beforeDestroy -> onBeforeUnmount    组件挂载到节点上之前执行的函数。
destroyed   -> onUnmounted  组件卸载之前执行的函数。
activated   -> onActivated  组件卸载完成后执行的函数
deactivated  -> onDeactivated

2 ビューのライフサイクル (11 の拡張機能)

ステートメントサイクルは何回ですか? それぞれのライフサイクルの特徴とできること

beforeCreate() 创建前,这个时候data中的数据,还未定义,所以不能使用
created()创建后 最早开始使用 data和methods中数据的钩子函数
beforeMount()挂载前 指令已经解析完毕内存中已经生成dom树,但是尚未挂载到页面中去,此时页面还是旧的。
mounted()挂载后 dom已经渲染完毕,此时页面和内存中都是最新的数据,最早可以操作DOM元素钩子函数
 beforeUpdate()更新前 当视图层的数据发生改变会执行这个钩子 内存更新,但是DOM节点还未更新,数据没有与页面同步
 updated()更新后 数据更新完成以后触发的方法,DOM节点已经更新
 beforeDestroy()即将销毁 data和methods中的数据此时还是可以使用的,可以做一些释放内存的操作
 destroyed()销毁完毕  组件已经全部销毁,Vue实例已经被销毁,Vue中的任何数据都不可用
 
 其他三个:
activated  被 keep-alive 缓存的组件激活时调用。
deactivated 被 keep-alive 缓存的组件停用时调用。
errorCaptured 2.5.0+ 新增当捕获一个来自子孙组件的错误时被调用
Vue3.0中的生命周期做了一些改动:
beforeCreate  -> setup()    开始创建组件之前,创建的是data和method
created       -> setup()
beforeMount   -> onBeforeMount  组件挂载到节点上之前执行的函数。
mounted       -> onMounted  组件挂载完成后执行的函数
beforeUpdate  -> onBeforeUpdate 组件更新之前执行的函数。
Update        - > onUpdated组件更新完成之后执行的函数。
beforeDestroy -> onBeforeUnmount    组件挂载到节点上之前执行的函数。
destroyed     -> onUnmounted    组件卸载之前执行的函数。
- vue的实例加载完成是在哪个声明周期完成呢
beforeCreate
- vue的dom挂载完成是在哪个声命周期里呢
mounted
1、created mounted 的区别?
created 模板渲染成html前调用,即通常初始化某些属性值,然后再渲染成视图。
mounted:在模板渲染成html后调用,通常是初始化页面完成后,再对html的dom节点进行一些需要的操作。
2、怎么在created里面操作dom?
this.$nextTick()将回调延迟到下次 DOM 更新循环之后执行。在修改数据之后立即使用它,然后等待 DOM 更新。它跟全局方法 Vue.nextTick 一样,不同的是回调的 this 自动绑定到调用它的实例上。
可以根据打印的顺序看到,在created()钩子函数执行的时候DOM 其实并未进行任何渲染,而此时进行DOM操作并无作用,而在created()里使用this.$nextTick()可以等待dom生成以后再来获取dom对象,而通过this.$nextTick()获取到的值为dom更新之后的值
 setTimeout(() => {
      console.log(this.$refs.button);
 });
 
 
3、那 setTimeout this.$nextTick 什么区别呢?
setTimeout 将同步转换为异步 this.$nextTick 
 this.$nextTick 将回调延迟到下次 DOM 更新循环之后执行。在修改数据之后立即使用它,
4、this.$nextTick()是宏任务还是微任务啊? 
 优先是Promise.then方法,是个微任务,这样可以避免多一次队列,进而少一次UI渲染,节省性能
5、a页面跳转到b页面周期执行
页面a----beforeCreate undefined
页面a----created 1
页面a----beforeMount 1
页面a----mounted 1
页面b----beforeCreate undefined
页面b----created 1
页面b----beforeMount 1
页面a----beforeDestroy 1
页面a----destroyed 1
页面b----mounted 1
6、组件 和 页面周期 的执行顺序
- 页面beforeCreate undefined
- 页面created 1
- 页面beforeMount 1
- 组件beforeCreate undefined
- 组件created 5555
- 组件beforeMount 5555
- 组件mounted 5555
- 页面mounted 1
7、父子组件生命周期执行顺序
加载渲染过程
父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount->子mounted->父mounted
代码更新过程
父beforeUpdate->子beforeUpdate->子updated->父updated
代码销毁过程
父beforeDestroy->子beforeDestroy->子destroyed->父destroyed
代码常用钩子简易版
父create->子created->子mounted->父mounted
8、补充单一组件钩子执行顺序
activated, deactivated 是组件keep-alive时独有的钩子
beforeCreate
created
beforeMount
mounted
beforeUpdate
updated
activated
deactivated
beforeDestroy
destroyed
errorCaptured
watch
仅仅是数据发生改变的时候会侦听到;
只是会检测到你写在watch里的那些属性,没写的就不会触发。
updated
执行到它的时候时候是数据发生变化且界面更新完毕;
不能监听到路由数据(例如网址中的参数);
所有的数据发生变化都会调用(消耗性能);
每次触发的代码都是同一个
computed
1、监控自己定义的变量,不用再data里面声明,函数名就是变量名
2、适合多个变量或对象进行处理后返回一个值(结果)。若这多个变量发生只要有一个发生变化,结果都会变化。
3、计算的结果具有缓存,依赖响应式属性变化,响应式属性没有变化,直接从缓存中读取结果。
4、在内部函数调用的时候不用加()。
5、必须用return返回
6、不要在computed 中对data中的数据进行赋值操作,这会形成一个死循环。
methods不会被缓存:方法每次都会去重新计算结果。methods 方法表示一个具体的操作,主要书写业务逻辑;
使用 methods 方法编写的逻辑运算,在调用时 add() 一定要加“()”,methods 里面写的多位方法,调用方法一定要有()。methods方法页面刚加载时调用一次,以后只有被调用的时候才会被调用。我们在长度框和宽度框的值输入完以后,点击“+” methods 方法调用一次。这里很明显我们采用 methods 会更节省资源。
使用场景?
watch:
1、watch 函数是不需要调用的。
2、重点在于监控,监控数据发生变化的时候,执行回调函数操作。
3、当我们需要在数据变化时执行异步或开销较大的操作时,应该使用 watch
4、函数名就是你要监听的数据名字
5、监控一些input框值的特殊处理,适合一个数据影响多个数据。
6、数据变化时,执行一些异步操作,或开销比较大的操作
computed:
在模板中放入太多的逻辑会让模板过重且难以维护,在需要对数据进行复杂处理,且可能多次使用的情况下,尽量采取计算属性的方式
一个需要的结果受多个数据影响的时候,比如购物车结算金额(受到很多处的价格结算)。
操作某个属性,执行一些复杂的逻辑,并在多处使用这个结果。
内部函数中多处要使用到这个结果的。
1、监控自己定义的变量,不用再data里面声明,函数名就是变量名
2、适合多个变量或对象进行处理后返回一个值(结果)。若这多个变量发生只要有一个发生变化,结果都会变化。
3、计算的结果具有缓存,依赖响应式属性变化,响应式属性没有变化,直接从缓存中读取结果。
4、在内部函数调用的时候不用加()。
5、必须用return返回
6、不要在computed 中对data中的数据进行赋值操作,这会形成一个死循环。

一般に、どのライフサイクルで非同期データをリクエストするか

可以啊钩子函数中的 created、beforeMount、mounted 中进行调用,因为在这三个钩子函数中,data 已经创建,可以将服务端端返回的数据进行赋值。

在created中最好

能更快获取到服务端数据,减少页面加载时间,用户体验更好;

SSR不支持 beforeMount 、mounted 钩子函数,放在 created 中有助于一致性。

mounted 在请求完数据之后需要对 dom 进行操作的时候可以用到

vue中methods,computed,watch的区别

computed 是vue中的计算属性,具有缓存性,当他的依赖于值,发生改变的时候才会重新调用

methods 是没有缓存的,只要调用,就会执行,一般结合事件来使用

watch 没有缓存性 监听data中的属性 属性值只要发生变化就会执行 可以利用他的特性做一些异步的操作

created和mounted区别?

created:dom渲染前调用,即通常初始化某些属性值

mounted:在dom渲染后调用,通常是初始化页面完成后,再对html的dom节点进行一些需要的操作

生命周期钩子是如何实现的

Vue 的生命周期钩子核心实现是利用发布订阅模式先把用户传入的的生命周期钩子订阅好(内部采用数组的方式存储)然后在创建组件实例的过程中会一次执行对应的钩子方法(发布)

3-VUEX常问的考点

vuex严格模式

开启严格模式,仅需在创建 store 的时候传入 strict: true:
 
const store = new Vuex.Store({
  // ...
  strict: true
})
在严格模式下,无论何时发生了状态变更且不是由 mutation 函数引起的,将会抛出错误。这能保证所有的状态变更都能被调试工具跟踪到。

vuex是什么,

vuex是一个状态管理工具,所谓状态的是就是数据,采用集中式存储管所有组件的状态,是为了解决中大型项目一个数据共享的问题。vuex 他可以将数据保存到本地,数据是响应式的,能够保持数据页面的共享,提高开发效率

好处

能够在 vuex 中集中管理共享的数据,易于开发和后期维护 可以做状态管理、采用localstorage保存信息、数据一直存储在用户的客户端中 存储在 vuex 中的数据都是响应式的,能够实时保持数据与页面的同步,能够高效地实现组件之间的数据共享,提高开发 效率

vuex核心

  1. state: vuex の基本データ、データ ソースの保存場所、共有データの定義に使用されます。
  2. getter: 基本データから派生したデータ。状態の計算されたプロパティに相当します。
  3. 突然変異: 更新されたデータを送信するメソッド (状態内のデータを操作できる唯一のメソッド) は同期的である必要があります。最初のパラメータは状態、2 番目のパラメータはコミットによって渡されるデータです。
  4. アクション: 非同期操作に使用されます。通常は、リクエストの送信、アクションでの関数の作成、ページでの呼び出しのディスパッチ、アクションでのコミットによるミューテーションの呼び出し、ミューテーションによる状態の操作に使用されます。
  5. モジュール、modular vuex により、各モジュールが独自の状態、突然変異、アクション、ゲッターを持つことができ、構造が明確になり、管理が容易になります。

vuex の動作メカニズム

操作メカニズム: Vuex はビュー (ここでは Vue コンポーネントを指します) を駆動するデータ (状態) を提供し、ビューは Dispatch を通じてアクションをディスパッチし、一部の非同期操作はアクション内でさらに実行できます (ajax を介したバックエンド インターフェイス データのリクエストなど)。 、その後 Commit で Mutation に Submit すると、最終的に Mutation によって状態が変更されます。では、なぜ突然変異を行うのでしょうか? これは、プラグインを通じてさらにデバッグを実行できるように、Vue デバッグ ツール (Devtools) でデータの変更を記録する必要があるためです。したがって、Mutation では純粋な同期操作のみが可能であり、非同期操作がある場合は、Action で処理する必要があります。非同期操作がない場合、コミット操作のミューテーションはコンポーネントによって直接実行できます。

高度な使用法ヘルパー関数 (mapState、mapActions、mapMutation、mapGetters)

MapState、mapActions、mapMutation、mapGetters

補助関数は、vuex のデータとメソッドを vue コンポーネントにマップできます。操作を簡素化するという目的を達成するため

使い方:

「vuex」から {mapActions、mapGetters、mapMutations、mapState} をインポートします

computed(){ ...mapState(['データ名'])}

Vuex ページの更新データ損失を解決する方法

vuex データの永続化を行う必要があります。通常はローカル ストレージ ソリューションを使用してデータを保存します。独自のストレージ ソリューションを設計するか、サードパーティのプラグインを使用できます。

Vuex 永続ストレージ用のプラグインである vuex-persist プラグインを使用することをお勧めします。ストレージに手動でアクセスする必要はありませんが、状態を Cookie または localStorage に直接保存します。

Vuex がモジュールを分割し、名前空間を追加する理由

モジュール: 単一の状態ツリーを使用するため、アプリケーションのすべての状態が比較的大きなオブジェクトに集中します。アプリケーションが非常に複雑になると、ストア オブジェクトが非常に肥大化する可能性があります。上記の問題を解決するために、Vuex ではストアをモジュールに分割できます。各モジュールには、独自の状態、突然変異、アクション、ゲッター、さらにはネストされたサブモジュールがあります。管理が簡単

4 ルーティング vue-router

vue-router (ルーティング原則? ルーティングガード?)

開発中に Vue のルーティング サポートが不足していたため、公式の vue-router プラグインが追加されました。Vue のシングルページ アプリケーションはルーティングとコンポーネントに基づいており、ルーティングはアクセス パスの設定、パスとコンポーネントのマップに使用されます。従来のページ アプリケーションは、ページの切り替えやジャンプにいくつかのハイパーリンクを使用します。vue-router シングルページ アプリケーションでは、パス間の切り替えであり、実際にはコンポーネントの切り替えです。ルーティングは、SPA (シングル ページ アプリケーション) のパス マネージャーです。平たく言えば、vue-router は WebApp のリンク パス管理システムです。

原則 一般的なソース コードでは、window.history と location.hash が使用されます 原則: ブラウザのアドレス URL を変更することで、ページを再リクエストせずに、BOM 内の location オブジェクトを通じて、場所が表示されるページ ビューを更新します。ハッシュには、ルートのアドレス、つまり URL を変更するために割り当てることができるアドレスが格納されます。これにより hashchange イベントがトリガーされ、window.addEventListener を通じてハッシュ値をリッスンし、対応するルートと照合してページのコンポーネントをレンダリングします。1 つは # ハッシュで、アドレスに # を追加してブラウザーを欺きます。アドレスはページ内ナビゲーション 2 によるものです。1 つは、URL のハッシュを使用して完全な URL をシミュレートする h5 の履歴です。

ルーティングにはハッシュ モードとヒストリー モードの 2 つのモードがあり、デフォルトはハッシュです。

vue-router (コア) の実装原則: ページを再リクエストせずにビューを更新します。

1. ハッシュ — アドレスバーの URL にある # 記号のことです。その特徴は、ハッシュは URL に表示されますが、HTTP リクエストには含まれず、バックエンドにはまったく影響を与えないことです。したがって、ハッシュを変更してもページはリロードされません。

2. 履歴 - HTML5 History API を使用すると、ブラウザーに # がありません。ブラウザーの互換性の問題があります。

3. 履歴モードでは、フロントエンド URL は、実際にバックエンドへのリクエストを開始する URL と一致している必要があります。そうでない場合は、404 エラーが返されます。

グローバル ルート ガード

router.beforeEach 全局前置守卫 进入路由之前

router.beforeResolve 全局解析守卫,在beforeRouteEnter调用之后调用

同时在所有组件内守卫和异步路由组件被解析之后,解析守卫就被正确调用

router.afterEach 全局后置钩子 进入路由之后

你也可以注册全局后置钩子,然而和守卫不同的是,这些钩子不会接受 next 函数也不会改变导航本身:

コンポーネントレベルのルーティングガードは、データやメソッドと同じレベルで、保護されるコンポーネントに配置されます。

  • BeforeRouteEnter がルートに入りますが、この時点ではインスタンスが作成されていないため、zhis を取得できません
  • beforeRouteUpdate (2.2) ルーティングが同じコンポーネントを再利用する場合
  • beforeRouteLeave は現在のルートを離れます。これは、データの保存、データの初期化、タイマーのオフなどに使用できます。
//在组件内部进行配置,这里的函数用法也是和beforeEach一毛一样
const Foo = {
  template: `...`,
  beforeRouteEnter (to, from, next) {
    // 在渲染该组件的对应路由被 confirm 前调用
    // 不!能!获取组件实例 `this`
    // 因为当守卫执行前,组件实例还没被创建
  },
  beforeRouteUpdate (to, from, next) {
    // 在当前路由改变,但是该组件被复用时调用
    // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
    // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
    // 可以访问组件实例 `this`
  },
  beforeRouteLeave (to, from, next) {
    // 导航离开该组件的对应路由时调用
    // 可以访问组件实例 `this`
  }
}

単一のルーティング ルールの排他的ガードはルーティング設定に記述されており、このパスにアクセスした場合にのみフック関数がトリガーされます。

beforeEnter:(to,from,next)=>{ alert("欢迎来到我的界面") next() }

パラメータ

  • to: Route:入力する対象のルーティングオブジェクト
  • from: Route: 現在のナビゲーションが出発するルート オブジェクト
  • next: Function: このフックを解決するには、必ずこのメソッドを呼び出してください実行効果はnextメソッドの呼び出しパラメータによって異なります。

リダイレクトにどの属性を使用するか?

リダイレクト:「/パス」

Vue ルーティングにはいくつかのジャンプ方法があります

1、<router-link to="需要跳转到页面的路径"> 2、this.$router.push()跳转到指定的url,并在history中添加记录,点击回退返回到上一个页面

3、this.$router.replace()跳转到指定的url,但是history中不会添加记录,点击回退到上上个页面

4、this.$touter.go(n)向前或者后跳转n个页面,n可以是正数也可以是负数

router.push、router.replace、router.go、router.back の違いは何ですか?

router.push:跳转,并向history栈中加一个记录,可以后退到上一个页面

router.replace:跳转,不会向history栈中加一个记录,不可以后退到上一个页面

router.go:传正数向前跳转,传负数向后跳转

router.back 返回到上一级页面

vue ルーティングパラメータ、クエリ、パラメータを実装する方法

主にクエリとパラメータを通じて実現します

(1) クエリでは名前とパスを使用できますが、パラメータでは名前のみを使用できます。

(2)paramsでリフレッシュすると保存されませんが、queryでリフレッシュすると保存できるようになります。

(3) アドレスバーにパラメータは表示されませんが、クエリは表示されます

(4) Params は動的ルーティングで使用できますが、クエリは使用できません

(5) to=”/goods?id=1001”this.受け取りページの$route.query.idから受け取ります

ルーティングオブジェクトのルートとルーターの違い

Route は、path、params、hash、query、fullPath、matched、name などのルーティング情報パラメータを含む「ルーティング情報オブジェクト」です。

router は、ルーティング ジャンプ メソッド (push、go)、フック関数などを含む「ルーティング インスタンス オブジェクト」です。

vue-router ルーティングフック関数の実行順序は何ですか?

一、打开页面的任意一个页面,没有发生导航切换。
全局前置守卫beforeEach (路由器实例内的前置守卫)
路由独享守卫beforeEnter(激活的路由)
组件内守卫beforeRouteEnter(渲染的组件)
全局解析守卫beforeResolve(路由器实例内的解析守卫)
全局后置钩子afterEach(路由器实例内的后置钩子)

二、如果是有导航切换的(从一个组件切换到另外一个组件)
组件内守卫beforeRouteLeave(即将离开的组件)
全局前置守卫beforeEach (路由器实例内的前置守卫)
组件内守卫beforeRouteEnter(渲染的组件)
全局解析守卫beforeResolve(路由器实例内的解析守卫)
全局后置钩子afterEach(路由器实例内的后置钩子)


完整的导航解析流程
导航被触发。
在失活的组件里调用 beforeRouteLeave 守卫。
调用全局的 beforeEach 守卫。
在重用的组件里调用 beforeRouteUpdate 守卫 (2.2+)。
在路由配置里调用 beforeEnter。
解析异步路由组件。
在被激活的组件里调用 beforeRouteEnter。
调用全局的 beforeResolve 守卫 (2.5+)。
导航被确认。
调用全局的 afterEach 钩子。
触发 DOM 更新。
调用 beforeRouteEnter 守卫中传给 next 的回调函数,创建好的组件实例会作为回调函数的参数传入。

動的ルーティング

動的ルーティングとは、ルーターが独自のルーティング テーブルを自動的に構築し、実際の状況の変化に応じてリアルタイムに調整できることを意味します。先頭を使用し、その後の値は不確かです。この値は、渡したいパラメータです。動的ルーティング マッチングでは、基本的に URL を介してパラメータを渡します。

    比如在写一个商品详情页面的时候,我们的页面结构都一样,只是渲染的数据不同而已,这时候就可以根据商品的不同id去设置动态路由,只需要写一个组件,就可以把每个商品的商品详情映射到同一个组件上去。
    { 
        path: '/Jqxq/:id', // 路由配置拼接
        name: 'Jqxq',
        component: Jqxq
    }
    跳转 this.$router.push('/Jqxq/'+ item.id)
    接收  : this.$route.params.id

ネストされたルート

Vue プロジェクトでは、通常、インターフェイスは複数のネストされたコンポーネントで構成されます。対応する 1 つのディスプレイがコンポーネントであることを明確にする必要があります。したがって、ネストされたルーティングを実装するには 2 つの重要なポイントがあります: ルーティング オブジェクトでサブルートを定義することと、子を使用することネストを実装するには、ルーティング コンポーネント内の使用法を設定します。

ルーティング設定とパラメータ

export default new Router({
    mode: 'history', //路由模式,取值为history与hash
    base: '/', //打包路径,默认为/,可以修改
    routes: [
    {
        path: string, //路径
        ccomponent: Component; //页面组件
        name: string; // 命名路由-路由名称
        components: { [name: string]: Component }; // 命名视图组件
        redirect: string | Location | Function; // 重定向
        props: boolean | string | Function; // 路由组件传递参数
        alias: string | Array<string>; // 路由别名
        children: Array<RouteConfig>; // 嵌套子路由
        // 路由单独钩子
        beforeEnter?: (to: Route, from: Route, next: Function) => void; 
        meta: any; // 自定义标签属性,比如:是否需要登录
        icon: any; // 图标
        // 2.6.0+
        caseSensitive: boolean; // 匹配规则是否大小写敏感?(默认值:false)
        pathToRegexpOptions: Object; // 编译正则的选项
    }
    ]
})

vue-router の動的ルーティングを定義するにはどうすればよいですか? 渡された値を取得するにはどうすればよいですか?

Router ディレクトリ下の Index.js ファイルで、path 属性に /:id を追加し、ルート オブジェクトの params.id を使用して取得します。

ルーティングの遅延読み込み

使用理由: シングルページ アプリケーションでは、アプリケーションの遅延読み込みがないと、webpack によってパッケージ化されたファイルが異常に大きくなり、その結果、ホームページに入るときに読み込まれるコンテンツが多すぎて、遅延が長すぎます。遅延読み込みを使用すると、ページを分割して必要に応じてページを読み込むことができるため、ホームページの読み込み圧力を効果的に共有し、ホームページの読み込み時間を短縮できます 原理: vue 非同期コンポーネント テクノロジ: 非同期ロード、vue-router 構成ルーティング、vue を使用した非同期コンポーネント技術により、オンデマンドロードを実現します。

{ パス: '/home', コンポーネント: () => import('@/views/home/home.vue') } // 遅延読み込み

vue-router で一般的に使用されるルーティング モードの実装原理について話してもらえますか?

ハッシュモード
location.hash の値は、実際には URL の # 以降の値であり、その特徴は、URL にはハッシュが表示されますが、HTTP リクエストには含まれず、バックエンドにはまったく影響を与えないことです。ハッシュを変更してもページはリロードされません。

ハッシュ変更のリスナー イベントを追加できます。
window.addEventListener(“hashchange”, funcRef, false);

ハッシュ(window.location.hash)を変更するたびに、ブラウザのアクセス履歴に記録が追加されます 上記のハッシュの性質を利用して、「ページを再リクエストせずにビューを更新する」という機能をブラウザで実現できます。フロントエンドルーティングの特徴:
互換性がある セクシーだけど醜い

history 模式
利用了 HTML5 History Interface 中新增的 pushState() 和 replaceState() 方法。
这两个方法应用于浏览器的历史记录站,在当前已有的 back、forward、go 的基础之上,它们提供了对历史记录进行修改的功能。这两个方法有个共同的特点:当调用他们修改浏览器历史记录栈后,虽然当前 URL 改变了,但浏览器不会刷新页面,这就为单页应用前端路由“更新视图但不重新请求页面”提供了基础。

5-常用指令

vue常用修饰和常见指令

修饰符
.stop  阻止事件冒泡
.cpture 设置事件捕获
.self  只有当事件作用在元素本身才会触发
.prevent 阻止默认事件,比如超链接跳转
.once 事件只能触发一次
.native 触发js原生的事件
.number 把文本框的内容转换为数字
.trim  去除文本框左右空格
常见指令
⑴v-bind:给元素绑定属性
⑵v-on:给元素绑定事件
⑶v-html:给元素绑定数据,且该指令可以解析 html 标签
⑷v-text:给元素绑定数据,不解析标签
⑸v-model:数据双向绑定
⑹v-for:遍历数组
⑺v-if:条件渲染指令,动态在 DOM 内添加或删除 DOM 元素
⑻v-else:条件渲染指令,必须跟 v-if 成对使用
⑼v-else-if:判断多层条件,必须跟 v-if 成对使用
⑽v-cloak:解决插值闪烁问题
⑾v-once:只渲染元素或组件一次
⑿v-pre:跳过这个元素以及子元素的编译过程,以此来加快整个项目的编译速度
⒀v-show:条件渲染指令,将不符合条件的数据隐藏(display:none)

v-if与v-for优先级

v-for 比 v-if 优先,如果每一次都需要遍历整个数组,将会影响速度,尤其是当之需要渲染很小一部分的时候。

vue中key的作用

“key 值:用于管理可复用的元素。因为 Vue 会尽可能高效地渲染元素,通常会复用已有元素而不是从头开始渲染。这么做使 Vue 变得非常快,但是这样也不总是符合实际需求。 2.2.0+ 的版本里,当在组件中使用 v-for 时,key 是必须的。”

key是给每一个vnode的唯一id,也是diff的一种优化策略,可以根据key,更准确, 更快的找到对应的vnode节点,更高效的对比虚拟DOM中每个节点是否是相同节点,相同就复用,不相同就删除旧的创建新的

key使用index还是id

当 Vue.js 用 v-for 正在更新已渲染过的元素列表时,它默认用“就地复用”策略。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序, 而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素。key 的作用主要是为了高效的更新虚拟 DOM。

举例子:加入写一个带有复选框的列表

最初のノードのチェック ボックスをオンにして、[削除] をクリックします。これが vue での動作です。この時点で、削除後の新しいデータが比較されます。最初のノードのラベルは同じですが、値は異なります。元の位置が再利用されます ラベルは削除または作成されません 最初のノードでチェック ボックスがオンになっています 最初のノードが削除されているように見えますが、クリックしてチェック ボックスを表示すると、まだオンになっています最初のノードを直接削除する場合、チェックボックスはオフになります。

Vue の初期化ページのちらつきの問題。

補間式のちらつきの問題を解決するには、スタイルでスタイル [v- Clock]{display:none} を設定する必要があります。

v-if と v-show の違いと使用シナリオは?

v-if は要素を動的に作成または破棄します。true の場合は表示され、false の場合は表示されません。v-else を使用するには、v-if の隣にある必要があります。

v-show は要素の表示または非表示を制御するもので、ラベルには「display: block, none」と表示されます。

v-if はスイッチング消費量が多く、v-show は初期化レンダリング消費量が多いため、頻繁に切り替える場合は一般的に v-show を使用することをお勧めします。判定分岐が多い場合や初めてレンダリングする場合は v-if を使用してください

カスタム ディレクティブ、カスタム フィルター

vue に付属する仕様に加えて、dom で低レベルの操作を実行する必要がある場合は、ここでカスタム命令を使用します。

グローバル: vue.directive: {"", {}} ローカル: ディレクティブ: {ディレクティブ名: {フック関数}}

  1. bind: ディレクティブが初めて要素にバインドされるときに、1 回だけ呼び出されます。ここではワンタイムの初期化設定を行うことができます。

  2. insert: バインドされた要素が親ノードに挿入されるときに呼び出されます (親ノードのみが存在することが保証されますが、必ずしもドキュメントに挿入されるわけではありません)。

  3. update: コンポーネントの VNode が更新されるときに呼び出されますが、子 VNode の更新前に発生する場合もあります。ディレクティブの値は変更されている場合もあれば、変更されていない場合もあります。ただし、更新前後の値を比較することで、不要なテンプレートの更新を無視できます (フック関数のパラメーターの詳細については、以下を参照してください)。

  4. componentUpdated: コマンドが配置されているコンポーネントの VNode とその子 VNode がすべて更新された後に呼び出されます。

  5. unbind: 命令が要素からアンバインドされるときに 1 回だけ呼び出されます。

パラメータ

el: ディレクティブがバインドされる要素

バインディング: オブジェクトに含まれる、

name: v- プレフィックスを除いたコマンド名。

value: ディレクティブのバインディング値

カスタム指導の原則

1. ast 構文ツリーを生成するときに、命令に遭遇すると、現在の要素に directive 属性が追加されます。

2. genDirectives を通じて命令コードを生成する

3. パッチの前に命令のフックを cbs に抽出し、パッチ処理中に対応するフックを呼び出します。

4. 実行命令がフック関数に該当する場合、対応する命令で定義されたメソッドを呼び出します。

6- オプション オブジェクトと共通 API

フィルター

フィルターは、表示されるデータをさらにスクリーニングし、フィルターが元のデータを変更せず、元のデータに基づいて新しいデータを生成するだけであることを表示します。

グローバル:

Vue.filter('フィルタ名', funciton(val){})

ローカル フィルター。コンポーネント内のフィルター プロパティで定義されます。このコンポーネント内でのみ使用できます。

フィルター: {フィルター名: 関数 (パラメーター) {//ロジック コード}}

用途: 時間のフィルター、お金のフィルター

混入します

ミックスインを使用すると、Vue コンポーネントのプラグイン可能で再利用可能な機能を作成できます。mixin プロジェクトが複雑になると、複数のコンポーネント間でロジックが繰り返される場合に mixin が使用されます。

ライフサイクル フックやメソッドなど、複数のコンポーネント間でコンポーネント オプションのセットを再利用したい場合は、それをミックスインとして記述し、コンポーネント内で単純に参照できます。

次に、ミックスインの内容をコンポーネントにマージします。ミックスインでライフサイクル フックを定義すると、コンポーネント独自のフックに最適化されて実行されます。

vue.js における Mixin とページの実行順序の問題

ミックスイン内のコードが最初に実行され、単一ファイル内のコードが後で実行されます。

ページの beforeCreate --> mixin の beforeCreate --> ページの作成 --> mixin の作成 --> ページの beforeMount --> mixin の beforeMount --> ページのマウント --> mixin のマウント

nextTick の使用シナリオと原則

在下次DOM更新循环结束后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的DOM。使用场景是:可以在created钩子函数中拿到dom节点

nextTick 中的回调是在下次 DOM 更新循环结束之后执行的延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。主要思路就是采用微任务优先的方式调用异步方法去执行 nextTick 包装的方法

vue的删除数组和原生删除数组的区别delete

删除数组

  1. delete只是把数组元素的值变成empty/undefined,元素的键不变,数组长度不变。
  2. Vue.delete直接删除数组,改变数组的键值和长度。

删除对象

两者相同,都会把键名(属性/字段)和键值删除。

Vue.extend 作用和原理

官方解释:Vue.extend 使用基础 Vue 构造器,创建一个“子类”。参数是一个包含组件选项的对象。

其实就是一个子类构造器 是 Vue 组件的核心 api 实现思路就是使用原型继承的方法返回了 Vue 的子类 并且利用 mergeOptions 把传入组件的 options 和父类的 options 进行了合并 基础用法

<div id="mount-point"></div>
// 创建构造器
/* Vue.extend( options )
  参数:{Object} options
  用法:使用基础 Vue 构造器,创建一个“子类”。参数是一个包含组件选项的对象;
       data 选项是特例,需要注意: 在 Vue.extend() 中它必须是函数;*/
var Profile = Vue.extend({
  template: '<p>{
   
   {firstName}} {
   
   {lastName}} aka {
   
   {alias}}</p>',
  data: function () {
    return {
      firstName: 'Walter',
      lastName: 'White',
      alias: 'Heisenberg'
    }
  }
})
// 创建 Profile 实例,并挂载到一个元素上。
new Profile().$mount('#mount-point')
// 结果如下:
<p>Walter White aka Heisenberg</p>
/*
可以看到,extend 创建的是 Vue 构造器,而不是我们平时常写的组件实例,所以不可以通过 new Vue({ components: testExtend }) 来直接使用,需要通过 new Profile().$mount(’#mount-point’) 来挂载到指定的元素上。
*/

7-组件模块部分(插槽,单页面,通信)

vue父子,子父,兄弟通信

父传递子如何传递

(1)在父组件的子组件标签上绑定一个属性,挂载要传输的变量 (2)在子组件中通过props来接受数据,props可以是数组也可以是对象,接受的数据可以直接使用 props: [“属性名”] props:{属性名:数据类型}

子传递父如何传递

(1)在父组件的子组件标签上自定义一个事件,然后调用需要的方法 (2)在子组件的方法中通过 this.$emit(“事件”)来触发在父组件中定义的事件,数据是以参数的形式进行传递的

兄弟组件如何通信

(1)找到min.js文件,给他vue挂载一个 公共的 b u s V u e . p r o t o t y p e . bus Vue.prototype. busVue.prototype.bus = new Vue() (2)传送数据的一方 用this. b u s . bus. bus.emit(‘事件名’,‘传送的数据’) (3)在 接收数据的一方用通过 Bus.$on(“事件名”,(data)=>{data是接受的数据})

props验证,和默认值

props:会接收不同的数据类型,常用的数据类型的设置默认值的写法,Number, String, Boolean, Array, Function, Object

所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级prop 的更新流动到子组件中,但是反过来则不行。这样防止子组件意外改变父级组件的状态,从而导致你的应用的数据流向难以理解。若果在子组件中直接修改prop传递的值,Vue会发出警告,

组件中写 name 选项有什么作用

① 项目使用 keep-alive 时,可搭配组件的 name 进行缓存过滤。 ② DOM 做递归组件时需要调用自身 name ③ vue-devtools 调试工具里显示的组件名称是由 vue 中组件 name 决定的

自定义组件

在vue 中的 component 中新建组件,定义好视图层,

在vue中开发,都是用的组件化的思想开发的,组件封装的方式可以使我们的开发效率提高,把单页面的每个模块拆分为一个组件件,

コンポーネントのカプセル化という方法は、開発効率の低さ、メンテナンスの困難さ、再利用性の低さなど、従来のプロジェクトの問題を解決します。

使用方法: たとえば、スワイパーをカプセル化するには、まず、渡されたデータを受け入れるための props を定義し、応答のロジックを記述し、それをページにインポートしてラベルとして登録する必要があります。

キープアライブ機能

keep-alive は Vue によって提供される組み込みコンポーネントであり、非アクティブなコンポーネント インスタンスを破棄する代わりにキャッシュします。ラベルとして使用され、キャッシュする必要があるコンポーネントの外側にラップされます。

コンポーネントの切り替えプロセス中、切り替えられたコンポーネントはメモリ内に保持されるため、DOM の繰り返しレンダリングが防止され、読み込み時間とパフォーマンスの消費が削減され、ユーザー エクスペリエンスが向上します。

機能: たとえば、リストページに詳細を入力するときに、リストのスクロール位置を保存したいので、キープアライブを使用してリストページのスクロール位置を保存できます。

コンポーネントがキープアライブを使用すると、actived() と deactived() という 2 つの新しいライフサイクルが追加されます。

アクティブ化 (コンポーネントがアクティブ化されるときに使用されます) および非アクティブ化 (グループ価格が終了するときに呼び出されます)

パラメータは 2 つあります。 コンポーネントを条件付きでキャッシュできるようにします。

include - ラップされたコンポーネント名がキャッシュされます

exclude でラップされたコンポーネント名はキャッシュされません。

キープアライブ キャッシュ beforeDestroy は引き続き実行されますか?

まず、答えは「いいえ」です。正確に言えば、直接呼び出されることはありません。デフォルトではkeep-aliveが設定されていないので、現在のルートから抜ける場合は直接beforeDestroyを呼び出してdestroyして破棄します。コンポーネントがキープアライブに設定されている場合、この破棄サイクル関数は直接呼び出されませんが、アクティブ化および非アクティブ化された 2 つの新しい関数がライフ サイクル関数に追加されます。終了時には、非アクティブ化された関数が実行されます。

VUE コンポーネントのデータが関数である理由

オブジェクトは参照データ型です。関数によって返されない場合、各コンポーネントのデータはメモリ内の同じアドレスになります。一方のデータが変更されると、もう一方のデータも変更されるため、データ汚染が発生しますデータが関数の場合、各インスタンスのデータはクロージャ内にあるため、各インスタンスには影響しません。

コンポーネントの特長と利点、コンポーネントの基本構成

(1) 特性:重用性、可指定性、互操作性、高内聚性、低耦合度

(2) 好处:组件可以扩展HTML元素、封装可重用代码

template 结构(html代码)

script行为

style样式

什么是slot?什么是命名slot?slot怎么使用?

插槽就是父组件往子组件中插入一些内容。

有三种方式,默认插槽,具名插槽,作用域插槽

默认插槽就是把父组件中的数据,显示在子组件中,子组件通过一个slot插槽标签显示父组件中的数据

具名插槽是在父组件中通过slot属性,给插槽命名,在子组件中通过slot标签,根据定义好的名字填充到对应的位置。这样就可以指定多个可区分的slot,在使用组件时灵活地进行插值。

作用域插槽是带数据的插槽,子组件提供给父组件的参数,父组件根据子组件传过来的插槽数据来进行不同的展现和填充内容。在标签中通过v-slot=""要穿过来的数据“来接受数据。

scoped 原理及穿透方法

vue 中的 scoped 通过在 DOM 结构以及 css 样式上加唯一不重复的标记:data-v-hash 的方式,以保证唯一(通过 PostCSS 转译),达到样式私有模块化的目的。

scoped 的 3 条渲染规则: ① 给 HTML 的 DOM 节点加一个不重复的 data 属性,来表示它的唯一性; ② 在每句 css 选择器末尾(编译后的生成的 css 语句)加一个当前组件的 data 属性选择器来私有化样式; ③ 如果组件内部包含有其他组件,只会给其他组件的最外层标签加上 ddan 当前组件的 data 属性

在做项目中,会遇到这么一个问题,即:引用了第三方组件,需要在组件中局部修改第三方组件的样式,而又不想去除scoped属性造成组件之间的样式污染。那么有哪些解决办法呢?
①不使用scopeds省略(不推荐);
② 在模板中使用两次style标签。
③scoped穿透:/deep/ >>>

函数式组件使用场景和原理

函数式组件与普通组件的区别
1.函数式组件需要在声明组件是指定 functional:true
2.不需要实例化,所以没有this,this通过render函数的第二个参数context来代替
3.没有生命周期钩子函数,不能使用计算属性,watch
4.不能通过$emit 对外暴露事件,调用事件只能通过context.listeners.click的方式调用外部传入的事件
5.因为函数式组件是没有实例化的,所以在外部通过ref去引用组件时,实际引用的是HTMLElement
6.函数式组件的props可以不用显示声明,所以没有在props里面声明的属性都会被自动隐式解析为prop,而普通组件所有未声明的属性都解析到$attrs里面,并自动挂载到组件根元素上面(可以通过inheritAttrs属性禁止)
优点 1.由于函数式组件不需要实例化,无状态,没有生命周期,所以渲染性能要好于普通组件 2.函数式组件结构比较简单,代码结构更清晰
使用场景:
一个简单的展示组件,作为容器组件使用 比如 router-view 就是一个函数式组件
“高阶组件”——用于接收一个组件作为参数,返回一个被包装过的组件

8-VUE项目中的问题

单页面应用和多页面应用的优缺点

单页面:只有一个html页面,跳转方式是组件之间的切换

优点:跳转流畅、组件化开发、组件可复用、开发便捷

缺点:首屏加载过慢

多页面:有多个页面,跳转方式是页面之间的跳转

优点:首屏加载块

缺点:跳转速度慢

口述axios封装

首先要安装axios,一般我会在项目的src目录中,新建一个network文件夹,作为我们的网络请求模块,然后在里面新建一个http.js和一个api.js文件和一个reques.js。

http.js文件用来封装我们的axios basUrl Tiemout,

api.js用来统一管理我们的接口url,

在request.js中添加请求拦截和响应拦截。在请求拦截中,会给请求头添加token字段,还有loading动画的开启。在响应拦截中,可以做一些loading动画的关闭,还有可以根据后端返回的状态码,做一些检验token是否有效或者过期的操作。

接着就是做一些axios进行的api接口的封装,这里我用到了async,await封装请求接口函数,这样可以将异步操作同步化操作,代码更加友好,避免回调地域的出现

vue中如何解决跨域

在vue开发中实现跨域:在vue项目根目录下找到vue.config.js文件(如果没有该文件则自己创建),在proxy中设置跨域

 
devServer: {
    proxy: {  //配置跨域
      '/api': {
        target: 'http://121.121.67.254:8185/',  //这里后台的地址模拟的;应该填写你们真实的后台接口
        changOrigin: true,  //允许跨域
        pathRewrite: {
          /* 重写路径,当我们在浏览器中看到请求的地址为:http://localhost:8080/api/core/getData/userInfo 时
            实际上访问的地址是:http://121.121.67.254:8185/core/getData/userInfo,因为重写了 /api
           */
          '^/api': '' 
        }
      },
    }
  },

assets和static的区别?

assets中的文件会经过webpack打包,重新编译,推荐在assets存放js等需要打包编译的文件。

static中的文件,不会打包编译。static中的文件只是复制一遍。static中建议放一些外部第三方文件,自己的放assets里,别人的放static中。(图片推荐放在static里)

Vue data 中某一个属性的值发生改变后,视图会立即同步执行重新渲染吗?

不会立即同步执行重新渲染。Vue 实现响应式并不是数据发生变化之后 DOM 立即变化,而是按一定的策略进行 DOM 的更新。Vue 在更新 DOM 时是异步执行的。只要侦听到数据变化, Vue 将开启一个队列,并缓冲在同一事件循环中发生的所有数据变更。

同じウォッチャーが複数回トリガーされた場合、キューにプッシュされるのは 1 回だけです。バッファリング中のこの重複排除は、不必要な計算や DOM 操作を避けるために非常に重要です。次に、次のイベント ループ ティックで、Vue はキューをフラッシュし、実際の (重複排除された) 作業を実行します。

複数の環境変数

1 つ目は、ルート ディレクトリに .env.* (構成ファイル) ファイルを作成し、開発ローカル開発環境構成、ステージング テスト環境構成、本番正式環境構成 (実稼働環境) を作成することです。作成したファイルには多くの変数を定義せず、基本的な env のみを定義したため、さまざまな環境を管理するには、src ディレクトリに config フォルダーを作成し、対応する環境変数ファイルを作成する必要があります。対応するファイルは、後の変更の便宜のために、プロジェクトを再起動せずに config 内に作成されます。これは、開発習慣に沿っています。その後、必要な環境に応じて、分解して代入することでカプセル化された axios にインポートし、baseURL で使用できます。

element-ui と vant-ui はオンデマンドで導入されます

まず、オンデマンドでインポートされたプラグインをインストールし、オンデマンドでインポートされた構成を babel.config.js に追加し、プラグイン フォルダーを作成し、オンデマンドでインポートされたコードを保存する js ファイルを定義してから、最初にビルドされた js ファイルに vue をインポートします。次に、必要な vant-ui プラグインをインポートし、vue.use() を通じてグローバルに挿入します。修正スタイルはスタイルで /深く/ 浸透することができます

Vue はどのような問題を解決しますか

① 仮想 dom: DOM 操作は多くのパフォーマンスを消費します。ネイティブ dom 操作ノードは使用されなくなり、dom 操作が大幅に解放されますが、特定の操作は依然として dom ですが、方法が異なります。多数の命令が提供されていますが、もちろん dom に対する低レベルの操作が必要な場合にはカスタム命令が使用されます。

② ビュー、データ、構造の分離: データの変更が容易になり、関連する操作を完了するためにデータを操作するだけで済みます。

③ コンポーネント化: 単一ページのアプリケーション内のさまざまなモジュールを個別のコンポーネントに分割します。これは、開発とその後のメンテナンスに便利です。

Vue.jsの特徴

簡潔: ページは HTML テンプレート + Json データ + Vue インスタンスで構成されます データ駆動型: 属性を自動的に計算し、依存するテンプレート式を追跡します

コンポーネント化: 再利用可能な分離されたコンポーネントを使用してページを構築します 軽量: コードの量が少なく、他のライブラリに依存する必要がありません 高速: 正確かつ効果的なバッチ DOM 更新 テンプレートに優しい: npm、bower などを通じてインストールでき、Vue の統合が簡単ですコア ライブラリはビュー レイヤーのみに焦点を当てており、学習が非常に簡単です

vue.cliプロジェクトのsrcディレクトリ内の各フォルダとファイルの使い方を教えてください。

アセット フォルダーは静的リソース用です。

コンポーネントはコンポーネントを配置することです。

ルーターはルーティング関連の設定を定義します。

ビュービュー;

app.vue はアプリケーションのメインコンポーネントです。

main.js はエントリファイルです

ページの初期化 –> データの変更 –> ページ UI の更新までの vue プロセスについて説明してください。

当 Vue 进入初始化阶段时,一方面 Vue 会遍历 data 中的属性,并用 Object.defineProperty 将它转化成 getter/setterd 的形式,实现数据劫持;另一方面,Vue 的指令编译器 Compiler 对元素节点的各个指令进行解析,初始化视图,并订阅 Watcher 来更新视图,此时 Watcher 会将自己添加到消息订阅器 Dep 中,此时初始化完毕。
当数据发生变化时,触发 Observer 中 setter 方法,立即调用 Dep.notify( ),Dep 这个数组开始遍历所有的订阅者,并调用其 update 方法,Vue 内部再通过 diff 算法,patch 相应的更新完成对订阅者视图的改变。

Vue がデータをリセットする方法

Object.assign() を使用すると、vm.data は現在の状態のデータを取得できます。

Object.assign(this.data , this .data, this.data )データ_ _ _これ_ _ オプション.データ())

vue-routerのログイン権限の判定

vue-routerのログイン許可判定は主にグローバルフック関数内で行われ、router.jsファイル内の定義ルート内で、ログイン許可が必要なページにmeta属性を追加し、その値は の形式となります。オブジェクトを作成し、そのオブジェクト内でプロパティをカスタマイズし、そのプロパティ値がブール値である場合は、main.js ファイルのグローバルフック関数で判断します。 be Jumped が true の場合、ログインしているかどうかを判定し、ログインがなければログインするように指示し、ログインがあればページジャンプを行います。

vue の最初の画面の読み込みが遅すぎるのを解決するにはどうすればよいですか?

① 頻繁に変更されないライブラリをindex.htmlに配置し、cdn経由でインポートして、build/webpack.base.conf.jsファイルを見つけて、module.exports = { }に次のコードを追加します。

externals: {
'vue': 'Vue',
'vue-router': 'VueRouter',
'element-ui': 'ELEMENT',
}

②vueルートの遅延読み込み、画像の遅延読み込み、非同期コンポーネントの使用、オンデマンド読み込み

③ マップ ファイルを生成せず、config/index.js ファイルを見つけて、productionSourceMap: false に変更します。

④ vueコンポーネントをグローバルに導入しないようにする

⑤軽量化されたツールライブラリを使用する

⑥ gzip 圧縮をオンにする: この最適化には 2 つの側面があり、フロントエンドはファイルを .gz ファイルにパックし、ブラウザが nginx の設定を通じて .gz ファイルを直接解析できるようにします。

⑦ ホームページのみでサーバーサイドレンダリングを実行する: ホームページに本当にボトルネックがある場合は、ノードを使用してサーバーサイドレンダリングを単独で実行することを検討できます。また、次のサブページでは引き続きスパシングルページインタラクションを使用します。nuxt.js サーバー側レンダリング ソリューションを直接使用することは、学習コストが増加し、次にサーバーのメンテナンス コストも増加するため、お勧めできません。ローカル テストでは問題がない場合もありますが、サーバー上で実行する場合に問題が発生するため、静的ページを最大限に使用することをお勧めします。

Vue と JQuery の違いは何ですか? なぜ JQuery を諦めて Vue を使用するのでしょうか?

jQuery は DOM を直接操作します、Vue は DOM を直接操作しません、Vue のデータとビューは分離されています、Vue はデータを操作するだけで済みます、それはフレームワークです

jQuery は DOM を操作する動作が頻繁に発生しますが、Vue は仮想 DOM の技術を利用して DOM 更新時のパフォーマンスを大幅に向上させるライブラリです。

Vue では DOM の直接操作は推奨されていません。開発者はエネルギーのほとんどをデータ レベルに集中するだけで済みます。

Vue には、Route、Vuex など、開発効率を大幅に向上させるいくつかのライブラリが統合されています。

どのような Vue パフォーマンスの最適化を行いましたか?

データ内のデータを可能な限り最小限に抑え、データ内のデータはゲッターとセッターを追加し、対応するウォッチャーを収集します。使用シナリオを区別するために、v-if と v-for を一緒に使用することはできません。v-if と v-show -for トラバーサルは key、key を追加する必要があります。id 値が最適です。同時に v-if を使用することは避けてください。イベントを各要素にバインドするために v-for を使用する必要がある場合は、イベント プロキシを使用してください。

SPA ページはキープアライブ キャッシュ コンポーネントを使用する 多くの場合、v-show の代わりに v-if を使用する ルーティング遅延読み込みコンポーネントと非同期コンポーネントを使用する

手ぶれ補正およびスロットリングのサードパーティ モジュールはオンデマンドでインポートされます

長いリストは表示領域までスクロールされ、動的にロードされます。応答する必要のないデータはデータ内に配置しないでください (Object.freeze() を使用してデータをフリーズできます)。

画像の遅延読み込み

SEOに最適化されたプリレンダリング

サーバーサイドレンダリングSSRパッケージの最適化、

圧縮コード ツリーシェイク/スコープホイスティング

CDN を使用したサードパーティ モジュールのロード マルチスレッド パッケージング happypack splitChunks パブリック ファイルの抽出 sourceMap スケルトン画面の最適化

PWA は、キャッシュ (クライアント キャッシュ、サーバー キャッシュ) の最適化を使用したり、サーバー上で gzip 圧縮を有効にしたりすることもできます。内部リークを防ぐために、コンポーネントが破棄された後にグローバル変数とイベントを破棄します。

ソース;

コンポーネントはコンポーネントを配置することです。

ルーターはルーティング関連の設定を定義します。

ビュービュー;

app.vue はアプリケーションのメインコンポーネントです。

main.js はエントリファイルです

ページの初期化 –> データの変更 –> ページ UI の更新までの vue プロセスについて説明してください。

当 Vue 进入初始化阶段时,一方面 Vue 会遍历 data 中的属性,并用 Object.defineProperty 将它转化成 getter/setterd 的形式,实现数据劫持;另一方面,Vue 的指令编译器 Compiler 对元素节点的各个指令进行解析,初始化视图,并订阅 Watcher 来更新视图,此时 Watcher 会将自己添加到消息订阅器 Dep 中,此时初始化完毕。
当数据发生变化时,触发 Observer 中 setter 方法,立即调用 Dep.notify( ),Dep 这个数组开始遍历所有的订阅者,并调用其 update 方法,Vue 内部再通过 diff 算法,patch 相应的更新完成对订阅者视图的改变。

Vue がデータをリセットする方法

Object.assign() を使用すると、vm.data は現在の状態のデータを取得できます。

Object.assign(this.data , this .data, this.data )データ_ _ _これ_ _ オプション.データ())

vue-routerのログイン権限の判定

vue-routerのログイン許可判定は主にグローバルフック関数内で行われ、router.jsファイル内の定義ルート内で、ログイン許可が必要なページにmeta属性を追加し、その値は の形式となります。オブジェクトを作成し、そのオブジェクト内でプロパティをカスタマイズし、そのプロパティ値がブール値である場合は、main.js ファイルのグローバルフック関数で判断します。 be Jumped が true の場合、ログインしているかどうかを判定し、ログインがなければログインするように指示し、ログインがあればページジャンプを行います。

vue の最初の画面の読み込みが遅すぎるのを解決するにはどうすればよいですか?

① 頻繁に変更されないライブラリをindex.htmlに配置し、cdn経由でインポートして、build/webpack.base.conf.jsファイルを見つけて、module.exports = { }に次のコードを追加します。

externals: {
'vue': 'Vue',
'vue-router': 'VueRouter',
'element-ui': 'ELEMENT',
}

②vueルートの遅延読み込み、画像の遅延読み込み、非同期コンポーネントの使用、オンデマンド読み込み

③ マップ ファイルを生成せず、config/index.js ファイルを見つけて、productionSourceMap: false に変更します。

④ vueコンポーネントをグローバルに導入しないようにする

⑤軽量化されたツールライブラリを使用する

⑥ gzip 圧縮をオンにする: この最適化には 2 つの側面があり、フロントエンドはファイルを .gz ファイルにパックし、ブラウザが nginx の設定を通じて .gz ファイルを直接解析できるようにします。

⑦ ホームページのみでサーバーサイドレンダリングを実行する: ホームページに本当にボトルネックがある場合は、ノードを使用してサーバーサイドレンダリングを単独で実行することを検討できます。また、次のサブページでは引き続きスパシングルページインタラクションを使用します。nuxt.js サーバー側レンダリング ソリューションを直接使用することは、学習コストが増加し、次にサーバーのメンテナンス コストも増加するため、お勧めできません。ローカル テストでは問題がない場合もありますが、サーバー上で実行する場合に問題が発生するため、静的ページを最大限に使用することをお勧めします。

Vue と JQuery の違いは何ですか? なぜ JQuery を諦めて Vue を使用するのでしょうか?

jQuery は DOM を直接操作します、Vue は DOM を直接操作しません、Vue のデータとビューは分離されています、Vue はデータを操作するだけで済みます、それはフレームワークです

jQuery は DOM を操作する動作が頻繁に発生しますが、Vue は仮想 DOM の技術を利用して DOM 更新時のパフォーマンスを大幅に向上させるライブラリです。

Vue では DOM の直接操作は推奨されていません。開発者はエネルギーのほとんどをデータ レベルに集中するだけで済みます。

Vue には、Route、Vuex など、開発効率を大幅に向上させるいくつかのライブラリが統合されています。

どのような Vue パフォーマンスの最適化を行いましたか?

データ内のデータを可能な限り最小限に抑え、データ内のデータはゲッターとセッターを追加し、対応するウォッチャーを収集します。使用シナリオを区別するために、v-if と v-for を一緒に使用することはできません。v-if と v-show -for トラバーサルは key、key を追加する必要があります。id 値が最適です。同時に v-if を使用することは避けてください。イベントを各要素にバインドするために v-for を使用する必要がある場合は、イベント プロキシを使用してください。

SPA ページはキープアライブ キャッシュ コンポーネントを使用する 多くの場合、v-show の代わりに v-if を使用する ルーティング遅延読み込みコンポーネントと非同期コンポーネントを使用する

手ぶれ補正およびスロットリングのサードパーティ モジュールはオンデマンドでインポートされます

長いリストは表示領域までスクロールされ、動的にロードされます。応答する必要のないデータはデータ内に配置しないでください (Object.freeze() を使用してデータをフリーズできます)。

画像の遅延読み込み

SEOに最適化されたプリレンダリング

サーバーサイドレンダリングSSRパッケージの最適化、

圧縮コード ツリーシェイク/スコープホイスティング

CDN を使用したサードパーティ モジュールのロード マルチスレッド パッケージング happypack splitChunks パブリック ファイルの抽出 sourceMap スケルトン画面の最適化

PWA は、キャッシュ (クライアント キャッシュ、サーバー キャッシュ) の最適化を使用したり、サーバー上で gzip 圧縮を有効にしたりすることもできます。内部リークを防ぐために、コンポーネントが破棄された後にグローバル変数とイベントを破棄します。

Supongo que te gusta

Origin blog.csdn.net/m0_37408390/article/details/127902762
Recomendado
Clasificación