前端面試題—vue部分詳解

vue

基本概念區分

  • 單頁面應用:在一個頁面跳來跳去,不從新加載頁面
  • vue 特色:漸進式 框架 雙向數據綁定
    • 雙向數據綁定:視圖改變 數據自動更新;數據更新 視圖自動改變
    • 漸進式:vue vue-router路由 vuex axios
    • 框架:本身寫的代碼被框架調用(庫:本身調用庫的代碼)
  • 聲明式

安裝vue

cmd命令javascript

npm i vuecss

yarn add vuehtml

vue核心實現方法

var obj={}
Object.defineProperty(obj,'name',{
     value:'xhufeng',
     configurable:true,//是否可刪
     writable:true,//是否可寫
     enumerable:true,//是否可枚舉(循環)
     set(val){
        //只要外界給name賦值,就會觸發該函數
        //形參val就是外界賦予的值
     },
     get(){
        return 123
     }
  })
複製代碼

vue指令

指令都是行內屬性
v-model放在input、textarea、select>option上的,實現雙向數據綁定
v-text 展現對應的文本
v-once 對應的標籤只渲染一次
v-show=布爾 是否能顯示,true能顯示,false不能顯示(存在隱式轉化)
v-html 把值中的標籤渲染出來前端

v-for

循環顯示元素
能夠循環數組、對象、數字、字符串
最好加:key='a+i'
v-for='item in ary'vue

v-bind

用於綁定行內屬性 簡寫成:java

v-if

控制是否渲染該元素
值是true,則渲染該元素;false則不渲染
v-else v-else-if連着使用
可使用template標籤,就不會出現多餘標籤node

<body>
    <div id="app">
        <h1>{{name}}</h1>
        <button @click='flag=!flag'>按鈕</button>
        <h2 v-show='flag'>hello</h2>
        <h2 v-show='!flag'>world</h2>
        
        <button @click='n=1'>1</button>
        <button @click='n=2'>2</button>
        <button @click='n=3'>3</button>
        <h3 v-if='n===1'>hello</h3>
        <h3 v-else-if="n===2">hahaha</h3>
        <h3 v-else>world</h3>
    </div>
</body>

</html>
<script src="./node/node_modules/vue/dist/vue.js"></script>
<script>
    let vm = new Vue({
        el: '#app',
        data: {
            name: "珠峯",
            flag:true,
            n:1
        },
        methods: {
            fn() {

            }
        }
    })
</script>
複製代碼
v-cloak

須要配合css使用:解決小鬍子顯示問題ios

v-pre

跳過有這個指令的標籤及其子元素的編譯,按照原生代碼編譯ajax

vue對象

data中的屬性最終都添加到了實例上 屬性須要有get set,才能觸發視圖更新vue-router

let vm = new Vue({
         el: '#app',
         data: {
             name: 'liu',
             age:21,
             q:'<h1>haha</h1>',
             obj:{
                 a:123,//對於對象來講,新增一個屬性不會觸發視圖更新,只有改變屬性時纔會觸發視圖更新
                 b:undefined,
             }
         }
     }).$mount('#app')
     //處理方式
     //1.正常寫全要用到的屬性;先預留要用到的屬性
     //2.整個對象的從新賦值
     //3.$set()方法
     vm.$set(vm.obj,'c','456')
     //4.增長一個無關變量t,每次修改完數據以後;重置t就能夠了
複製代碼

vue數組

let vm = new Vue({
        el: '#app',
        data: {
            ary: [1, 2, 3, 4]
        }
    })
    vm.ary.length--;
    //能改變原有數組,但不能觸發視圖更新,只有數組原型上的變異方法能夠觸發更新
    //數組變異方法:pop shift unshift push reverse splice sort
複製代碼

vue 事件

<body> <div id="app"> {{ary}} <button @click='fn'>按鈕1</button> <button @click='fn(name,$event)'>按鈕2</button> <!-- $event是固定寫法,表明傳參事件對象 --> </div> </body> </html> <script src="./node/node_modules/vue/dist/vue.js"></script> <script> //事件綁定,用v-on:事件類型=‘函數’ 或者 @事件類型=‘函數’ //函數通常是在methods中定義的 //對應的函數通常不帶小括號,默認傳參事件對象e //當咱們須要傳參時,須要加小括號,小括號裏寫須要傳的參數;當只有小括號沒有傳參時,爲undefined //el data methods 都是VUE規定死的屬性名  let vm = new Vue({ el: '#app', data: { ary: [1, 2, 3, 4], name:'liu' }, methods: { fn: function (val,e) { console.log(val,e,this) } } }) //@kryup.13='fn'在按下回車的時候纔會觸發該函數 </script> 複製代碼

vue過濾器

全局用filter,實例局部使用filters 全局過濾器要放在須要使用的實例的前面

vue計算屬性computed

  • 於data同級別
  • 語法同methods同樣
  • 計算屬性的名字 不能跟 data 或 methods 中的名字重複
  • 徹底依賴於函數體中出現的屬性名,只在最初加載時和其中屬性名改變時運行,並非像methods中的函數只要頁面更新就運行一次
  • 不能傳參
  • 異步的沒法處理
  • 爲了提升性能而存在

vue監聽屬性

  • 當且僅當監聽的屬性(例如:name)發生變化時會執行函數
  • 能夠處理異步
  • 下面這種寫法不能監聽引用數據類型的內部變化
watch:{
            name(newV,oldV){
                clearTimeout(this.timer)
                this.timer=setTimeout(() => {
                    if (newV.length > 5) {
                        this.msg2 = '名字太長'
                    }else{
                        this.msg2 = ''
                    }
                }, 500)
            }
        }
複製代碼
  • 深度監聽須要用下面這種語法
  • 這種深度監聽在有get和set屬性時纔會觸發監聽
watch:{
            obj:{
                handler(){
                    console.log(1111)
                },
                deep:true
             }
        }
複製代碼

directives自定義指令

一個指令定義對象能夠提供以下幾個鉤子函數 (均爲可選):

  • bind:只調用一次,指令第一次綁定到元素時調用。在這裏能夠進行一次性的初始化設置。
  • inserted:被綁定元素插入父節點時調用 (僅保證父節點存在,但不必定已被插入文檔中)。
  • update:所在組件的 VNode 更新時調用,可是可能發生在其子 VNode 更新以前。指令的值可能發生了改變,也可能沒有。可是你能夠經過比較更新先後的值來忽略沒必要要的模板更新 (詳細的鉤子函數參數見下)。
  • componentUpdated:指令所在組件的 VNode 及其子 VNode 所有更新後調用。
  • unbind:只調用一次,指令與元素解綁時調用。

vue動畫

transition
  • 把須要實現動畫的標籤用transition標籤包起來
  • 只能對根元素有動效

transition-group
  • tag指定外層包裹元素的tag類型;不寫,默認span
  • duration控制vue設置的類名存在的時間

事件修飾符

  • .self只點元素自己時才觸發事件
  • .stop阻止冒泡事件
  • .prevent阻止默認事件
  • .once對應函數只觸發一次
  • .capture在捕獲階段觸發二級綁定事件
  • .passive優先執行默認事件(滾動行爲)

表單修飾符

  • .number轉化爲數字,相似parse轉化
  • .trim去字符串先後空格

生命週期

enter image description here

let vm = new Vue({
        el:'#app',
        // template:'<h1>哈哈哈</h1>',
        data:{
            name:"liu"
        },
        // 生命週期鉤子函數 就是VUE規定的一些在固定階段執行的函數
        // 語法上 跟 data和el、methods等 同級
        beforeCreate(){
            // 創造以前
            // 不能獲取data和methods裏的數據
            console.log('beforeCreate');
            debugger;
        },
        created(){            
           // 能獲取data和methods裏的數據
           // 通常把ajax請求的發送寫到這裏
        },
        beforeMount() {},
        mounted(){
           // 在此時DOM已經渲染完成
        },
        beforeUpdate(){
           // 在視圖更新時會觸發其中函數
           // 函數在視圖更新前執行
        },
        updated(){
           // 在視圖更新時會觸發其中函數
           // 函數在視圖更新後執行
           // 不要寫會觸發視圖更新的代碼
        },
        beforeDestroy(){},
        destroyed(){}
    })
    vm.$destory();//手動銷燬該實例,雙向數據綁定沒了
複製代碼

組件

  • 劃分比較明細,複用率比較高
  • 功能性組件 頁面級組件
  • 全局組件 局部組件
  • template模板中只能有一個根元素

全局組件的註冊

  • 必須寫到根組件(根實例)的前面
//全局組件的定義
    Vue.component('qqq',{
        template:'<i>hello 小聰子</i>'
    })
複製代碼
<body> <div id="app"> <h1>{{name}}</h1> <aaa></aaa> <aaa></aaa> <my-name></my-name> <!-- 不支持駝峯式命名 --> </div> </body> <template id='qqq'> <div> <input type="text" v-model='name'> <h1><i>{{name}}</i></h1> </div> </template> <script> //全局組件的定義 //使用時只要把組件名看成標籤使用便可 Vue.component('aaa', { //沒有el屬性,有template屬性,data是個函數,而且返回一個對象 //template就是qqq標籤要去展現的內容 //template有且只能有一個根元素 template: '#qqq', data() { return { name: 'liu' } }, created() { console.log(this.name) } }) Vue.component('myName', { template: `<h2>My name is </h2>`, data() { return { } }, }) let vm = new Vue({ el: '#app', data: { name: "liu" } }) </script> 複製代碼

局部組件的註冊

  • 局部組件只能使用在此以前聲明的局部組件做爲子組件
 <body> <div id="app"> <h1>{{name}}</h1> <son></son> <parent></parent> </div> </body> <template id="opp"> <h2>ninininini</h2> </template> <template id="o"> <h2>小聰子<son></son></h2> </template> <script> let son = { template: '#opp', data() { return { } } } let parent = { template: '#o', data() { return { } }, components: { son } } let vm = new Vue({ el: '#app', data: { name: "liu" }, components: { son, parent: parent } }) </script> 複製代碼

組件的數據傳輸

父傳子

過程

  • 1.經過v-bind綁定屬性,把相應的數據傳遞給子組件
  • 2.子組件經過props接收傳進來的數據

注意事項

  • 父傳子是單向數據流,不能從子組件修改父組件的數據
  • 但若是是引用數據類型,不修改地址,只改變內容,能夠改變
  • props能夠是數組,也能夠對象
  • props中自定義屬性的參數
  • - 1.default:默認值
    複製代碼
  • - 2.type:規定此屬性的數據類型
    複製代碼
  • 能夠經過實例this.$parent調用父組件的數據和方法(不推薦)
<body> <div id="app"> <h1>{{name}}</h1> <input type="text" v-model='name'> <son :name='name'></son> </div> </body> <template id="o"> <div> <h3>{{name}}</h3> <button @click='fn'> 這個按鈕點擊了{{n}}次</button> </div> </template> <script> let son = { template: '#o', data() { return { n: 0 } }, methods: { fn() { this.n++ } }, props:['name'] } let vm = new Vue({ el: '#app', data: { name: "liu" }, components: { son, } }) </script> 複製代碼
子傳父

本質上是父組件使用子組件的數據

官方過程

  1. 經過自定義事件觸發父組件中的方法
  2. 再由子組件方法的執行經過this.$emit('自定義事件名',this.qqq)傳遞子組件的數據

也能夠在父組件中經過this.$children[i]調用子組件的數據及方法 也能夠在父組件中經過this.$refs.son調用子組件的方法

插槽

在template模板中寫入<slot></slot>,可顯示在使用組件時組件名標籤內部內容

具名插槽

在slot標籤中的name屬性是控制要去顯示哪一部分的一個功能 不寫時,默認default,所有顯示 name對應的的是slot='qqq'的部分

模板中如有與name值對應的元素,則slot標籤包含的內容不會顯示出來;反之,能夠顯示

子父組件的mounted

執行順序

動態組件component

keep-alive

-在沒有keep-alive時,component組件是銷燬舊的,從新渲染新的 -加上keep-alive後,動態組件有緩存機制,不會銷燬舊的

<keep-alive>
      <component :is='son'></component>
  </keep-alive>

複製代碼

vue-router

vue-router是vue的路由插件

基本用法

  • 步驟
  • 一、聲明組件
  • 二、編寫路由映射表
  • 三、把編輯好的映射表注入到router實例中
  • 四、把router實例注入到根實例中
  • router-link 控制跳轉的連接和顯示的文字
  • router-view 控制顯示的組件內容
  • active-class 控制選中對應路徑的類名
  • tag 控制渲染成什麼標籤
<body>
    <div id="app"> <router-link to='/home' active-class='current'>首頁</router-link> <router-link to='/list' tag='div'>列表</router-link> <router-view></router-view> </div> </body> </html> <template id="home"> <div>home</div> </template> <template id="list"> <div>list</div> </template> <script src="../node/node_modules/vue/dist/vue.js"></script> <script src="../node_modules/vue-router/dist/vue-router.js"></script> <script> let home = { template: '#home', } let list = { template: '#list', } //路由映射表 let routes = [{ path: '/home', component: home }, { path: '/list', component: list } ] let router=new VueRouter({ routes:routes, }) let vm = new Vue({ el: '#app', data: { name: "liu" }, router, }) </script> 複製代碼

傳參

  • 提供了兩種傳參方式
  • 一、query傳參(問號傳參)
  • 路由映射表不用改動 :to={path:'',query:{}}或者:to={name:'',query:{}}
  • 二、params傳參(路徑傳參)
  • 在映射表中添加 /:變量 的形式; :to={name:'',params:{變量:''}}}

<router-link :to='{path:"/list",query:{id:123,e:name}}' tag='div'>列表</router-link>

重定向redirect

let routes = [
        {
            path:'/',
            redirect:'/son2/222'
        },
        {
            path:'/son1',
            // redirect:'/son2/5555',
            name:'son1',
            component:son1,
            redirect:'/son1/sz',
            children:[
                {
                    path:'/son1/sz',
                    component:sz
                }
            ]
        },
        {
            path:'/son2/:bl1234',
            name:'son2',
            component:son2
        },
        {
            path:'/*',
            redirect:'/son1'
        }
    ]
複製代碼

vuex

是一個能方便vue實例及其組件傳輸數據的插件 方便傳輸數據,做爲公共存儲數據的一個庫

基本用法

  • 步驟
  • 一、建立一個vuex實例
  • 二、在根組件中註冊一下
  • 三、註冊後,根組件及其一下的局部或全局組件可以使用vuex實例中的數據方法,多個組件使用同一套規則時,咱們能夠把這套規則單獨拎出來寫在vuex實例中通用

方法彙總

state

相似vue實例中的data,存儲數據 在vue實例中用this.$store.state調用state裏的數據 使用...Vuex.mapStore(['count'])將其數據放入computed中

mutations

官方提供的惟一改數據的方法 其中必須是同步函數 經過commit來調用mutations中的函數 其中函數最少有一個參數state,最多兩個參數另加val(調用時的傳參) 使用...Vuex.mapMutations(['mu_add'])將其函數放入methods中

actions

能夠寫異步函數,通常多用於觸發ajax請求 不能直接用於修改state中的數據,須要經過其中函數默認的第一個實參obj,用obj.commit('mu_')來調用mutations中的函數來修改數據 使用...Vuex.mapActions(['ac_add'])將其函數放入methods中

getters

相似vue實例中的計算屬性,存儲數據 使用...Vuex.mapGetters(['remove'])將其函數放入computed中

//一、創造一個vuex實例
    //二、把創造的實例放到根實例中
    //使用this.$store.state
    let son1 = {
        template: `<div> <button @click='add'>增長</button> <button @click='mu_add(100)'>增長</button> <button @click='add2(100)'>2增長</button> <h2>{{count}}</h2> <h2>{{qqq}}</h2> </div>`,
        data() {
            return {

            }
        },
        computed: {
            //兩種監聽vuex數據的寫法
            // myCount(){
            // return this.$store.state.count
            // }
            ...Vuex.mapState(['count', 'qqq'])
        },
        methods: {
            add() {
                // this.$store.state.count++
                // this.$store.commit('mu_add', 1)
                this.mu_add(10)
            },
            ...Vuex.mapMutations(['mu_add']),
            add2() {
                this.$store.dispatch('ac_add', 22)
                //dispatch 觸發的是actions裏的函數
                //commit 觸發的是mutations裏的函數
            }
        }
    }
    let son2 = {
        template: `<div> <button @click='remove'>減小</button> <h2>{{$store.state.count}}</h2> </div>`,
        methods: {
            remove() {
                this.$store.commit('mu_remove', 1)
            }
        },
    }
    let store = new Vuex.Store({
        state: {
            count: 0,
            qqq: 12
        },
        
        mutations: {
            mu_add(state, val = 1) {
                console.log(arguments)
                //第一個實參是默認傳的state
                //第二個實參是本身傳的參數
                //一共只有一個或兩個實參
                state.count += val
            },
            mu_remove(state, val = 1) {
                console.log(arguments)
                //第一個實參是默認傳的state
                //第二個實參是本身傳的參數
                //一共只有一個或兩個實參
                state.count -= val
            }
        },
        actions: {
            ac_add(obj,n) {
                //obj是vuex封裝好的一個對象,裏邊提供了commit方法
                obj.commit('mu_add',n)
                console.log(arguments)
            }
        }
        //mutations中必須是同步函數,actions同步異步都行
        //想要修改state裏的數據只能用commit來調用mutations裏的函數
    })
    let vm = new Vue({
        el: '#app',
        store,
        data: {
            name: "liu"
        },
        components: {
            son1,
            son2
        },
        created() {
            console.log(this)
        },
    })
複製代碼

==========================================================

前端小白,第一次發文,歡迎評論指正!

相關文章
相關標籤/搜索