vue-cli 實戰總結

文章會不定時更新!!!!請添加關注哦!!!(最後更新日期:2019,09)

也多是由於接觸vue時間也不長,常常落入不知名的‘坑’中,對於我這個菜鳥來講,每次‘落坑’無疑是一場不小的災難。前兩天有個朋友在問我,在使用vue中有沒有遇到一些很難解決的問題,一下我也只能說出一兩個,正所謂‘光說不練,假把式’,因此索性就抽時間總結一下我在項目中遇到的vue的問題,也貼出了效果圖片,這樣看起來也比較清晰。有寫的不對的地方,在您時間還容許的狀況下,還勞煩你們告訴我哦,我也好儘早修改,以避免給看文章的其餘同仁帶來沒必要要的麻煩!(當前版本:"vue@2.5.3") -------------------在此謝過!-----------css

說到vue的實戰,不得不說vue項目建立,那麼關於vue cli項目搭建,我在以前的文章中有專門寫過,可參考個人第一篇文章: vue cli 框架搭建html

  • 接下來給你們安利一個vue的網頁運行工具 iVuewRun網頁版的vue,可直接運行使用,還能夠分享給小夥伴!

每一個Vue實例在被建立以前都要通過一系列的初始化過程,這個過程就是vue的生命週期前端

方法名 狀態 含義
beforeCreate creating 所有實例建立以前,獲取不到props 和data中的數據
created creating 實例建立成功,能夠拿到data中的數據
beforeMount mounting 此時data裏面的數據和模板已生成html
mounted mounting 掛載結束,模版中的 data 數據直接顯示出來了,此時通常能夠作一些ajax操做
beforeUpdate updating 當 data 數據發生變化調用,發生在虛擬 DOM 從新渲染和打補丁以前
updated updating 數據更改致使的虛擬 DOM 從新渲染和打補丁
beforeDestroy destroying 在 vue 實例銷燬以前調用,此時實例任然可用,通常在這一步作一些重置的操做,好比清除掉組件中的定時器 和 監聽的dom事件
destroyed destroying 在 vue 實例銷燬以後調用,vue 實例指示的全部東西都會解綁定,全部的事件監聽器會被移除,全部的子實例也會被銷燬

⚠️注意:vue

  1. 若是在created階段的發送ajax請求,此時頁面視圖未出現,若是請求信息過多,頁面會長時間處於白屏狀態,請求建議放在mounted階段,固然mounted 不會承諾全部的子組件也都一塊兒被掛載。若是你但願等到整個視圖都渲染 完畢再發生請求,能夠用 vm.$nextTickwebpack

  2. 子組件完成掛載後,父組件纔會掛載,銷燬父組件時,先將子組件銷燬後纔會銷燬父組件ios

參考地址web

vue的父組件和子組件生命週期執行順序:

加載渲染過程ajax

父beforeCreate -》父created -》父beforeMount-》子beforeCreate -》子created-》子beforeMount-》子 mounted-》父mouted
複製代碼

子組件更新過程:正則表達式

父beforeUpdate -》子 beforeUpdate -》子 update -》父update
複製代碼

父組件更新過程:vue-router

父beforeUpdate -》父update
複製代碼

銷燬過程:

父beforeDestroy -》子beforeDestroy -》子 destroy  -》父 destroy
複製代碼

分享:自用的vue模版

<template>
   <div>
   </div>
</template>

<script>
   export default {
       props:{},
       data() {
           return {}
       },
       computed:{},
       components: {},
       created(){},
       mounted() {},
       methods: {},
       watch: {},
       destroyed(){},
   }
</script>

<style scoped lang="less">
</style>
複製代碼

1、添加css的多種方式。

vue的每一個組件中,能夠自定義cssjs,那麼若是隻但願當前的css只在當前頁面生效,能夠在style 的標籤這樣書寫,這樣當前頁面的全部css樣式,除當前組件,不會在其餘組件生效而且不會影響到其餘組件頁面渲染。

<style scoped> </style>
複製代碼

若是你引入來sass到vue項目中,那麼只需在當前組件添加lang屬性便可:

sass $

<style scoped lang="scss"> </style>
複製代碼

亦你的項目引入的不是sass,是less,也是一樣更改lang屬性便可:

less @:

<style scoped lang="less"> </style>

複製代碼

動態傳入style值的幾種方式:


1.正常class樣式:

<template>
<div>
    <p class="fs20">1.正常class樣式: 2018年8月27日</p>
</div>
<template>

<style>
    .fs20 {
        font-size: 20px
    }
</style>
複製代碼

頁面展示:


對於多個"../../../"查找引入文件時,能夠先跳到最外層,即src層開始查找

關於引入外部的less文件或者img圖片:

~@/xxx/...
複製代碼

關於引入外部js、template、component:

@/xxx/...
複製代碼

2.根據data中的className對應的class,可用於動態切換class:

<template>
<div>
    <p :class="className">2.動態切換class的值</p>
</div>
<template>
<script>
    export default {
        data() {
            return {
                className: "classA"
            }
        },
        components: {},
        mounted() {},
        methods: {},
        watch: {}
    }
</script>

<style>
    .classA {
        color: yellowgreen
    }
</style>
複製代碼

頁面展現:


3.給當前的class添加判斷:當isOktrue時添加class,爲false時不添加:

<template>
<div>
    <p :class="{colorRed:isOk}">
        3.添加判斷:當isOk爲true是添加class,爲false時不添加
    </p>
    <Checkbox v-model="isOk">Checkbox</Checkbox>
</div>
<template>
<script>
    export default {
        data() {
            return {
                isOk: true,
            }
        },
        components: {},
        mounted() {},
        methods: {},
        watch: {}
    }
</script>

<style>
   .colorRed {
        color: red
    }
</style>
複製代碼

頁面展現:


4.以數組的方式,一次添加多個class:

<template>
<div>
    <p :class="[classC,classD]">4.以數組的方式,一次添加多個class</p>
</div>
<template>
<script>
    export default {
        data() {
            return {
                classC: "classC",
                classD: "classD"
            }
        },
        components: {},
        mounted() {},
        methods: {},
        watch: {}
    }
</script>

<style>
 .classC {
        font-size: 16px;
        font-weight: 600;
    }
    .classD {
        color: blue
    }
</style>
複製代碼

頁面展現:


5.使用三元運算符判斷切換class樣式,當isOktrue時用的是classA,當爲false的時候用的是classB:

<template>
<div>
    <p :class="isOk?classA:classB">5.使用三元運算符判斷切換class樣式</p>
</div>
<template>
<script>
    export default {
        data() {
            return {
                isOk: true,
                classA: "classA",
                classB: "classB"
            }
        },
        components: {},
        mounted() {},
        methods: {},
        watch: {}
    }
</script>

<style>
   .classA {
        color: yellowgreen
    }
    .classB {
        color: green
    }
</style>
複製代碼

頁面展現:

6.綁定動態的style的樣式:

<template>
<div>
    <p :style="{color:color,fontSize:font}">6.綁定style的樣式</p>
</div>
<template>
<script>
    export default {
        data() {
            return {
                color: "red",
                font: "18px",
            }
        },
        components: {},
        mounted() {},
        methods: {},
        watch: {}
    }
</script>

<style>
 
</style>
複製代碼

頁面展現:

7.給style 綁定對象:

<template>
<div>
    <p :style="styleObject">7.給style 綁定對象</p>
</div>
<template>
<script>
    export default {
        data() {
            return {
             styleObject:{
                color:"pink",
                fontWeight:"600"
            }
        },
        components: {},
        mounted() {},
        methods: {},
        watch: {}
    }
</script>

<style>
 
</style>

複製代碼

頁面展示:

2、關於循環中的imgsrc賦值的問題

vue中的循環是使用v-for 來實現的,在標籤中注入v-for,在接下來使用到的地方就能夠直接使用。

<template>

    <div  v-for="item in cityList">

        <div>城市名稱:{{item.title}}</div>

        <div>城市ID:{{item.id}}</div>

        <div>城市圖片:<img src={{item.img}}></div>  //這行是報錯的

    </div>

</template>

<script>
     export default:{
         data(){
            return:{
                cityList:[{
                   title:'北京',
                        id:001,
                        img:'static/logo.png'
             },
             {
                   title:'上海',
                        id:002,
                        img:'static/logo.png'
             }]
         }
        }
    }

</script>
複製代碼

報錯以下:(這裏意思是在「src」屬性插值將致使404請求。使用v-bind:src 簡寫爲:src 代替)

[HMR] bundle has 1 errors
client.js?d90c:161 ./~/_vue-loader@12.2.2@vue-loader/lib/template-compiler?{"id":"data-v-60d18b79","hasScoped":true,"transformToRequire":{"video":"src","source":"src","img":"src","image":"xlink:href"}}!./~/_vue-loader@12.2.2@vue-loader/lib/selector.js?type=template&index=0!./src/components/vuetest.vue
(Emitted value instead of an instance of Error) 
  Error compiling template:
  
  <div>
     <h1>vue測試頁面</h1>
     
       <div  v-for="item in cityList">
  
            <div>城市名稱:{{item.title}}</div>
  
            <div>城市ID:{{item.id}}</div>
  
            <div>城市圖片:<img src="https://user-gold-cdn.xitu.io/2017/11/26/15ff7324b8313b05"></div>  
  
     </div>
  </div>
  
  - src="https://user-gold-cdn.xitu.io/2017/11/26/15ff7324b8313b05": Interpolation inside attributes has been removed. Use v-bind or the colon shorthand instead. For example, instead of <div id="{{ val }}">, use <div :id="val">.

 @ ./src/components/vuetest.vue 10:2-340
 @ ./src/router/index.js
 @ ./src/main.js
 @ multi ./build/dev-client ./src/main.js

複製代碼

由於vue官網在介紹v-bind時,不能夠再使用{{}},例如href的兩種使用:

<template>
    <div>
        <a :href='msg'>獲取動態數據</a> 
        <a href='http://www.baidu.com'>百度</a> 
    </div>    
</template>
<script>
   export default:{
        data(){
          return:{
            msg:'http://www.baidu.com'
          }  
       }

}
</script>

複製代碼

正確代碼以下:

<template>

    <div  v-for="item in cityList">

        <div>城市名稱:{{item.title}}</div>

        <div>城市ID:{{item.id}}</div>

        <div>城市圖片:<img :src='item.img'></div>  

    </div>

</template>

<script>
     export default:{
         data(){
            return:{
                cityList:[{
                   title:'北京',
                        id:001,
                        img:'static/logo.png'
             },
             {
                   title:'上海',
                        id:002,
                        img:'static/logo.png'
             }]
         }
        }
    }
</script>
複製代碼

3、關於v-ifv-show的區別

在vue中有兩種隱藏元素的方式,那就是 v-ifv-show,可是二者有什麼區別呢?何時用v-if,何時用v-show呢?

  • 1.先說最大的區別,`v-if` 經過條件判斷來渲染條件塊,當爲假值時,當前條件塊的全部`DOM`元素不進行渲染;`v-show`一樣也是條件判斷,但若是`v-show`的值爲假值時,當前條件塊雖不會在頁面顯示,但已經渲染完畢,只是屬性設置成了`display:none`.總結就是`v-if` 是經過條件判斷來添加和刪除`DOM`元素。`v-show`是經過`display:block`和`display:none`來控制元素的顯示隱藏。
  • 2.`v-if` 是有惰性的,若是初始條件爲假值,則直接什麼也不作,只有在條件變爲真時纔開始局部編譯;`v-show`是在任何條件都被編譯,而後被緩存,並且`DOM`元素保留,即便爲假值時,在後臺仍然能夠看到`DOM`元素已經被渲染出來。
  • 3.`v-if`適合在條件不太可能變化時使用,v-show適合頻繁切換。
  • 4.`v-if`後面能夠跟`v-else`,或`v-else-if`,但`v-show`不能夠

    v-ifv-show兩個值都爲true時的渲染結果,都正常渲染

    v-ifv-show的值都爲假值時:頁面沒有渲染,v-if未渲染dom元素,v-show渲染成功,但被添加了styledisplay:none

    4、關於在vue中如何操做DOM元素。

    咱們都知道vue框架中咱們通常操做的都是數據,那麼假如咱們要操做dom元素使用什麼方法呢?下面就來介紹一下!

    假若有如下元素,咱們要獲取這個h2元素的文本,須要給此元素添加ref屬性,並賦予名字。

    <h2 ref='foo'>我是ref的值</h2>
    複製代碼

    接下來就可使用這個方法獲取到它的文本(注意是this.$refs不是this.$ref):

    console.log(this.$refs.foo.innerHTML') 複製代碼

    那麼如何改變h2中的文本呢?

    this.$refs.foo.innerHTML='我是新值 複製代碼


    這樣就能夠和之前同樣,輕鬆的操做dom元素了,可是vue仍是以操做數據爲核心,因此建議儘可能少的使用以上方法。

    5、探究router-link中的tag屬性。

    vue路由的router-link標籤中有一個屬性tag,是我今天在查閱資料時發現的,感受比較有意思,推薦給你們。

    那麼咱們就給<router-link to='/about'>的標籤上添加上tag屬性,並賦值:

    <router-link to='/fenceCenter' >中心點</router-link>
    <router-link to='/vuetest'tag='li'>vue測試</router-link>
    複製代碼

    那麼咱們看看它和咱們正常渲染的有什麼不一樣



  • 上面的是咱們正常渲染的 vue會自動解析成``標籤的形式;
  • 下面是咱們加了`tag`屬性的渲染成了賦值的`
  • `標籤。

    是否是很神奇呢? tag除了能夠賦值li,還能夠賦值成你想要的全部的標籤哦! p,span,h1,div....均可以哦!快去動手試試吧!!


    6、vue中的指定路由跳轉router

    在咱們的實際業務中,有時須要在某一組件內,點擊一個按鈕或者是點擊一個連接切換跳轉到其餘組件,也就是跳轉路由,咱們能夠試試下面的方法:

    //直接跳轉
    this.$router.push('/map')
    
    //條件容許時跳轉
    if(this.data){
        this.$router.push('/map')
    }
    複製代碼

    注意:router須要掛在到vue實例上,這樣才能夠獲取到this.$router,並且push後面的括號中的路由地址,也須要在vuerouter中有註冊,最後,在('')中填寫你須要跳轉的路由便可完成跳轉。

    7、vue的路由router中的go方法

    上面剛剛有講到路由router,接下來再講一個和router相關的方法go,這個方法是用做前進後退導航來使用的,有時實際業務須要咱們添加一個返回上一頁面的功能,那麼咱們就能夠用go來實現。當爲‘-1’時就能夠後退到上一個路由頁面。

    this.$router.go('-1')
    複製代碼

    8、輕鬆編寫vue組件

    vue是一個單頁面應用,那麼就會涉及到組件的問題,例如A頁面爲一個主頁面,A1,A2,A3爲3個子頁面,A1,A2,A3頁面的內容分別比較複雜,須要單頁面來編輯,這時咱們就須要把A1,A2,A3寫成3個組件,而後所有加載A的主頁面上;又或有這樣的狀況,當子頁面的複用率比較高時,一樣能夠採起使用組件的方式來實現。總之,你能夠把你想實現的寫成組件,這樣第一方便修改,第二頁面乾淨整潔,第三;讓別人看起來一目瞭然。 下面咱們就看看,組件究竟是怎麼實現吧!!!

    A頁面:

    <template>
      <div>
        <h2 style="color:red">我是主頁面</h2> 
        <content><content>      //我是添加的組件
      </div>
    </template>
    
    <script>
    import content from './content'    //找到組件的位置,引入
      export default {
        name: "",
        data() {
            return {
            }
        },
       components:{
          content      //將組件寫入模板內纔可生效,當有多個組件,看用逗號分開
       },
        mounted() {
        },
        methods: {}
      }
    </script>
    
    <style scoped>
    </style>
    複製代碼

    A頁面的子頁面(content組件頁面): 組件頁面就是普通頁面,固然組件頁面的事件也是會帶到主頁面的。

    <template>
    
      <div @click="foo()">我是組件頁面</div>
      
    </template>
    <script>
      export default {
        name: "",
        data() {
          return {
          }
        },
        mounted() {
        },
        methods: {
            foo(){
                alert("我是好人")
            }
        }
      }
    </script>
    
    <style scoped>
    </style>
    複製代碼

    這時咱們來看一下效果:



    這樣你想要的效果就有了哦!

    那麼還須要注意一點:若是你的組件名字是駝峯式寫法,那麼按照如下方式修改:

    <template>
    
      <div>我是主頁面<content-f> </content-f>   //這裏要這樣寫</div>
      
    </template>
    <script>
    import contentF from './contentF'         //找到組件的位置 引入
      export default {
        name: "",
        data() {
            return {
            }
        },
       components:{
          contentF     //將組件寫入模板內纔可生效,當有多個組件,看用逗號分開
       },
        mounted() {
        },
        methods: {}
      }
    </script>
    
    <style scoped>
    </style>
    
    複製代碼

    9、在vue中觀察者watch的用法

    vue的官網是這麼介紹的:把它命名爲 觀察者模式 雖然計算屬性在大多數狀況下更合適,但有時也須要一個自定義的 watcher。這是爲何vue經過watch。 選項提供一個更通用的方法,來響應數據的變化。當你想要在數據變化響應時,執行異步操做或開銷較大的操做,這是頗有用的。 通俗點講,就是在vue中有一個watch,它能夠監聽你的數據是否發生變化,一旦發生變化,能夠進行某些操做,那麼咱們就來試試:

    <template>
       <div>
           <button @click="foo()">點擊按鈕</button>
           <div>{{value}}</div>
       </div>
    </template>
    <script>
       export default {
           name: "",
           data() {
               return {
                   value:1,
               }
           },
           mounted() {},
           watch:{
               value:function(val,oldval){
                   console.log(val,oldval)
               }
           },
           methods: {
               foo() {
                   this.value=5
               }
           }
       }
    </script>
    
    <style scoped>
    </style>
    複製代碼

    咱們點擊一下,看一下結果:當value被改變時,會在後臺打印出當前的值和改變前的值:



    但當咱們再次重複上一次的動做時,並不會再次打印結果,那是由於value值改變成5後,再次點擊,仍是一樣的值,value的值並無再次發生變化。


    watch 裏面有一個deep的參數,能夠監聽object中屬性的變化。(咱們上面使用的是number,而一樣使用上面的方法,並不能監聽到對象的屬性值的變化) 下面咱們來使用deep來檢測一下對象屬性:

    <template>
        <div>
            <button @click="foo()">點擊按鈕</button>
            <div>{{value}}</div>
        </div>
    </template>
    <script>
        export default {
            name: "",
            data() {
                return {
                    value:{
                        a:1,b:2
                    }
                }
            },
            mounted() {},
            watch:{
                value:{
                    handler(val,oldVal){
                        console.log("lalala",val,oldVal)
                    } ,
                    deep: true,
                    immediate: true
                }
            },
            methods: {
                foo() {
                    this.value.a=5;
                    this.value.b=6;
                }
            }
        }
    </script>
    
    <style scoped>
    </style>
    
    
    複製代碼

    10、關於assetsstatic的區別,靜態資源到底該放哪裏?

    在咱們搭建好的vue-cli的項目中會自動給咱們建兩個文件夾來存放咱們的數據,圖片之類的資產,這兩個分別是assetsstatic兩個,那麼咱們怎麼來區分這兩個文件夾呢?在經過直譯咱們瞭解到assets的中文意思爲資產,而static的中文意思爲靜態的,靜止的

    緣由以下:

    assets目錄中的文件會被webpack處理解析爲模塊依賴,只支持相對路徑形式。

    static/ 目錄下的文件並不會被webpack處理:它們會直接被複制到最終的打包目錄(默認是dist/static)下。

    下面來一段代碼,來現身說法:

    <template>
     <div class="hello">
       <div v-for="item in cityList" :key="item.id">
           <div >{{item.title}}</div>
           <div>城市圖片:<img :src="item.img"></div>
       </div>
     </div>
    </template>
    
    <script>
     export default {
       name: 'HelloWorld',
       data() {
         return {
           cityList: [{
               title: '北京',
               id: "001",
               img:"../assets/logo.png" //這行是不被識別的
             },
             {
               title: '上海',
               id: "002",
               img: "static/logo.png" //這個能夠被正確顯示
             }
           ]
         }
       }
     }
    </script>
    
    
    
    複製代碼

    頁面展現效果以下:


    那麼咱們看看在不寫在js中的圖片引入是否也會出現問題呢?

    <template>
      <div class="hello">
        <img src="../assets/logo.png" alt="logo"> 
        <img src="static/logo.png" alt="logo"> 
      </div>
    </template>
    
    <script>
      export default {
        name: 'HelloWorld',
        data() {
          return {
           
          }
        }
      }
    </script>
    
    
    
    複製代碼

    來看一下頁面的反應:


    效果證明,咱們在html中的引入方式是不會受到影響的。 那若是咱們必需要在js中使用assets中的圖片,該怎麼寫呢?

    <template>
      <div class="hello">
        <div v-for="item in cityList" :key="item.id">
          <div >{{item.title}}</div>
          <div>城市圖片:<img :src="item.img"></div>
        </div>
      </div>
    </template>
    
    <script>
      export default {
        name: 'HelloWorld',
        data() {
          return {
            cityList: [{
                title: '北京',
                id: "001",
                img:require("../assets/logo.png") //使用require()的方式引入便可
              },
              {
                title: '上海',
                id: "002",
                img: "static/logo.png"
              }
            ]
          }
        }
      }
    </script>
    
    
    複製代碼

    好啦,接下來就是見證奇蹟的時刻了!!


    綜上所述,總結爲如下兩點:

    1.任何放在 static中文件須要以絕對路徑的形式引用:/static/imgurl

    2.static放不會變更的文件,assets放可能會變更的文件。

    參考:juejin.im/post/59be4d… OBKoro1


    11、關於打包後空白頁面的問題

    vue-cli在執行 npm run build 打包後,

    會在dist 目錄下生成如下文件
    但是當咱們執行命令打包後,打開index.html的時候,顯示空白頁面,並且報錯,指明文件找不到,以下:

    接下來讓咱們打開cofig文件夾的index.js,找到build這個對象,將

    assetsPublicPath: '/'
    複製代碼

    這個路徑地址改爲

    assetsPublicPath: './',
    複製代碼

    從新執行命令,從新打包,再打開index.htnl,頁面便可顯示:

    assetsPublicPath屬性做用是指定編譯發佈的根目錄,'/'指的是項目的根目錄 ,'./'指的是當前目錄。當咱們打包後,index和static是放在dist目錄下,而static是和index是平級的,因此不該該在根目錄查找文件。

    參考:juejin.im/post/59ca4b… OBKoro1

    12、關於異步懶加載路由的寫法

    在vue-cli自帶的腳手架的路由是以下這樣寫的:

    import Vue from 'vue'
    import Router from 'vue-router'
    import bus from '../bus'
    
    import HelloWorld from '@/components/HelloWorld'
    
    Vue.use(Router)
    
    export default new Route({
      routes: [
        {
        path: '/',
        name: 'HelloWorld',
        component: HelloWorld
       
        },
       
      ]
    });
    
    
    複製代碼

    使用的是import 的方式引入進來的,那麼咱們須要使用異步的方式,該怎麼寫呢?

    import Vue from 'vue'
    import Router from 'vue-router'
    import bus from '../bus'
    
    Vue.use(Router)
    
    var router = new Router({
      routes: [
        {
          path: '/',
          name: 'HelloWorld',
          component: (resolve) => require(['@/components/HelloWorld'], resolve),
        },
        {
          path: '/login',
          name: 'login',
          component: (resolve) => require(['@/login'], resolve),
          
        }
      ]
    });
    bus.router = router
    
    export default router
    
    
    複製代碼

    第二種方式:

    const Index = () => import( '@/views/index')
    const routers = [
        {
            path: '/',
            name: 'index',
            component: Index
        }
    ]
    
    
    複製代碼

    十3、寫一個自定義指令

    在vue中除了能夠寫組件,還可使用自定義指令來實現某些特殊的操做,下面就拿一個相似官方的獲取input焦點的「基本款」的栗子🌰來演示。 我有個習慣,就是把相同的東西歸類,因此,我先去建了一個文件夾來存放個人指令,以下圖:

    詳細代碼以下: 在這裏定義並導出個人自定義指令,指令裏包含我想實現的操做。(當前是一個獲取焦點的示例

    export const focus = (el) => {
        el.focus()
    }
    
    複製代碼

    在使用的頁面,首先將指令文件引入,而後配置到directive中,在須要使用到標籤內添加,注意指令前需添加:」v-「,以下所示: 個人指令name爲focus,在標籤內寫成 「v-focuss」:

    <template>
      <div>
      <input type="text" v-focus>
      </div>
    </template>
    
    <script>
     import { focus } from "../../directives/index"
      export default {
        name: "",
        data() {
            return {}
        },
        directives: {focus}, //自定義指令
        components: {},
        mounted() {},
        methods: {}
      }
    </script>
    
    <style scoped>
    
    </style>
    
    複製代碼

    今日在掘金閒逛,看到vue的偏門操做,分享給你們: juejin.im/post/5adc99…

    vue的自定義指令直接操做dom較方便:

    先看directives/index頁面 :

    接下來看一下調用頁面:

    最後咱們來看一下頁面:

    再升級!添加參數的自定義指令

    頁面的數據也能夠寫成一個變量,使用變量來控制樣式:

    下面是自定義指令的生命週期(咱們能夠在指令的生命週期中作咱們想處理的事件): 1.bind:只調用一次,指令第一次綁定到元素時調用,用這個鉤子函數能夠定義一個綁定時執行一次的初始化動做。 2.inserted:被綁定元素插入父節點時調用(父節點存在便可調用,沒必要存在於document中)。 3.update:被綁定於元素所在的模板更新時調用,而不管綁定值是否變化。經過比較更新先後的綁定值,能夠忽略沒必要要的模板更新。 4.componentUpdated:被綁定元素所在模板完成一次更新週期時調用。 5.unbind:只調用一次,指令與元素解綁時調用

    好啦!大功告成,小夥伴們,動手試試吧!

    十4、關於打包後大圖片請求不到到問題

    今日在項目完成後,進行打包測試,本地開發好好的,但打包後發現登陸頁面到背景圖片拿不到,可是其餘logo小圖片是能夠正常顯示,因而就很鬱悶,第一反應,想着應該是圖片太大了,未被壓縮,而後,就找到了以下位置:

    想着把limit的範圍放大,但是那若是還有更大的圖片呢?這並非個優雅的辦法。因而想到了萬能到度娘,就有了以下解決方法: my.oschina.net/u/1778998/b… css引入圖片再打包後,style-loader沒法設置本身的publicPath,因此只要改變style-loader中的publicPath便可,在build/util.js文件中ExtractTextPlugin的css路徑,手動添加publicPath參數。

    添加後,再執行一次build,圖片就能夠正常顯示。

    十5、跳過無需編譯及避免出現{{}}

    在咱們的項目中應該會有不少情景,標籤內的內容是不須要編譯的,但是咱們的代碼並不知道,vue提供了一個能夠直接跳過編譯的指令,供咱們添加在純靜態標籤上。

    <div  v-pre> 直接跳過不須要編譯的標籤,加快編譯效率</div>
    複製代碼

    還有一種情形,在頁面有用到{{}}賦值時,有時咱們頁面阻塞或加載跟不上、頻繁刷新時,可能會顯示未賦值的{{}},等拿到值後才能更新出來,這樣給用戶一種很不友好的體驗,一樣vue也幫咱們想到了,vue提供了一個能夠等待編譯結束,纔會顯示標籤內容到指令.

    <div v-cloak> {{message}}直接結束編譯,避免出現閃爍花括號,配合css樣式書寫</div>
    
    //配合css 樣式完成
    <style scoped>
        [v-cloak]{display: none;}
    </style>
    複製代碼

    十6、寫一個自定義過濾器

    vue有本身自帶的過濾器供咱們使用,那咱們如何來寫一個自定義過濾器呢?下面跟我一塊兒操做吧!

    先去建立一個filter文件夾,來存放你的過濾器,並在文件中寫出你想執行的過濾器的方法

    在頁面的調用(相似自定義指令)

    OBKoro1 的《你或許不知道的Vue的這些小技巧》很實用,推薦給你們!

    十7、vuex的簡單實現

    咱們都知道vuex是用來實現vue各個組件數據傳輸功能的,不區分父子組件,全局便可調用,讓咱們的工程有了一個總的title,下來就讓試試: 先來建一個store,用來存放咱們的初始化狀態,以及更改的方法:

    接下來讓咱們引入必備的依賴,以及相應的默認導出:

    代碼以下:

    import Vue from 'vue';
    import Vuex from 'vuex';
    import { state as userState, actions as userActions, mutations as userMutations } from './stores.js';
    
    Vue.use(Vuex);
    
    const state = Object.assign({}, userState);
    const mutations = Object.assign({}, userMutations);
    const actions = Object.assign({}, userActions);
    
    
    export default new Vuex.Store({
        state,
        mutations,
        actions
    });
    
    複製代碼

    最後讓咱們來寫一下定義的初始值以及須要改變的方法:

    代碼以下:

    import {appRouter} from '../assets/data/menu';
    
    // 初始值
    export const state = {
        data: "0",
        menuList: appRouter,
        pageTitle:'初始值'
    
    }
    
    //如何改變 setData方法名
    export const mutations = {
        setData(state, val) {
            state.data = val
        },
        changePage(state,val){
            state.pageTitle = val
        }
    
    }
    //實現改變
    export const actions = {
        setData(contex, val) {
            contex.commit("setData", val)
        },
        changePage(contex,val){
            contex.commit("changePage", val)
        }
    }
    複製代碼

    使用頁面,直接調用便可,不用其餘依賴:

    // 獲取全局變量
     console.log( this.$store.state.pageTitle)  // 初始值
     
     
     
    // 更改全局變量
    this.$store.commit('changePage', '門店管理')
    複製代碼

    十8、經過路由傳參,獲取參數,用於記錄狀態等

    以下圖狀況:

    咱們須要在點擊操做列的詳情進入下一個頁面,那麼咱們是須要拿到此行的id 值,而且請求數據,而後再去渲染頁面,那麼咱們如何經過路由來實現參數的傳遞呢? 借鑑

    第一種:經過path,query 來傳參,參數會在地址欄中顯示

    // 傳參
    <div>
        <router-link tag="a" :to="{path:'detail',query:{id:1}}" >詳情</router-link>
    </div>
    複製代碼
    // 接收參數
    <script>
    export default{
        mounted (){
           const id = this.$route.query.id;   //能夠拿到從列表頁傳過來的id  
        }
    }
    
    </script>
    複製代碼

    第二種:經過name,param 來傳參,參數不會在地址欄中顯示

    // 傳參
    <div>
        <router-link tag="a" :to="{name:'detail',params:{id:1}}" >詳情</router-link>
    </div>
    複製代碼
    // 接收參數
    <script>
    export default{
        mounted (){
           const id = this.$route.params.id;   //能夠拿到從列表頁傳過來的id  
        }
    }
    
    </script>
    複製代碼

    **⚠️注意:取參數時用的是this.$route,而不是this.$router

    上面兩個大同小異,接下來咱們試試傳動態的參數:

    // 傳參
    <div>
        <router-link tag="a" :to="{name:'detail',params:{id:val}}" >詳情</router-link>
    </div>
    複製代碼
    // 接收參數
    <script>
    export default{
        data () {
            val:1212
        },
        mounted () {
           const val = this.$route.params.val;   //能夠拿到從列表頁傳過來的val值  
        }
    }
    
    </script>
    複製代碼

    繼續升級,接下來咱們試試,傳多個動態參數,每一個key用逗號分割便可:

    // 傳參
    <div>
        <router-link tag="a" :to="{name:'detail',params:{id:id,name:name,age:age}}" >詳情</router-link>
    </div>
    複製代碼
    // 接收參數
    <script>
    export default{
        data () {
            id:1212,
            name:"張小一",
            age:10
        },
        mounted () {
           const id = this.$route.params.id;   //能夠拿到從列表頁傳過來的id值 
           const name = this.$route.params.name;   //能夠拿到從列表頁傳過來的name值  
           const age = this.$route.params.age;   //能夠拿到從列表頁傳過來的age值  
        }
    }
    
    </script>
    複製代碼

    再升級,咱們接下來傳一個數組改如何操做

    // 傳參
    <div>
        <router-link tag="a" :to="{name:'detail',params:{list:[1,2,3,4]}}">詳情</router-link>
    </div>
    複製代碼
    // 接收參數
    <script>
    export default{
        data () {
           arr:
        },
        mounted () {
           const list = this.$route.params.list;   //能夠拿到從列表頁傳過來的list數組  
        }
    }
    
    </script>
    複製代碼

    !!!⚠️注意:通常狀況下不建議使用路由傳過多的參數

    十9、關於跳轉路由後,清楚計時器的解決方法

    某天有看到一篇大佬的文章,講述的是跳轉頁面後,原頁面計時器仍然在執行的問題,正好本身也有寫國一個實時的鐘表的demo,因而就實驗了一番:

    頁面以下:

    在每次進入頁面後調用了setTimeout,每秒去更新時間,爲了驗證切換路由後,是否還會調用計時器,我在計時器後面加了一個打印數值來觀察,以下:

    ...
    ...
    ...
     this.inif.oSecond = seconds;
     this.inif.seconds = seconds * 6;
     this.inif.minute = minutes * 6 + seconds * (6 / 60);
     this.inif.hour = (hours - 12) * 30 + minutes * (360 / 12 / 60);
     
     //調用計時器
     this.timer = setTimeout(this.time, 1000)
     
     //打印參考值
     console.log(this.inif.seconds)
    複製代碼

    能夠看到後臺的打印狀況:

    如今咱們切換路由去往其餘的頁面,看看計時器是否中止:

    實際證實,它並無中止,計時器依然在執行。這樣是很是消耗性能的。接下來咱們來看看,大神是怎麼解決的:

    第一種解決方案:

    beforeDestroy 生命週期內進行清除:

    beforeDestroy() {
        clearInterval(this.timer);
        this.timer = null;
    }
    
    複製代碼

    鑑於上面的方法,大神給出解釋:咱們的代碼獨立於清理代碼,此種操做使得咱們比較難於程序化的清理咱們創建的全部東西。

    第二種解決方案:

    經過$once來監聽定時器,在beforeDestroy鉤子能夠被清除

    ...
    ...
    ...
    
    this.timer = setTimeout(this.time, 1000)
    
    this.$once('hook:beforeDestroy', () => {
        clearInterval(this.timer);
    })
    
    複製代碼

    兩種解決方案均可以將咱們的問題解決,相對來講第二種較優雅!!! 借鑑於 chinaBerg 大神

    二10、關於打包後在dist文件夾的js裏面會有不少.map文件

    項目打包後,代碼都是通過壓縮加密的,若是運行時報錯,輸出的錯誤信息沒法準確得知是哪裏的代碼報錯。而生成的.map後綴的文件,就能夠像沒有加密的代碼同樣,能夠準肯定位到錯誤的位置,能夠經過設置來不生成該類文件,由於咱們在生成環境是不須要.map文件的,因此能夠在打包時不用生成這些文件。

    解決方案:

    在config/index.js文件中,設置productionSourceMap: false,就能夠不生成.map文件

    二11、監聽當前vueurl路徑,發生變化時刷新頁面

    此需求是因爲項目中一個列表中詳情點擊後須要從新請求當前列的id,從新繪製當前頁面,以下:

    首先我將我須要跳轉的信息使用組合完整,以下:

    this.$router.push({
                        path: '/crowdmanage/crowddetails',
                        query: {
                            name: 'detail',
                            id: 17
                        }
                    });
    複製代碼

    點擊後url確實發生了變化,但vue並無檢測到,也就是url變化了,頁面並無從新去請求??????究竟是什麼狀況????---(此時第一感受是:個人跳轉方式哪裏出現了問題嗎?爲何vue 檢測不到呢?或者我要換成原生的跳轉??.....) 去諮詢了團隊的前端小哥哥,小哥哥給出瞭如下方式解決:---》》》》

    因爲個人頁面組件裏面嵌套了小的組件,因此我須要在跳轉到的.vue的頁面添加:

    watch: {
                $route(to, from) {
                    this.initData();
                }
            }
    複製代碼

    this.initData()是全部的請求信息,當url發生變化後,watch就能夠監聽到,而後從新去請求數據。啦啦啦啦啦 解決了。。。。。感謝小哥哥!!!

    二12、編寫動態組件

    此時場景爲:當一個組件裏面有3塊內容,並且這三塊內容每次展現都只展現一個tab,不會同時展示,以下圖:

    此時,咱們能夠把這三個寫成動態組件,將其包裹在一個index文件裏。

    首先,咱們先建一個主index文件,用於包裹三個子文件,再建三個子的.vue文件,這四個文件並列便可。

    index.vue 主文件內容以下(如下tabs來自UI組件iview):

    <template>
        <div>
            <Tabs size="small" @on-click="tabChange" v-model="tabContent">
                <TabPane v-for="(item,index) in tabList" :key="index" :label="item.label" :name="item.name"></TabPane>
            </Tabs>
            <--用:is的方式綁定動態變量,變量改變,隨之顯示的組件切換-->
            	<component :is="tabView"></component>
        </div>
    </template>
    
    <script>
      //引入三個子組件
        import A from "./A"
        import B from "./B"
        import C from "./C"
        export default {
            data() {
                return {
                    tabContent:"",
                    tabView: "",
                    tabList: [{
                            name: "a",
                            label: "標籤a"
                        },
                        {
                            name: "b",
                            label: "標籤b"
                        },
                        {
                            name: "c",
                            label: "標籤c"
                        }
                    ],
                }
            },
            // 註冊組件
            components: {
                A, // 標籤a
                B, // 標籤b
                C, // 標籤c
            },
            mounted() {
                this.tabChange(name)
            },
            methods: {
                //切換tab事件
                tabChange(name) {
                    this.tabView="A";
                    this.tabContent = name || "a";
                    if (name === "a") {
                        this.tabView = A;
                    } else if (name === "b") {
                        this.tabView = B
                    }else if (name === "c") {
                        this.tabView = C
                    }
                },
            },
            watch: {}
        }
    </script>
    
    <style scoped lang="less">
    
    </style>
    
    複製代碼

    子組件的A.vue的文件內容以下:

    <template>
        <!-- 第一個tab頁的內容  -->
        <div>
            我是標籤a的內容
        </div>
    </template>
    
    <script>
        export default {
            data() {
                return {
                  
                }
            },
            props: {},
            components: {},
            mounted() {},
            methods: {},
            watch: {}
        }
    </script>
    
    <style scoped lang="less">
    
    </style>
    
    複製代碼

    其餘幾個子文件也如同A文件同樣,這樣點擊不一樣的tab 就會請求不一樣的.vue文件。

    二十3、keep-alive 緩存動態組件,以及它的參數,主要用於保留組件狀態或避免從新渲染。

    <keep-alive> 包裹動態組件時,會緩存不活動的組件實例,而不是銷燬它們。

    Props

    • include - 字符串或正則表達式。只有名稱匹配的組件會被緩存。
    • exclude - 字符串或正則表達式。任何名稱匹配的組件都不會被緩存。
    • max - 數字。最多能夠緩存多少組件實例。
    <!-- 基本 -->
    <keep-alive>
      <component :is="view"></component>
    </keep-alive>
    
    <!-- 多個條件判斷的子組件 -->
    <keep-alive>
      <comp-a v-if="a > 1"></comp-a>
      <comp-b v-else></comp-b>
    </keep-alive>
    
    <!-- 和 `<transition>` 一塊兒使用 -->
    <transition>
      <keep-alive>
        <component :is="view"></component>
      </keep-alive>
    </transition>
    
    複製代碼

    注意,``是用在其一個直屬的子組件被開關的情形。若是你在其中有 `v-for` 則不會工做。若是有上述的多個條件性的子元素,`` 要求同時只有一個子元素被渲染。

    • includeexclude屬性容許組件有條件地緩存。兩者均可以用逗號分隔字符串、正則表達式或一個數組來表示:
    <!-- 逗號分隔字符串 -->
    <keep-alive include="a,b">
      <component :is="view"></component>
    </keep-alive>
    
    <!-- 正則表達式 (使用 `v-bind`) -->
    <keep-alive :include="/a|b/">
      <component :is="view"></component>
    </keep-alive>
    
    <!-- 數組 (使用 `v-bind`) -->
    <keep-alive :include="['a', 'b']">
      <component :is="view"></component>
    </keep-alive>
    複製代碼
    • max 最多能夠緩存多少組件實例。一旦這個數字達到了,在新實例被建立以前,已緩存組件中最久沒有被訪問的實例會被銷燬掉。
    <keep-alive :max="10">
      <component :is="view"></component>
    </keep-alive>
    複製代碼

    二十4、父子組件傳遞參數 props

    首先來寫一個父子組件傳參的例子🌰: 父組件內容:

    <template>
      <div>
        下面是引入的組件:
        <template-a :isItem="item"><template-a/>
      </div>
    </template>
    <script>
      import templateA from "./templateA"
      export default {
        data () {
          return {
            item:"000"
            
          }
        },
        components: {
          templateA
        },
        methods: {
          
        },
        mounted () {
          
        }
      }
    </script>
    <style>
    
    </style>
    
    複製代碼

    子組件內容:

    <template>
      <div>
      我是templateA 組件,這是從父組件傳過來的參數: {{isItem}}
      </div>
    </template>
    <script>
    
      export default {
        data () {
          return {
            
          }
        },
        props:{
          isItem:{
            type:String,
            default:""
          }
        },
        components: {
        
        },
        methods: {
          
        },
        mounted () {
          
        }
      }
    </script>
    <style>
    
    </style>
    複製代碼

    props 配置多個類型

    例若有時咱們在傳遞參數的時候,不肯定拿到是什麼類型,有多是Number有多是String,此時咱們就可給props的默認類型時添加一個數組,以下:

    props:{
        data: {     
    		type: [String, Number],
    		default: ''
    	},
    }
    
    複製代碼

    這樣在拿到參數的時候,不管是string仍是number都不會由於類型錯誤而報錯,加大了傳參的容錯率。 詳細參考

    • 補充:props 執行的比data早,因此在data中能夠拿到props中的傳值。

    二十5、 很是好用的計算屬性 computed

    在咱們的平常編碼中,每每會遇到不少須要判斷的條件、計算數據或者控制權限等,以下:

    條件判斷: AA&&BB&&cc  ;
    計算數據: A+B-C-D 、   message.split('').reverse().join('');
    控制權限: A === B || B===C ;
    複製代碼

    以上的內容咱們能夠在標籤或者模版{{}}中進行判斷,計算,但若是邏輯較多,或者條件較複雜,這樣還在標籤或者模版上進行操做的話,咱們的代碼就看起來會很難理解,並且很冗餘,這時,咱們能夠把這些複雜的邏輯判斷放到 computed中進行計算,返給模版一個變量便可:

    <template>
      <div id="example">
        <p>未計算前的值: "{{ message }}"</p>
        <p>計算完畢返回的值: "{{ reversedMessage }}"</p>
      </div>
    </template>
    <script>
    
      export default {
        data () {
          return {
             message: 'Hello',     
          }
        },
        computed: {
        // 計算屬性的 getter 在這裏面進行一系列的計算,最後return出一個結果給模版
          reversedMessage: function () {
          // `this` 指向 vm 實例
            return this.message.split('').reverse().join('*')
          }
       },
        components: {
          
        },
        methods: {
          
        },
        mounted () {
          
        }
      }
    </script>
    <style>
    
    </style>
    複製代碼

    頁面展現效果以下:

    計算屬性是基於它們的依賴進行緩存的。只在相關依賴發生改變時它們纔會從新求值。這就意味着只要 message 尚未發生改變,屢次訪問reversedMessage計算屬性會當即返回以前的計算結果,而沒必要再次執行函數。

    參考:vue-computed

    二十6、組件之間的傳參 bus

    關於組件和組件之間的參數傳遞(非父子),vue推薦使用bus來進行傳遞,可進行上行、下行、平行、斜行各類傳遞,下面咱們就來用bus來驗證。 首先須要先將它建立出來,能夠放在公用的工具js中,最後統一引入到全局mian.js中或者直接在mian中均可以,根據你狀況建立並引入就行:

    import Vue from "vue";
    
    export default new Vue()
    複製代碼

    此時就能夠直接用了,下面讓咱們來傳個參數試試:

    A頁面:

    <template>
      <div id="example">
        <Button @click="searIconClick" slot="append" icon="ios-search"></Button>
      </div>
    </template>
    <script>
    
      export default {
        data () {
          return {
             message: 'Hello',     
          }
        },
        methods: {
          // 當點擊按鈕後,將message使用$emit傳給B頁面
          searIconClick(){
            this.bus.$emit("searInfo", this.message);  
          }
        },
      }
    </script>
    
    複製代碼

    B頁面:

    <template>
      <div id="example">
           {{value}}
      </div>
    </template>
    <script>
    
      export default {
        data () {
          return {
             value: '',     
          }
        },
    
        components: {
          
        },
        methods: {
    
        },
        mounted () {
           this.bus.$on('searInfo', (message) => {
                    this.value = message;
                });
        }
      }
    </script>
    <style>
    
    </style>
    
    複製代碼

    A 頁面發送的事件名B頁面接受的事件名必須一致,並且需是全項目惟一的,否則會被其餘傳參影響,或者影響其餘傳參,我以前就出過這樣的錯,讓小姐姐找問題找來好久😂 !

    二十7、 計算屬性conputed,用來處理數據計算

    在咱們項目中,有時須要進行一些計算,只要數據改變,計算實時更新,如數據不發生變化,緩存計算結果。 效果展現地址:

    二十8、 vue中的錨連接跳轉

    vue中的錨連接和普通的html不一樣,關於vue中的錨連接能夠參考vue 中的 scrollBehavior 滾動行爲

    ----------------廢話很少說,直接上代碼-----------

    router.js中的router 實例中


    const router = new VueRouter({
                routes,
                mode: 'history',
                scrollBehavior(to, from, savedPosition) {
                if (to.hash) {
                    return {
                        selector: to.hash
                    }
                }
            }
        })
      
    export default router;
    複製代碼

    vue中點擊跳轉的位置 使用<a>連接包起來

    <div>
        <a href="#populationInformation">A</a>
    </div>
    
    <div>
        <a href="#peopleCounting">B</a>
    </div> 
    <div>
        <a href="#trafficAnalysis">C</a>
    </div>
    複製代碼

    在須要跳轉到的位置

    <div id='populationInformation '> A跳轉到此</div>
        
    <div id='peopleCounting'> B跳轉到此</div>
        
    <div id='trafficAnalysis '>C跳轉到此</div>
    複製代碼

    要保證<a>標籤的 href 的地址要和下面id的值是相同的才能夠完成相應的跳轉, 至於在router中的配置也是必須的

    二十9、 vue如何獲取當前頁面的url地址

    當場景須要咱們獲取url地址,以作某些判斷操做時,咱們可使用下面的方法來獲取。

    1.獲取所有url

    console.log("完整的url地址:",window.location.href)  
    
    // 完整的url地址: https://juejin.im/editor/posts/5a1a6a6551882534af25a86b
    
    複製代碼

    2.獲取路由路徑

    console.log("路由路徑:",this.$route.path)
    
    // 路由路徑:/activity/list
    
    複製代碼

    3.獲取路徑參數

    console.log("路徑參數:",this.$route.query)
    
    // 路徑參數: {name: "detail", id: "109", tabView: "self", groupID: ""}
    
    複製代碼

    (參考:十8、經過路由傳參,獲取參數,用於記錄狀態等)

    三10、兩種前端下載方式

    1.經過後端接口直接經過url跳轉到下載地址便可

    window.location.replace(http://172.******/exports/${id}/download`)
    複製代碼

    2.經過後端接口前端實現下載請求

    this.$axios.get(`${this.$config.apiDomain}/crowds/exports/${row.id}/download-crowd`)
        .then(({data})=>{
        // data 直接傳入now Blob中
            const blob = new Blob([data], { type: 'cache-control,expires,pragma,content-type' })
            const downloadElement = document.createElement('a')
            const href = window.URL.createObjectURL(blob)
            downloadElement.href = href
            downloadElement.download = row.id+'.csv'
            document.body.appendChild(downloadElement)
            downloadElement.click()
    		document.body.removeChild(downloadElement) // 下載完成移除元素
    		window.URL.revokeObjectURL(href) // 釋放掉blob對
    	})
    
    複製代碼

    借鑑地址

    三11、給組件添加原生事件

    現階段咱們前端開發者作項目通常手裏都有各類各樣的UI庫,例如vueUI庫有 iview,elementUI 等等,UI庫的組件都會提供一些須要的事件,你可能有不少次想要在一個組件的根元素上直接監聽一個原生事件。這時,你可使用 v-on.native 修飾符:

    <base-input v-on:focus.native="onFocus"></base-input>
    複製代碼

    參考地址


    值得推薦

    • vue的代碼風格指南 裏面有vue 推薦的代碼編寫風格,強烈推薦的,推薦及謹慎使用的各類風格示例,推薦你們看看,有助於開發效率提高。
    • vue的網頁運行工具 iVuewRun網頁版的vue,可直接運行使用,還能夠分享給小夥伴!

    接下來我還會持續追加,看文章的小夥伴們能夠添加一下關注哦!

    做者:Christine    
    出處:https://juejin.im/post/5a125827518825293b4fea8a
    版權全部,歡迎保留原文連接進行轉載:) 
    複製代碼

    若是你對我對文章感興趣或者有些建議想說給我聽👂,也能夠添加一下微信哦!

    PS:目前找工做中,求大佬們內推,中高級前端,偏JS,Vue,北京。

    郵箱:christine_lxq@sina.com

    若是親感受個人文章還不錯的話,能夠一下添加關注哦!

    最後:
            祝各位工做順利!
                            -小菜鳥Christine
    複製代碼
  • 相關文章
    相關標籤/搜索