1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        經(jīng)常會(huì)被問(wèn)及的 Vue 面試題(下)

        共 12938字,需瀏覽 26分鐘

         ·

        2021-10-17 22:53

        作者:東起

        鏈接:https://zhuanlan.zhihu.com/p/103763164


        上一篇文章我們分享了《經(jīng)常會(huì)被問(wèn)及的 Vue 面試題(上)》,今天我們繼續(xù)分享剩余的部分。


        11、怎么在vue中點(diǎn)擊別的區(qū)域輸入框不會(huì)失去焦點(diǎn)?

        答:阻止事件的默認(rèn)行為

        具體操作:監(jiān)聽(tīng)你想點(diǎn)擊后不會(huì)丟失 input 焦點(diǎn)的那個(gè)元素的 mousedown 事件,回調(diào)里面調(diào)用 event.preventDefault(),會(huì)阻止使當(dāng)前焦點(diǎn)丟失這一默認(rèn)行為。

        12、vue中data的屬性可以和methods中的方法同名嗎?為什么?

        答:不可以

        因?yàn)?,Vue會(huì)把methods和data的東西,全部代理到Vue生成的對(duì)象中,會(huì)產(chǎn)生覆蓋所以最好不要同名

        13、怎么給vue定義全局的方法?

        Vue.prototype.方法名稱

        14、Vue 2.0 不再支持在 v-html 中使用過(guò)濾器怎么辦?

        解決方法:

        ①全局方法(推薦)

        Vue.prototype.msg = function(msg){
        return msg.replace("\n","
        ")
        }

        ②computed方法

        computed:{
        content:function(msg){
        return msg.replace("\n","
        ")
        }
        }
        {{content}}

        ③$options.filters(推薦)

        filters:{
        msg:function(msg){
        return msg.replace(/\n/g,"
        ")
        }
        },   
        data:{
        content:"XXXX"
        }

        15、怎么解決vue打包后靜態(tài)資源圖片失效的問(wèn)題?

        答:將靜態(tài)資源的存放位置放在src目錄下

        16、怎么解決vue動(dòng)態(tài)設(shè)置img的src不生效的問(wèn)題?


        data() {
        return {
        logo:require("./../assets/images/logo.png"),
        };
        }

        因?yàn)閯?dòng)態(tài)添加src被當(dāng)做靜態(tài)資源處理了,沒(méi)有進(jìn)行編譯,所以要加上require

        17、跟keep-alive有關(guān)的生命周期是哪些?描述下這些生命周期

        activated和deactivated兩個(gè)生命周期函數(shù)

        1.activated:當(dāng)組件激活時(shí),鉤子觸發(fā)的順序是created->mounted->activated

        2.deactivated: 組件停用時(shí)會(huì)觸發(fā)deactivated,當(dāng)再次前進(jìn)或者后退的時(shí)候只觸發(fā)activated

        18、你知道vue中key的原理嗎?說(shuō)說(shuō)你對(duì)它的理解

        暫時(shí)沒(méi)弄明白,等會(huì)兒寫(xiě)

        19、vue中怎么重置data?

        答:Object.assign()

        Object.assign()方法用于將所有可枚舉屬性的值從一個(gè)或多個(gè)源對(duì)象復(fù)制到目標(biāo)對(duì)象。它將返回目標(biāo)對(duì)象。

        var o1 = { a: 1 };
        var o2 = { b: 2 };
        var o3 = { c: 3 };
        var obj = Object.assign(o1, o2, o3);
        console.log(obj); // { a: 1, b: 2, c: 3 }
        console.log(o1); // { a: 1, b: 2, c: 3 }, 注意目標(biāo)對(duì)象自身也會(huì)改變。

        注意,具有相同屬性的對(duì)象,同名屬性,后邊的會(huì)覆蓋前邊的。

        由于Object.assign()有上述特性,所以我們?cè)赩ue中可以這樣使用:

        Vue組件可能會(huì)有這樣的需求:在某種情況下,需要重置Vue組件的data數(shù)據(jù)。此時(shí),我們可以通過(guò)this.$data獲取當(dāng)前狀態(tài)下的data,通過(guò)this.$options.data()獲取該組件初始狀態(tài)下的data。

        然后只要使用**Object.assign(this.options.data())**就可以將當(dāng)前狀態(tài)的data重置為初始狀態(tài)。

        20、vue怎么實(shí)現(xiàn)強(qiáng)制刷新組件?

        答:① v-if ② this.$forceUpdate

        v-if

        當(dāng)v-if的值發(fā)生變化時(shí),組件都會(huì)被重新渲染一遍。因此,利用v-if指令的特性,可以達(dá)到強(qiáng)制


        data() {
        return {
        update: true
        }
        },
        methods: {
        reload() {
        // 移除組件
        this.update = false
        // 在組件移除后,重新渲染組件
        // this.$nextTick可實(shí)現(xiàn)在DOM 狀態(tài)更新后,執(zhí)行傳入的方法。
        this.$nextTick(() => {
        this.update = true
        })
        }
        }

        this.$forceUpdate


        methods: {
        reload() {
        this.$forceUpdate()
        }
        }

        21、vue如何優(yōu)化首頁(yè)的加載速度?

        ① 第三方j(luò)s庫(kù)按CDN引入(一、cdn引入 二、去掉第三方庫(kù)引入的import 三、把第三方庫(kù)的js文件從打包文件里去掉)

        ② vue-router路由懶加載

        ③ 壓縮圖片資源

        ④ 靜態(tài)文件本地緩存

        http緩存:推薦網(wǎng)站:https://www.cnblogs.com/chinajava/p/5705169.html

        service worker離線緩存:,缺點(diǎn):需要在HTTPS站點(diǎn)下,推薦:http://lzw.me/a/pwa-service-worker.html

        ⑤ 服務(wù)器端SSR渲染

        除了上面的方案以外,另一種方案也不容小視

        我們先說(shuō)說(shuō)通常項(xiàng)目中是如何加載頁(yè)面數(shù)據(jù):Vue組件生命周期中請(qǐng)求異步接口,在mounted之前應(yīng)該都可以,據(jù)我了解絕大部分同學(xué)是在mounted的時(shí)候執(zhí)行異步請(qǐng)求。但是我們可以把頁(yè)面需要的請(qǐng)求放到Vue-Router的守衛(wèi)中執(zhí)行,意思是在路由beforeEnter之前就可以請(qǐng)求待加載頁(yè)面中所有組件需要的數(shù)據(jù),此時(shí)待加載頁(yè)面的Vue組件還沒(méi)開(kāi)始渲染,而Vue組件開(kāi)始渲染的時(shí)候我們就可以用Vuex里面的數(shù)據(jù)了。

        以上方法的實(shí)現(xiàn)思路:

        圖意:每個(gè)頁(yè)面(Page)中都會(huì)有很多個(gè)Vue組件,可以在Vue組件中添加自定義屬性fetchData,fetchData里面可以執(zhí)行異步請(qǐng)求(圖中執(zhí)行Vuex的Action),但是我們?cè)趺传@取到所有組件的fetchData方法并執(zhí)行呢?如圖所示,在router.beforeResolve守衛(wèi)中,我們看看router.beforeResolve的定義,所有組件內(nèi)守衛(wèi)和異步路由組件被解析之后,解析守衛(wèi)就被調(diào)用,意思是即使頁(yè)面中有異步組件,它會(huì)等待異步組件解析之后執(zhí)行,并且解析守衛(wèi)在beforeEnter之前執(zhí)行。那我們?cè)趺丛诮馕鍪匦l(wèi)中獲取到待加載頁(yè)面的所有組件呢?通過(guò)router.getMatchedComponents方法。


        這樣我們就可以在解析守衛(wèi)中獲取到所有待加載組件的fetchData方法并執(zhí)行,這樣無(wú)疑會(huì)在組件開(kāi)始渲染之后獲取到所有數(shù)據(jù),提高頁(yè)面加載速度。以上方法的實(shí)現(xiàn)思路:

        很多人可能有個(gè)疑問(wèn),如果異步請(qǐng)求放在beforeCreate和created不是一樣嗎?答案是否定的,因?yàn)檫@種方式可以將異步請(qǐng)求放到beforeCreate之前!

        22、你了解vue的diff算法嗎?

        推薦網(wǎng)站:https://www.cnblogs.com/wind-lanyan/p/9061684.html

        23、vue能監(jiān)聽(tīng)到數(shù)組變化的方法有哪些?為什么這些方法能監(jiān)聽(tīng)到呢?

        Vue.js觀察數(shù)組變化主要通過(guò)以下7個(gè)方法(push、pop、shift、unshift、splice、sort、reverse)

        大家知道,通過(guò)Object.defineProperty()劫持?jǐn)?shù)組為其設(shè)置getter和setter后,調(diào)用的數(shù)組的push、splice、pop等方法改變數(shù)組元素時(shí)并不會(huì)觸發(fā)數(shù)組的setter,繼而數(shù)組的數(shù)據(jù)變化并不是響應(yīng)式的,但是vue實(shí)際開(kāi)發(fā)中卻是實(shí)時(shí)響應(yīng)的,是因?yàn)関ue重寫(xiě)了數(shù)組的push、splice、pop等方法

        從源碼中可以看出,ob.dep.notify()將當(dāng)前數(shù)組的變更通知給其訂閱者,這樣當(dāng)使用重寫(xiě)后方法改變數(shù)組后,數(shù)組訂閱者會(huì)將這邊變化更新到頁(yè)面中

        24、說(shuō)說(shuō)你對(duì)proxy的理解?

        Proxy用于修改某些操作的默認(rèn)行為,也可以理解為在目標(biāo)對(duì)象之前架設(shè)一層攔截,外部所有的訪問(wèn)都必須先通過(guò)這層攔截,因此提供了一種機(jī)制,可以對(duì)外部的訪問(wèn)進(jìn)行過(guò)濾和修改。

        var target = {
        name: 'zhangsan',
        age:20,
        sex:'男'
        }
        var logHandler = {
        get(target, key) {
        console.log(`${key}被讀取`)
        return target[key]
        },
        set(target, key, value) {
        console.log(`${key}被設(shè)置為${value}`)
        target[key] = value
        }
        }
        var demo = new Proxy(target, logHandler)
        demo.name //name被讀取

        var proxy = new Proxy(target, handler);

        Proxy對(duì)象的所有用法,都是上面的這種形式。不同的只是handle參數(shù)的寫(xiě)法。其中new Proxy用來(lái)生成Proxy實(shí)例,target是表示所要攔截的對(duì)象,handle是用來(lái)定制攔截行為的對(duì)象。

        我們可以將Proxy對(duì)象,設(shè)置到object.proxy屬性,從而可以在object對(duì)象上調(diào)用。

        var object = { proxy: new Proxy(target, handler) };

        Proxy對(duì)象也可以作為其它對(duì)象的原型對(duì)象。

        var proxy = new Proxy({}, {
        get: function(target, property) {
        return 35;
        }
        });
        let obj = Object.create(proxy);
        obj.time // 35

        上面代碼中,proxy對(duì)象是obj的原型對(duì)象,obj本身并沒(méi)有time屬性,所以根據(jù)原型鏈,會(huì)在proxy對(duì)象上讀取屬性,從而被攔截。

        同一個(gè)攔截函數(shù),可以設(shè)置多個(gè)操作。

        var handler = {
        get: function (target, name) {
        if (name === 'prototype') {
        return Object.prototype;
        }
        return 'Hello, ' + name;
        },

        apply: function (target, thisBinding, args) {
        return args[0];
        },

        construct: function (target, args) {
        return { value: args[1] };
        }
        };

        var fproxy = new Proxy(function (x, y) {
        return x + y;
        }, handler);

        fproxy(1, 2) // 1
        new fproxy(1, 2) // {value: 2}
        fproxy.prototype === Object.prototype // true
        fproxy.foo === "Hello, foo" // true

        25、怎么緩存當(dāng)前的組件?緩存后怎么更新?










        {
        path: '',
        name: '',
        component: ,
        meta: {keepAlive: true} // 這個(gè)是需要keepalive的
        },
        {
        path: '',
        name: '',
        component: ,
        meta: {keepAlive: false} // 這是不會(huì)被keepalive的
        }

        如果緩存的組件想要清空數(shù)據(jù)或者執(zhí)行初始化方法,在加載組件的時(shí)候調(diào)用activated鉤子函數(shù),如下:

        activated: function () {
        this.data = '';
        }

        26、axios怎么解決跨域的問(wèn)題?

        使用axios直接進(jìn)行跨域訪問(wèn)不可行,我們需要配置代理

        代理可以解決的原因:

        因?yàn)榭蛻舳苏?qǐng)求服務(wù)端的數(shù)據(jù)是存在跨域問(wèn)題的,而服務(wù)器和服務(wù)器之間可以相互請(qǐng)求數(shù)據(jù),是沒(méi)有跨域的概念(如果服務(wù)器沒(méi)有設(shè)置禁止跨域的權(quán)限問(wèn)題),也就是說(shuō),我們可以配置一個(gè)代理的服務(wù)器可以請(qǐng)求另一個(gè)服務(wù)器中的數(shù)據(jù),然后把請(qǐng)求出來(lái)的數(shù)據(jù)返回到我們的代理服務(wù)器中,代理服務(wù)器再返回?cái)?shù)據(jù)給我們的客戶端,這樣我們就可以實(shí)現(xiàn)跨域訪問(wèn)數(shù)據(jù)

        1.配置BaseUrl

        import axios from 'axios'
        Vue.prototype.$axios = axios
        axios.defaults.baseURL = '/api' //關(guān)鍵代碼

        2.配置代理

        在config文件夾下的index.js文件中的proxyTable字段中,作如下處理:

        proxyTable: {
        '/api': {
        target:'http://api.douban.com/v2', // 你請(qǐng)求的第三方接口
        changeOrigin:true,
        // 在本地會(huì)創(chuàng)建一個(gè)虛擬服務(wù)端,然后發(fā)送請(qǐng)求的數(shù)據(jù),并同時(shí)接收請(qǐng)求的數(shù)據(jù),
        //這樣服務(wù)端和服務(wù)端進(jìn)行數(shù)據(jù)的交互就不會(huì)有跨域問(wèn)題
        pathRewrite:{ // 路徑重寫(xiě),
        '^/api': ''
        // 替換target中的請(qǐng)求地址,也就是說(shuō)以后你在請(qǐng)求http://api.douban.com/v2/XXXXX
        //這個(gè)地址的時(shí)候直接寫(xiě)成/api即可。
        }
        }
        }

        1. 在具體使用axios的地方,修改url如下即可

        axios.get("/movie/top250").then((res) => {
        res = res.data
        if (res.errno === ERR_OK) {
        this.themeList=res.data;
        }
        }).catch((error) => {
        console.warn(error)
        })

        原理:

        因?yàn)槲覀兘ourl加上了前綴/api,我們?cè)L問(wèn)/movie/top250就當(dāng)于訪問(wèn)了:localhost:8080/api/movie/top250(其中l(wèi)ocalhost:8080是默認(rèn)的IP和端口)。

        在index.js中的proxyTable中攔截了/api,并把/api及其前面的所有替換成了target中的內(nèi)容,因此實(shí)際訪問(wèn)Url是http://api.douban.com/v2/movie/top250。

        至此,純前端配置代理解決axios跨域得到解決

        27、怎么實(shí)現(xiàn)路由懶加載呢?

        第一種(最常用):

        const Foo = () => import('./Foo.vue')
        const router = new VueRouter({
        routes: [
        { path: '/foo', component: Foo }
        ]
        })

        第二種:

        const router = new Router({
        routes: [
        {
        path: '/index',
        component: (resolve) => {
        require(['../components/index'], resolve) // 這里是你的模塊 不用import去引入了
        }
        }
        ]
        })

        第三種(官方推薦):

        // r就是resolve
        const list = r => require.ensure([], () => r(require('../components/list/list')), 'list');
        // 路由也是正常的寫(xiě)法 這種是官方推薦的寫(xiě)的 按模塊劃分懶加載
        const router = new Router({
        routes: [
        {
        path: '/list/blog',
        component: list,
        name: 'blog'
        }
        ]
        })

        28、怎樣動(dòng)態(tài)加載路由?

        一、思路

        ① 在vue-router對(duì)象中首先初始化公共路由,比如(首頁(yè),404,login)等

        ② 用戶登陸成功后,根據(jù)用戶的角色信息,獲取對(duì)應(yīng)權(quán)限菜單信息menuList,并將后臺(tái)返回的menuList轉(zhuǎn)換成我們需要的router數(shù)據(jù)結(jié)構(gòu)

        ③ 通過(guò)**router.addRouter(routes)**方法,同時(shí)我們可以將轉(zhuǎn)后的路由信息保存于vuex,這樣我們可以在我們的SideBar組件中獲取我們的全部路由信息,并且渲染我們的左側(cè)菜單欄,讓動(dòng)態(tài)路由實(shí)現(xiàn)。

        二、實(shí)現(xiàn)

        ① 初始化公共路由

        //只顯示主要代碼
        export const routes= [
        { path: '/login', component: () => import('@/views/login/index'), hidden: true },
        { path: '/404', component: () => import('@/views/404'), hidden: true }
        ]
        export default new Router({
        scrollBehavior: () => ({ y: 0 }),
        routes: routes
        })

        ② 登陸成功后,獲取菜單信息 menuList,并轉(zhuǎn)換成router數(shù)組的結(jié)構(gòu)

        router.beforeEach((to, from, next) => {
        NProgress.start()//進(jìn)度條包 npm安裝
        if (getToken()) {
        /*有 token,已經(jīng)登錄成功*/
        if (to.path === '/login') {
        next({ path: '/' })
        NProgress.done()
        } else {
        if (store.getters.roles.length === 0) { // 判斷當(dāng)前用戶是否已拉取完user_info信息
        store.dispatch('GetInfo').then(res => { // 拉取user_info
        const roles = res.roles
        store.dispatch("GetMenu").then(data => {
        initMenu(router, data);
        });
        next()
        }).catch((err) => {
        store.dispatch('FedLogOut').then(() => {
        Message.error(err || 'Verification failed, please login again')
        next({ path: '/' })
        })
        })
        } else {
        next()
        }
        }
        } else {
        /* 無(wú) token*/
        if (whiteList.indexOf(to.path) !== -1) { // 在免登錄白名單,直接進(jìn)入
        next()
        } else {
        next('/login') // 否則全部重定向到登錄頁(yè)
        NProgress.done()
        }
        }
        })
        router.afterEach(() => {
        NProgress.done()
        })

        ③ 動(dòng)態(tài)加載路由

        import store from '../store'
        export const initMenu = (router, menu) => {
        if (menu.length === 0) {
        return
        }
        let menus = formatRoutes(menu);

        let unfound = { path: '*', redirect: '/404', hidden: true }
        menus.push(unfound) //404組件最后添加
        router.addRoutes(menus)
        store.commit('ADD_ROUTERS',menus)
        }
        export const formatRoutes = (aMenu) => {
        const aRouter = []
        aMenu.forEach(oMenu => {
        const {
        path,
        component,
        name,
        icon,
        childrens
        } = oMenu
        if (!validatenull(component)) {
        let filePath;
        const oRouter = {
        path: path,
        component(resolve) {
        let componentPath = ''
        if (component === 'Layout') {
        require(['../views/layout/Layout'], resolve)
        return
        } else {
        componentPath = component
        }
        require([`../${componentPath}.vue`], resolve)
        },
        name: name,
        icon: icon,
        children: validatenull(childrens) ? [] : formatRoutes(childrens)
        }
        aRouter.push(oRouter)
        }
        })
        return aRouter
        }

        ④ 渲染菜單




        就這樣我們動(dòng)態(tài)加載路由就是實(shí)現(xiàn)了,關(guān)鍵點(diǎn)就是router.addRoute方法

        ⑤ 防坑

        點(diǎn)擊刷新的時(shí)候頁(yè)面空白 控制臺(tái)也不報(bào)錯(cuò)?

        點(diǎn)擊刷新,vue-router會(huì)重新初始化,那么我們之前的動(dòng)態(tài)addRoute就不存在了,此時(shí)訪問(wèn)一個(gè)不存在的頁(yè)面,所以我們的sidebar組件也就不會(huì)被訪問(wèn),那么也無(wú)法獲取菜單信息,就導(dǎo)致頁(yè)面空白。所以我們需要把加載菜單信息這一步放在router的全局守衛(wèi)beforeEach中就可以了。

        export const initMenu = (router, menu) => {
        if (menu.length === 0) {
        return
        }
        let menus = formatRoutes(menu);
        // 最后添加
        let unfound = { path: '*', redirect: '/404', hidden: true }
        menus.push(unfound)
        router.addRoutes(menus)
        store.commit('ADD_ROUTERS',menus)
        }
        //404組件一定要放在動(dòng)態(tài)路由組件的最后,不然你刷新動(dòng)態(tài)加載的頁(yè)面,會(huì)跳轉(zhuǎn)到404頁(yè)面的

        29、切換到新路由時(shí),頁(yè)面要滾動(dòng)到頂部或保持原先的滾動(dòng)位置怎么做呢?

        當(dāng)創(chuàng)建一個(gè) Router 實(shí)例,可以提供一個(gè)?scrollBehavior?方法:

        注意: 這個(gè)功能只在 HTML5 history 模式下可用。
        const router = new VueRouter({
        routes: [...],
        scrollBehavior (to, from, savedPosition) {
        // return 期望滾動(dòng)到哪個(gè)的位置
        }
        })

        scrollBehavior 方法接收 to 和 from 路由對(duì)象。第三個(gè)參數(shù) savedPosition 當(dāng)且僅當(dāng) popstate 導(dǎo)航 (通過(guò)瀏覽器的 前進(jìn)/后退 按鈕觸發(fā)) 時(shí)才可用。

        scrollBehavior (to, from, savedPosition) {
        return { x: 0, y: 0 }
        }
        對(duì)于所有路由導(dǎo)航,簡(jiǎn)單地讓頁(yè)面滾動(dòng)到頂部。
        返回 savedPosition,在按下 后退/前進(jìn) 按鈕時(shí),在滾動(dòng)條位置,就會(huì)像瀏覽器的原生表現(xiàn)那樣:
        scrollBehavior (to, from, savedPosition) {
        if (savedPosition) {
        return savedPosition
        } else {
        return { x: 0, y: 0 }
        }
        }
        模擬『滾動(dòng)到錨點(diǎn)』的行為
        scrollBehavior (to, from, savedPosition) {
        if (to.hash) {
        return {
        selector: to.hash
        }
        }
        }

        還可以利用路由元信息更細(xì)顆粒度地控制滾動(dòng)。

        routes: [
        { path: '/', component: Home, meta: { scrollToTop: true }},
        { path: '/foo', component: Foo },
        { path: '/bar', component: Bar, meta: { scrollToTop: true }}
        ]
        const scrollBehavior = (to, from, savedPosition) => {
        if (savedPosition) {
        return savedPosition
        } else {
        const position = {}
        if (to.hash) {
        position.selector = to.hash
        }
        if (to.matched.some(m => m.meta.scrollToTop)) {
        position.x = 0
        position.y = 0
        }
        return position
        }
        }

        還可以在main.js入口文件配合vue-router寫(xiě)這個(gè)

        router.afterEach((to,from,next) => {
        window.scrollTo(0,0);
        });

        30、vue-router如何響應(yīng)路由參數(shù)的變化?

        當(dāng)使用路由參數(shù)時(shí),比如:

        {path:’/list/:id’component:Foo}

        從 /list/aside導(dǎo)航到 /list/foo,原來(lái)的組件實(shí)例會(huì)被復(fù)用。

        因?yàn)閮蓚€(gè)路由都渲染同個(gè)組件Foo,比起銷毀再創(chuàng)建,復(fù)用則更加高效。

        不過(guò),這也意味著組件的生命周期鉤子不會(huì)再被調(diào)用。

        如果跳轉(zhuǎn)到相同的路由還會(huì)報(bào)以下錯(cuò)誤

        這個(gè)時(shí)候我們需要重寫(xiě)push方法,在src/router/index.js 里面import VueRouter from 'vue-router'下面寫(xiě)入下面方法即可

        const routerPush = VueRouter.prototype.push
        VueRouter.prototype.push = function push(location) {
        return routerPush.call(this, location).catch(error=> error)
        }

        如何響應(yīng)不同的數(shù)據(jù)呢?

        ① 復(fù)用組件時(shí),想對(duì)路由參數(shù)的變化作出響應(yīng)的話,你可以簡(jiǎn)單地?watch (監(jiān)測(cè)變化) $route 對(duì)象

        const User = {
        template: '...',
        watch: {
        '$route' (to, from) {
        // 對(duì)路由變化作出響應(yīng)...
        }
        }
        }

        ② 使用beforeRouteUpdate

        const User = {
        template: '...',
        beforeRouteUpdate (to, from, next) {
        // react to route changes...
        // don't forget to call next()
        }
        }

        注意:

        (1)從同一個(gè)組件跳轉(zhuǎn)到同一個(gè)組件。

        (2)生命周期鉤子created和mounted都不會(huì)調(diào)用。

        31、vue模板中為什么以_、$開(kāi)始的變量無(wú)法渲染?

        名字以 _ 或?data._property 訪問(wèn)它們。

        32、vue中,如何監(jiān)聽(tīng)一個(gè)對(duì)象內(nèi)部的變化?

        方法①:對(duì)整個(gè)obj深層監(jiān)聽(tīng)

        watch:{
        obj:{
        handler(newValue,oldValue){
        console.log('obj changed')
        },
        deep: true,//深度遍歷
        immediate: true
        //默認(rèn)第一次綁定的時(shí)候不會(huì)觸發(fā)watch監(jiān)聽(tīng),值為true時(shí)可以在最初綁定的時(shí)候執(zhí)行
        }
        }

        方法② :指定key

        watch: {
        "dataobj.name": {
        handler(newValue, oldValue) {
        console.log("obj changed");
        }
        }
        }

        方法③:computed

        computed(){
        ar(){
        return this.obj.name
        }
        }

        33、v-for循環(huán)時(shí)為什么要加key?

        key的作用主要是為了高效的更新虛擬DOM,是因?yàn)閂irtual DOM 使用Diff算法實(shí)現(xiàn)的原因。

        當(dāng)某一層有很多相同的節(jié)點(diǎn)時(shí),也就是列表節(jié)點(diǎn)時(shí),Diff算法的更新過(guò)程默認(rèn)情況下也是遵循以上原則。

        比如一下這個(gè)情況


        我們希望可以在B和C之間加一個(gè)F,Diff算法默認(rèn)執(zhí)行起來(lái)是這樣的:


        即把C更新成F,D更新成C,E更新成D,最后再插入E,是不是很沒(méi)有效率?

        所以我們需要使用key來(lái)給每個(gè)節(jié)點(diǎn)做一個(gè)唯一標(biāo)識(shí),Diff算法就可以正確的識(shí)別此節(jié)點(diǎn),找到正確的位置區(qū)插入新的節(jié)點(diǎn)。

        34、$nextTick用過(guò)嗎,有什么作用?

        在下次 DOM 更新循環(huán)結(jié)束之后執(zhí)行延遲回調(diào)。在修改數(shù)據(jù)之后立即使用這個(gè)方法,獲取更新后的 DOM。

        解決的問(wèn)題:有些時(shí)候在改變數(shù)據(jù)后立即要對(duì)dom進(jìn)行操作,此時(shí)獲取到的dom仍是獲取到的是數(shù)據(jù)刷新前的dom,無(wú)法滿足需要,這個(gè)時(shí)候就用到了$nextTick。

        35、vue和react的區(qū)別是什么?

        ① React嚴(yán)格上只針對(duì)MVC的view層,Vue則是MVVM模式

        ② virtual DOM不一樣,vue會(huì)跟蹤每一個(gè)組件的依賴關(guān)系,不需要重新渲染整個(gè)組件樹(shù).而對(duì)于React而言,每當(dāng)應(yīng)用的狀態(tài)被改變時(shí),全部組件都會(huì)重新渲染,所以react中會(huì)需要shouldComponentUpdate這個(gè)生命周期函數(shù)方法來(lái)進(jìn)行控制

        ③ 組件寫(xiě)法不一樣, React推薦的做法是 JSX + inline style, 也就是把HTML和CSS全都寫(xiě)進(jìn)JavaScript了,即'all in js'; Vue推薦的做法是webpack+vue-loader的單文件組件格式,即html,css,jd寫(xiě)在同一個(gè)文件;

        ④ 數(shù)據(jù)綁定: vue實(shí)現(xiàn)了數(shù)據(jù)的雙向綁定,react數(shù)據(jù)流動(dòng)是單向的

        ⑤ state對(duì)象在react應(yīng)用中不可變的,需要使用setState方法更新?tīng)顟B(tài);在vue中,state對(duì)象不是必須的,數(shù)據(jù)由data屬性在vue對(duì)象中管理

        瀏覽 55
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            成人A片无码电影 | 综合色图 | 男人的天堂亚洲热 | 无码三级片视频 | 日韩美女tickle挠双乳免费网站 | 婷婷五月天丁香社区 | 丝袜老师踩我的喷水 | 玛丽莲传媒堕落人妻2 | 婷婷午夜剧场 | 久久无码高清 |