前端自己平時總結

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    
</body>
</html>
<script>
    //面試題:
    // 1.
    var z = 10;
           function foo(){
                console.log(z);//10 foo函數在外邊定義的  那個時候z取值應該是最外層的那個z=10;
            }
           (function(funArg){
                var z = 20;
                funArg();
            })(foo);
    // 2.
       console.log('第二題的開始:');
       var data = [];
        for(var k = 0; k < 3; k++){
                data[k] = function(){
                    console.log(k);
                };
        }
        data[0]();//3 執行函數的時候已經是循環執行完之後啦,k=3的時候啦!
        data[1]();//3
        data[2]();//3
        // 3.請問三行 a,b,c 輸出分別是什麼?
         console.log('第三題的開始:');
         function fun(n,o){
            console.log(o)
            return{
                fun:function(m){
                    return fun(m,n);
                }
            };
         }
    var a = fun(0); a.fun(1); a.fun(2); a.fun(3);//undefined/0/0/0
    var b = fun(0).fun(1).fun(2).fun(3);//undefined/0/1/2  
    var c = fun(0).fun(1);c.fun(2);c.fun(3);//undefined/0/1/1
    // 4.問,輸出分別爲什麼?
    console.log('第4題的開始:');
     var a = 100;
    function testResult(){
            var b = 2 * a;//NaN  NaN=2/undefined外邊也聲明啦 裏面也聲明  裏面的變量提升都函數的最上面 賦值還是在下面
            var a = 200;
            var c = a / 2;//100
            alert(b);
            alert(c);
    }
    testResult();
    // 5.問,輸出分別爲什麼?
    console.log('第5題的開始:');
    var tt = "MR_LP -->  QQ :3206064928";
    function test(){
            alert(tt);//undefined
            var tt = "李鵬";
            alert(tt);//李鵬
    }
    test();
// 6.實現數組翻轉用算法時間 數組的 reverse()方法
var arr1=[1,2,3,4,5,6,7,8,9,10];
function sum(arr){
    var stop=parseInt((arr.length-1)/2);
   for(let i=0;i<=(arr.length-1);i++){
       let a=arr[i];
       arr[i]=arr[arr.length-1-i];
       arr[arr.length-1-i]=a;
       if(i>=stop){
           return arr1
       }
   }
}
console.log(sum(arr1));
//7.數組求和
var arr2=[1,2,3,4,5,6,7,8,9,10];
var sum=0;
for(let i=0;i<arr2.length;i++){
    if(typeof arr2[i]=='number'){
        sum+=arr2[i];
    }
}
console.log(sum);
</script>

2.單行顯示文字超出省略號,多行超出省略號

單行:

          {
            width: 300px;
            overflow: hidden;/*超出部分隱藏*/
            white-space: nowrap;/*不換行*/
            text-overflow:ellipsis;/*超出部分文字以...顯示*/
          } 

顯示多行,超出省略號 :

overflow: hidden;
text-overflow: ellipsis;
display:-webkit-box; //作爲彈性伸縮盒子模型顯示。
-webkit-box-orient:vertical; //設置伸縮盒子的子元素排列方式--從上到下垂直排列
-webkit-line-clamp:2; //顯示的行

 

3. 斐波那契數列1 1 2 3 5 8 13 21 。。。。 求第n個數 使用遞歸實現

function demoF(n){
	if(n<=1){
		return n=1;
	}
	else if(n<=2){
		return n=1
	}else{
		return demoF(n-1)+demoF(n-2);
	}
}
console.log(demoF(7))

 

 4. 每次實例化函數的時候屬性a加1

var Obj = (function () {
      var _id = 0;
     return function obj() {
         this.id = _id++
      }
    })()
   new Obj()//{id:0};
   new Obj()//{id:1};
   new Obj()//{id:2};

 

5.找出這個字符串中的所有數字

//找出這個字符串中的所有數字
        function aaa(str) {
            //方法1:
            /*   let temp = '';
              let arr = [];
              for (let i = 0; i < str.length - 1; i++) {
                  if (!isNaN(str[i])) {
                      temp += str[i];
                  } else {
                      if (temp) {
                          arr.push(temp);
                      }
                      temp = '';
                  }
              }
              if (temp) {
                  arr.push(temp);
              } */
            //方法2:正則方式:
            let reg = /\d+/g;
            var arr = str.match(reg);
            console.log(arr);
        }
        aaa('abc123de45fgh6789qqq111');

6.求出這個字符串中出現最多的字母,並求出出現多少次(忽略大小寫)。

   var str = 'abbbbAAbcBCCccdaACBDDabcccddddaab';
        str = str.toLocaleLowerCase();
        let num = 0;
        let val = '';
        console.log(str);
        let obj = {};
        for (let n = 0; n < str.length - 1; n++) {
            if (obj[str[n]]) {
                obj[str[n]]++
            } else {
                obj[str[n]] = 1;
            }
        }
        for (let key in obj) {
            if (obj[key] > num) {
                num = key;
                val = obj[key]
            }
        }
        console.log("出現最多的是:" + val + "   這個數出現最多的是:" + num)//出現最多的是:8   這個數出現最多的是:a

7.高度不固定的容器的上下左右的居中顯示。(重點是垂直居中)

<!DOCTYPE html>
<html>
<head>
	<title></title>
	<style type="text/css">
	   
	    /*方法一:1)將父級容器設置爲:*/
	  .gao{
	/*	display:table-cell;
		vertical-align:middle;
		text-align:center;
		width:100px;	
		height:100px;
		background: #ddd;
	  }	  */
	  /*方法二:2)使用flex*/
	 /* .gao{
		display: flex;
		justify-content: center;
		align-items: center;
		width:100px;	
		height:100px;
		background: #ddd;
	  }	*/
	  /*方法三:*/
	/*  .test{
	  	position: absolute;
	  	left:50%;
	  	top:50%;
	  	margin-left:-50px;
	  	margin-top:-50px;
	  	width:100px;
	  	height:100px;
	  	border: 1px solid #aaa;
	  }*/
	  /*方法四:*/
	  /*.test{
	  	position: absolute;
	  	left:50%;
	  	top:50%;
	  	width:100px;	
		height:100px;
		background: #ddd;
		transform: translate(-50px,-50px);
	  }*/
	</style>
</head>
<body>
 <div class="gao">
 	<div class="test">dsfdsf</div>
 </div>
</body>
</html>

8.margin塌陷的問題,以及margin重疊問題。

相信很多人都知道解決父容器不設置margin的值,只給裏面的div設置一個margin-top,會有什麼樣的結果,就是父容器會margin-top == 子容器的margin-top值。

解決方案:

1)給父容器設置border:1px solid transparent;

2)padding>0

3)float

4)position:absolute;

5)display:inline-block;

6)overflow:hidden/auto;

另外一種情況:

兩個div,上面的margin-bottom:30px;下面的:margin-top:10px;中間的間距是30px;取最大的。

解決辦法:只設置一個的要麼margin-top;要麼margin-bottom

9.寫一個數組去重的方法

//也算事比較高級的一種,思路比較清晰   使用對象賦值檢測重複

 Array.prototype.unique=function(){
        let res=[];
        let obj={};
        for (let i = 0; i <this.length;i++) {
            if(!obj[this[i]]){
                res.push(this[i]);
                obj[this[i]]=1;
            }
        }
        return res;
    }
    let arr=[1,2,3,4,3,2,1,'你在他鄉還好嗎'];
    let aaa=arr.unique();
    console.log(aaa);// [1, 2, 3, 4, "你在他鄉還好嗎"]

 es6中去重方法:

Set :可以接收一個數組或者是類數組對象,自動去重。

Array.from:把類數組對象、可迭代對象轉化爲數組。

let str=[1,2,3,3,1,NaN,NaN,undefined,undefined,null,null];
console.log(new Set(str));//Set(6) {1, 2, 3, NaN, undefined, null}
console.log(Array.from(new Set(str)));//[1, 2, 3, NaN, undefined, null]
console.log([...new Set(str)]);//[1, 2, 3, NaN, undefined, null]

10.一像素1px在瀏覽器上出現視覺上的差異,顯示的粗細不一樣

出現的問題
最近做頁面,出現一個問題,頁面上有幾條線,我直接寫成height爲1px的div,結果頁面寫完了發現,命名用的同一個類名,爲什麼顯示的粗細不一樣,很確定這就是一條線,用的樣式一毛一樣的。而且瀏覽器放大縮小,變成了一會粗一會細,很鬱悶,有沒有。覺得這是瀏覽器對像素處理的問題,就麼有管。結果測試說會提bug,還是老老實實的改吧;
附加圖一張:

解決方案

第一種方式

div{
height:5px;
transform:scale(1 , 0.2);
};

先增加height的值,看增加到幾的時候,視覺上的高度會一樣,估計3px就可以了,但是不好計算所以就用了5px。
改過如下圖:

11.vue中的路由跳轉的方式都有哪些?

1.  router-link  

1. 不帶參數
 
<router-link :to="{name:'home'}"> 
<router-link :to="{path:'/home'}"> //name,path都行, 建議用name  
// 注意:router-link中鏈接如果是'/'開始就是從根路由開始,如果開始不帶'/',則從當前路由開始。
 
 
 
2.帶參數
 
<router-link :to="{name:'home', params: {id:1}}">  
 
// params傳參數 (類似post)
// 路由配置 path: "/home/:id" 或者 path: "/home:id" 
// 不配置path ,第一次可請求,刷新頁面id會消失
// 配置path,刷新頁面id會保留
 
// html 取參  $route.params.id
// script 取參  this.$route.params.id
 
 
<router-link :to="{name:'home', query: {id:1}}"> 
 
// query傳參數 (類似get,url後面會顯示參數)
// 路由可不配置
 
// html 取參  $route.query.id
// script 取參  this.$route.query.id

2.  this.$router.push() (函數裏面調用)

1.  不帶參數
 
this.$router.push('/home')
this.$router.push({name:'home'})
this.$router.push({path:'/home'})
 
 
 
2. query傳參 
 
this.$router.push({name:'home',query: {id:'1'}})
this.$router.push({path:'/home',query: {id:'1'}})
 
// html 取參  $route.query.id
// script 取參  this.$route.query.id
 
 
 
3. params傳參
 
this.$router.push({name:'home',params: {id:'1'}})  // 只能用 name
 
// 路由配置 path: "/home/:id" 或者 path: "/home:id" ,
// 不配置path ,第一次可請求,刷新頁面id會消失
// 配置path,刷新頁面id會保留
 
// html 取參  $route.params.id
// script 取參  this.$route.params.id
 
 
 
4. query和params區別
query類似 get, 跳轉之後頁面 url後面會拼接參數,類似?id=1, 非重要性的可以這樣傳, 密碼之類還是用params刷新頁面id還在
 
params類似 post, 跳轉之後頁面 url後面不會拼接參數 , 但是刷新頁面id 會消失

3.  this.$router.replace() (用法同上,push)

4.  this.$router.go(n) 

this.$router.go(n)
向前或者向後跳轉n個頁面,n可爲正整數或負整數

5.用a標籤也能跳轉 #/bbb <a href="#/bbb">跳轉a標籤</a>  需要加上#   history模式改怎麼寫就怎麼寫 eg:/aaa  這樣就可以

ps : 區別

this.$router.push
跳轉到指定url路徑,並想history棧中添加一個記錄,點擊後退會返回到上一個頁面
this.$router.replace
跳轉到指定url路徑,但是history棧中不會有記錄,點擊返回會跳轉到上上個頁面 (就是直接替換了當前頁面)

this.$router.go(n)
向前或者向後跳轉n個頁面,n可爲正整數或負整數

12.vue的路由模式及修改方法

 vue的路由模式有兩種模式History和hash模式,切換方式有兩種。
默認爲hash模式,修改爲history的方法如下,此方法也可以修改爲hash模式

路由切換模式:{hash/ history}

         對於Vue 這類漸進式前端開發框架,爲了構建SPA(單頁面應用),需要引入前端路由系統,這也就是Vue-router存在的意義。前端路由的核心,就在於——— 改變視圖的同時不會向後端發出請求。

    .  hash(#):默認路由模式

            —— 即地址欄URL中的#符號(此hsah 不是密碼學裏的散列運算)

           比如這個URL:http://www.abc.com/#/hello, hash 的值爲#/hello。它的特點在於:          hash 雖然出現URL中,但不會被包含在HTTP請求中,對後端完全沒有影響,因此改變          hash不會重新加載頁面。

    .  histroy(/)切換路由模式

              —— 利用了HTML5 History Interface 中新增的pushState() 和replaceState() 方法。(需要特定瀏覽器支持)

            * history模式,會出現404 的情況,需要後臺配置。

 404 錯誤

          1、hash模式下,僅hash符號之前的內容會被包含在請求中,如 http://www.abc.com, 因此對於後端來說,即使沒有做到對路由的全覆蓋,也不會返回404錯誤;

          2、history模式下,前端的url必須和實際向後端發起請求的url 一致,如http://www.abc.com/book/id 。如果後端缺少對/book/id 的路由處理,將返回404錯誤。 

13、組件路由守衛

// 跟methods: {}等同級別書寫,組件路由守衛是寫在每個單獨的vue文件裏面的路由守衛
beforeRouteEnter (to, from, next) {
    // 注意,在路由進入之前,組件實例還未渲染,所以無法獲取this實例,只能通過vm來訪問組件實例
    next(vm => {})
}
beforeRouteUpdate (to, from, next) {
    // 同一頁面,刷新不同數據時調用,
}
beforeRouteLeave (to, from, next) {
    // 離開當前路由頁面時調用
}

 

14.rem原理與簡介

rem是css3一種新的長度單位。在W3C中有這樣的定義:REM(Font size of the root element)是指相對於html根元素的字體大小的單位(注意這裏泛指是相對於html中的根元素標籤也就是html)。一般用於在移動端中解決多種機型適配問題。

在移動端開發時候,開發人員爲了解決不同的機型適配問題。常用mediaQue(媒體查詢)依據每種機型寫多套適配代碼。這種方法固然能解決適配問題。代碼量太多了,不美觀,且不利於維護。

用rem可以解決上述的問題。rem的核心在於通過動態設置根元素html的font-size。我們知道瀏覽器的默認的font-size是16px,(有些瀏覽器例外)。依據W3C中的描述相對於html中的根元素標籤。也就是1rem = 16px,  16px = 1rem

15.for in和for of的區別是什麼?

雖然for… in 、 for… of 都能夠變歷數組,但是兩者還是有很大區別的,先說結論:

兩者的主要區別在於他們的迭代方式

推薦在循環對象屬性的時候,使用for in,在遍歷數組的時候推薦使用for of
for…in 循環出來的是key, for…of循環出來的是value
for…in 是ES5 標準,for …of 是ES6標準,兼容性可能存在些問題,請注意使用
for…of 不能遍歷普通的對象,需要和Object.keys() 搭配使用

//遍歷數組常用的方法 map
//map
let arr=['first','second','third','four','five'];
let obj={
	name:'yangdongxu',
	age:29,
	sex:'男'
}
// let newArr=arr.map((item)=>{
//    return item.toUpperCase()
// })
// console.log(newArr); 
// console.log(arr); 
//for in
// for(let i in arr){
// 	// console.log(i);
// 	console.log(arr[i]);
// }
//遍歷對象也可以用for in   
// for(let key in obj){
// 	console.log(key);//
// 	console.log(obj[key]);
// }
//for of用來遍歷數組  直接遍歷出來的數數組的值
// for(let item of arr){
//    console.log(item);//
// }
// //for of用來遍歷對象 的時候需要 藉助Object.keys() 搭配使用
// for(let item of Object.keys(obj)){
//    console.log(obj[item]);
// }

 

16.檢測數組類型方法 

1.Object.prototype.toString 
Object.prototype.toString的行爲:首先,取得對象的一個內部屬性[[Class]],然後依據這個屬性,返回一個類似於"[object Array]"的字符串作爲結果(看過ECMA標準的應該都知道,[[]]用來表示語言內部用到的、外部不可直接訪問的屬性,稱爲“內部屬性”)。利用這 個方法,再配合call,我們可以取得任何對象的內部屬性[[Class]],然後把類型檢測轉化爲字符串比較,以達到我們的目的。

function isArrayFn (o) {
return Object.prototype.toString.call(o) === '[object Array]';
}
var arr = [1,2,3,1];
alert(isArrayFn(arr));// true 

call改變toString的this引用爲待檢測的對象,返回此對象的字符串表示,然後對比此字符串是否是'[object Array]',以判斷其是否是Array的實例。爲什麼不直接o.toString()?嗯,雖然Array繼承自Object,也會有 toString方法,但是這個方法有可能會被改寫而達不到我們的要求,而Object.prototype則是老虎的屁股,很少有人敢去碰它的,所以能一定程度保證其“純潔性”:) 

JavaScript 標準文檔中定義: [[Class]] 的值只可能是下面字符串中的一個: Arguments, Array, Boolean, Date, Error, Function, JSON, Math, Number, Object, RegExp, String. 
這種方法在識別內置對象時往往十分有用,但對於自定義對象請不要使用這種方法。

2.Array.isArray() 
ECMAScript5將Array.isArray()正式引入JavaScript,目的就是準確地檢測一個值是否爲數組。IE9+、 Firefox 4+、Safari 5+、Opera 10.5+和Chrome都實現了這個方法。但是在IE8之前的版本是不支持的。

3.較好參考 
綜合上面的幾種方法,有一個當前的判斷數組的最佳寫法:

var arr = [1,2,3,1];
var arr2 = [{ abac : 1, abc : 2 }];
function isArrayFn(value){
if (typeof Array.isArray === "function") {
return Array.isArray(value);
}else{
return Object.prototype.toString.call(value) === "[object Array]";
}
}
alert(isArrayFn(arr));// true
alert(isArrayFn(arr2));// true

17.display:none與visible:hidden的區別

display:none和visible:hidden都能把網頁上某個元素隱藏起來,但兩者有區別:

display:none ---不爲被隱藏的對象保留其物理空間,即該對象在頁面上徹底消失,通俗來說就是看不見也摸不到。

visible:hidden--- 使對象在網頁上不可見,但該對象在網頁上所佔的空間沒有改變,通俗來說就是看不見但摸得到。

18.js克隆一個對象

我們知道,對象類型在賦值的過程中其實是複製了地址,所以如果改變了一方,其他都會被改變。我們應該如何克隆一個對象,並且避免這種現象的發生呢?

方法一:Object.assign

function copy(obj){
    return Object.assign({}, obj);
}

方法二:…展開運算符

function copy(obj){
    return { …obj };
}

方法一,方法二是淺拷貝,也就是當對象層級大於2層時,複製到的還是地址信息

let a = {age:1,
         jobs: {first:'FE’} 
        }
let b = copy(a) 
a.jobs.first =‘native'
console.log(b.jobs.first)// native

 方法三:JSON

function copy(obj){
    return JSON.parse(JSON.stringify( obj ));
}

確實是深拷貝,也很方便。但是,這個方法只能適用於一些簡單的情況。比如下面這樣的一個對象就不適用:

const originObj = {
  name:'axuebin',
  sayHello:function(){
    console.log('Hello World');
  }
}
console.log(originObj); // {name: "axuebin", sayHello: ƒ}
const cloneObj = JSON.parse(JSON.stringify(originObj));
console.log(cloneObj); // {name: "axuebin"}

發現在 cloneObj 中,有屬性丟失了。。。那是爲什麼呢?

undefinedfunctionsymbol 會在轉換過程中被忽略。。

If undefined, a function, or a symbol is encountered during conversion it is either omitted (when it is found in an object) or censored to null (when it is found in an array). JSON.stringify can also just return undefined when passing in "pure" values like JSON.stringify(function(){}) or JSON.stringify(undefined).

明白了吧,就是說如果對象中含有一個函數時(很常見),就不能用這個方法進行深拷貝 

如何實現一個深拷貝呢?說起來也好簡單,我們在拷貝的時候判斷一下屬性值的類型,如果是對象,我們遞歸調用深拷貝函數不就好。



var deepCopy = function(obj) {
if (typeof obj !== 'object') return;
var newObj = obj instanceofArray ? [] : {};
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
newObj[key] = typeof obj[key] === 'object' ? deepCopy(obj[key]) : obj[key];
}
}
return newObj;
}

19.vue scoped 深度作用選擇器

 在vue中引入了scoped這個概念,scoped的設計思想就是讓當前組件的樣式不會修改到其它地方的樣式,使用了data-v-hash的方式來使css有了它對應模塊的標識,這樣寫css的時候不需要加太多額外的選擇器,方便很多。

  但是要注意scoped的作用域,因爲權重的問題,如果是在子組件使用了scoped,那麼在父組件中是不能直接修改子組件的樣式的,需要在父組件中使用vue的深度作用選擇器。

.parent >>> .children{ /* ... */ }

.parent /deep/ .children{ /* ... */ }

20.

Vue——組件上使用v-model

一、最近在工作過程中要實現一個搜索模糊匹配功能,考慮到組件的複用,就單獨把搜索框抽出來作爲一個子組件。在以往的開發中,我一般會在input框中的值變化時向父組件emit一個事件,並帶上一些父組件中需要的參數(比如搜索的關鍵詞,或者搜索之後返回的結果)

大概的實現方式如下:

父組件
<template>
    <div>
        <search @test="getData"></search>
        <button @click="submit">提交</button>
    </div>
</template>
<script>
import search from '@/components/index/search.vue'
export default {
    data() {
        return {
            keywords: ''
        }
    },
    components: {
        search
    },
    methods: {
        getData(val){
            this.keywords = val
        },
        submit() {
            console.log('keywords:', this.keywords)
        }
    }
}
</script>


子組件
<template>
    <div>
        <input @input="inputChange" type="text" name="keywords">
    </div>
</template>
<script>
export default {
    props: ['keywords'],
    methods: {
        inputChange(e) {
            this.$emit('test', e.target.value)
        }
    }
}
</script>

二、這次在實現的時候,我隱約記得在之前看Vue api的時候提到過,給組件添加v-model,就想用這種方式嘗試一下,根據官網解釋我理解:

v-model這個雙向綁定相當於做了兩個操作:(1)給當前這個組件添加了一個value屬性 (2)給當前這個組件綁定了一個input事件;由此我修改實現方式如下:

父組件:

<template>
    <div>
        <search v-model="keywords"></search>
        <button @click="submit">提交</button>
    </div>
</template>
<script>
import search from '@/components/index/search.vue'
export default {
    data() {
        return {
            keywords: ''
        }
    },
    components: {
        search
    },
    methods: {
        submit() {
            console.log('keywords:', this.keywords)
        }
    }
}
</script>

子組件:

<template>
    <div>
        <input :value="value" @input="$emit('input', $event.target.value)" type="text" name="keywords">
    </div>
</template>
<script>
export default {
    props: ['value']
}
</script>

三、總結:其實兩種思路是一樣的,都是子組件通過emit事件向父組件傳值,但是v-model的形式更直觀簡單~

21.避免v-if和v-for用在一起

v-if和v-for一起使用,v-for的優先級要高於v-if

  • 爲了過濾一個列表中的項目(比如v-for = "user in users" v-if = "user.isActive")。在這種情況下,請將users替換爲一個計算屬性(比如activeUsers),讓其返回過濾後的列表。
  • 爲了避免渲染本應該被隱藏的列表(比如v-for = "user in users" v-if = "shouldShowUsers")。這種情況下,請將v-if移動至容器元素上(比如ulol

詳解

當vue處理指令時,v-forv-if具有更高的優先級,所以這個模板:

 

<ul>
  <li
      v-for = "user in users"
      v-if = " user.isActive"
      :key = "user.id"
  >
    {{ user.name }}
  </li>
</ul>

將會經過如下運算

this.users.map(function (user) {
  if (user.isActive) {
    return user.name
  }
})

因此,哪怕我們只渲染出一小部分的用戶元素,也得在每次重新渲染的時候遍歷整個列表,不論活躍用戶是否發生了改變。

通過將其更換爲如下的一個計算屬性上遍歷:

 

computed: {
  activeUser: function () {
    return this.users.filter(function (user) {
      return user.isActive
    })
  }
}

 

<ul>
  <li
      v-for = "user in activeUsers"
      :key = "user.id"
  >
    {{ user.name }}
  </li>
</ul>

我們將會獲得如下好處:

  • 過濾後的列表只會在 users 數組發生相關變化時才被重新運算,過濾更高效。
  • 使用 v-for = "user in activeUsers"之後,我們在渲染的時候只遍歷活躍用戶,渲染更高效。
  • 解藕渲染層的邏輯,可維護性 (對邏輯的更改和擴展) 更強。

也可以把:

 

<ul>
  <li
    v-for="user in users"
    v-if="shouldShowUsers"
    :key="user.id"
  >
    {{ user.name }}
  </li>
</ul>

更新爲:

 

<ul v-if="shouldShowUsers">
  <li
    v-for="user in users"
    :key="user.id"
  >
    {{ user.name }}
  </li>
</ul>

通過將v-if移動到容器元素,我們不會再對列表中的每個用戶檢查shouldShoeUsers。取而代之的是,我們只檢查一次,且不會在shouldShoeUsers爲否的時候運算v-for

反例

 

<ul>
  <li
    v-for="user in users"
    v-if="user.isActive"
    :key="user.id"
  >
    {{ user.name }}
  </li>
</ul>

 

<ul>
  <li
    v-for="user in users"
    v-if="shouldShowUsers"
    :key="user.id"
  >
    {{ user.name }}
  </li>
</ul>

好例子

 

<ul>
  <li
    v-for="user in activeUsers"
    :key="user.id"
  >
    {{ user.name }}
  </li>
</ul>

 

<ul v-if="shouldShowUsers">
  <li
    v-for="user in users"
    :key="user.id"
  >
    {{ user.name }}
  </li>
</ul>

22.vue $router和$route的區別

一、

router爲VueRouter的實例,相當於一個全局的路由器對象,裏面含有很多屬性和子對象,例如history對象。。。經常用的跳轉鏈接就可以用this.$router.push,和router-link跳轉一樣。。。

this.$router.push會往history棧中添加一個新的記錄。。詳細見vue官方文檔https://router.vuejs.org/zh/guide/essentials/navigation.html

route相當於當前正在跳轉的路由對象。。可以從裏面獲取name,path,params,query等。。

打印this.$route和this.$router。

 

路由傳參的方式

1.可以手寫完整的path:

this.$router.push({path:`/user/${userId}`})

這樣傳遞參數的話,配置路由的時候需要在path上加參數path:user/:userId。

這種接收參數的方式是this.$route.params.userId。

2.也可以用params傳遞:

3.也可以用query傳遞:

query傳參是針對path的,params傳參是針對name的。。接收參數的方式都差不多。。this.$route.query.和this.$route.params.

注意這只是跳轉url,跳轉到這個url顯示什麼組件,得配置路由。router跳轉和<router-link>標籤跳轉,規則差不多。

展示上的話:

注意:如果提供了path,params將會被忽略,但是query不屬於這種情況。。。

如果使用完整路徑和query傳參,刷新頁面時不會造成路由傳參的參數丟失。

這個vue官方文檔講的很詳細。

二、

有時候配置路由時path有時候會加 '/' 有時候不加,例如path:'name'和path:'/name'。區別其實官方文檔說了,我當時沒仔細看,導致這個問題還困擾了我很久。

意思就是以 / 開頭的會被當做路徑,就不會一直嵌套之前的路徑。

23.異步組件

24. 實現一個方法, 獲得 url 上的參數:

  

 // 1. 實現一個方法, 獲得 url 上的參數: 
// getUrlParam('http://www.nowcoder.com?key=1&key=2&key=3&test=4#hehe'), 輸出爲一個對象 
// {key: 3, test:4}
function getUrlParam(url) { 
    //判斷是否有參數 有參數才執行
     if(url&&url.includes('?')){
           let queryStr=url.split('?')[1];//獲取問號後面的參數字符串
           //判斷是否有#
           if(queryStr.includes('#')){
               queryStr=queryStr.split('#')[0]
           }
           //字符串轉數組
          let queryArr=queryStr.split('&');
          let res={};
          //把參數放入空數組中
          for(val of queryArr){
               let key=val.split('=')[0];
               res[key]=val.split('=')[1];
          }
          console.log(res);
        return res
     }else{
         return {}
     }
}
getUrlParam('http://www.nowcoder.com?key=1&key=2&key=3&test=4#hehe');//{key: "3", test: "4"}
//思路:要想獲取當前頁面攜帶的URL參數,首先要獲取到當前頁面的地址,我們可以通過location.search來獲得。取到URL地址後,可以根據&進行數據拆分,拆分出一共有多少個參數,然後再根據=獲得參數的值 在賦值給空對象 返回要的結果 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章