Summary of practical interview questions related to Shangpinhui VUE project

1. What is the difference between v-show and v-if?

v-show: control through style display
v-if: operate by manipulating DOM elements

2. When developing a project, what are the optimization methods?

1: v-show|v-if (Footer component is present at the bottom of the homepage|search, but there is no Footer component in login and registration. The Footer component is
displayed|hidden, select v-show|v-if)
2: Load on demand (for the loadsh plugin , element, which encapsulates many functions)
3. Function anti-shake and throttling
4. Request performance optimization:

  • Request data optimization
    To send a request, you need to carry parameters to the server: with 100 parameters and 1 parameter [Broadband consumption]
    For the parameters carried to the server: if the value is undefind, when sending a request to the server, the parameters are not carried to the server
  • Optimization of the number of requests:
    1. TypeNav three-level linkage performance optimization?
    - Project: switch home to search or search to home, you will find one thing, the component is frequently sending requests to the server to obtain three-level linkage data for display .
    - If the project frequently sends requests to the server, the performance is very good, so we need to optimize it.
    2. Why do you frequently send requests to the server to obtain the data of the three-level linkage?
    - The data of the three-level linkage is a global component, and jumps are made in the used components, because when the routing jumps, the components will be destroyed [home Created of the component: dispatching action to vuex, so the data of the three-level linkage is obtained frequently]
    - Only one request is required to obtain the data of the three-level linkage, and there is no need for multiple times.
    - Final solution: moutend in App will only be executed once
APP文件
  mounted(){
    
    
    // TypeNav向仓库派发行为 获取数据
    // 放到这里,只需进行一次请求,Home小仓库获得数据后,全局组件TypeNav都会存储到Home小仓库获得的这个数据
    this.$store.dispatch("categroylist");
  },

Although main is also executed once, it is not a component. Without this, the component has the $store attribute

3. Routing pass parameters first close interview questions

 1:路由传递参数(对象写法)path是否可以结合params参数一起使用?
 不可以:不能这样书写,程序会崩掉
 2:如何指定params参数可传可不传?
 3:params参数可以传递也可以不传递,但是如果传递是空串,如何解决?
 4:如果指定name与params配置, 但params中数据是一个"", 无法跳转,路径会出问题
 5: 路由组件能不能传递props数据?

4. Axios secondary packaging

benefit:

  • API unified management, no matter how many interfaces there are, all interfaces can be very clear and easy to maintain.
// 这个文件进行统一的API管理
// 引入axios
import requests from './request'
// 引入mockAjax
import mockrequest from './mockAjax'


// 三级联动的接口
// 这里设置一个函数对外暴露,外面若需要发起三级联动的数据请求调用即可 记住要给函数返回,不然无返回值默认undefined
export const reqCategoryList = ()=>{
    
    
    // 发请求成功返回的是promise对象  直接使用封装好的axios
    return requests({
    
    
        url:'/product/getBaseCategoryList',
        method:'get'
    })

}

// 获取首页banner(首页轮播图的数据)
export const reqGetBannerList = ()=>mockrequest.get('/banner')
    
//获取floor的数据
export const reqGetFloor = ()=>mockrequest.get('/floor')

// 获取search的数据   这个函数需要不需要外部传递的参数?要给服务器带参进行params给服务器传递参数 调这个函数得有相应的参数     错错错需要接收home页传递过来的params数据和query数据/api/list
// 当前这个接口。给服务器发请求的时候,至少得是一个空对象
export const reqGetSearchInfo = (params)=>requests({
    
    
    url:'/list',
    method:'post',
    data:params
})
  • Request Interceptor and Response Interceptor
  • nprogress progress bar
// 这里进行axios的二次封装
// 主要想用请求拦截器和响应拦截器
import axios from 'axios'
// 引入进度条 start开始 end结束
import nprogress from 'nprogress'
// 引入进度条样式
import "nprogress/nprogress.css"

// 1.利用axios的create方法创建一个axios实例
// 2.request其实就是axios,只不过我们又进行了配置和封装
const requests = axios.create({
    
    
    // create里面可以传配置对象

    // 配置对象
    // 基础路径:baseURL就是给每个请求的路径上自动加上所配置的,就不用自己再去书写
    baseURL: '/api',
    // 请求超时的时间
    timeout: 5000
})

// 3.设置请求拦截器,在发请求之前,请求拦截器可以监测到,可以在请求发出去之前做一些事情
requests.interceptors.request.use((config) => {
    
    
    // config其实是一个配置对象,里面有属性headers请求头

    // 进度条开始
    nprogress.start()
    return config
});

//4.设置响应拦截器,里面传入成功的回调和失败的回调
requests.interceptors.response.use((response)=>{
    
    
    // 成功的回调函数,服务器在响应数据成功的时候,响应拦截器可以检测得到,做一些事情
    // 进度条结束
    nprogress.done()

    // 返回data字段  
    return response.data
},(error)=>{
    
    
    // 服务器响应失败回调函数
    // 终结promise
    return Promise.reject(new Error('false'))
})
// 对外暴露
export default requests

5. Function anti-shake and throttling interview questions

Normal: The event is triggered very frequently, and every time it is triggered, the callback function must be executed (if the time is short and there is calculation inside the callback function, then the browser may freeze)

Anti-shake: All the previous triggers are canceled, and the last execution will be triggered after the specified time, that is to say, if the triggers are triggered continuously and quickly, only the last one will be executed

 <button>点击</button>
    <script>
        // 防抖
        const btn = document.querySelector('button')
        // 事件处理函数
        function pay() {
    
    
            console.log("已经购买");
            // 没有处理过就是指向window 正常是button
            console.log(this);
        }
        // 防抖函数
        function debounce(func, delay) {
    
     
            // 3.只创建了一次,是唯一的只不过不断的给timer赋值进行延时而已
            // 每个清除延时就是清除上一个定义的延时,而不是清除新建立的延时
        let timer
            // 因为要在防抖函数里面执行原来的事件处理函数,所以要接收参数来接收,并且去执行这个函数的参数(事件处理函数)
            // 1.一旦监听到了函数就会马上执行,因为要进行处理,使用高阶函数(函数返回函数)
            return function () {
    
    
                // 因为在防抖函数里面的定时器里面的this是指向全局变量window的所以要提前保存this
                let This = this
                let arg= arguments
                //    这里虽然提前声明且清除函数调用函数了,但是每个防抖函数都是独立的没有相互联系,因此要使用作用域链(闭包)将声明放在外面
                // let timer
                // 设置清除延时
                // 2.不能清除一个没有定义的变量名,因此将变量名提前声明
                clearTimeout(timer)
                timer = setTimeout(function () {
    
    
                    // 通过call方法进行绑定这个this给
                    // func.call(This)
                    // 因为后续可能给事件处理函数传参因此使用apply
                    func.apply(This,arg)
                }, delay)
            }
        }
        btn.addEventListener('click', debounce(pay, 1000))
        // 节流
    </script>

Throttling: The callback will not be triggered repeatedly within the specified interval time range, and the callback will only be triggered if the time interval is greater than this time interval, turning frequent triggers into a small number of triggers

 <script>
        const btn = document.querySelector('button')
        function pay() {
    
    
            console.log("已经购买");
            console.log(this);
        }
        // 节流函数
        function throtte(func, delay) {
    
    
            // 节流核心是如果timer被赋值了(有定时在就不进行操作,如果没有赋值就执行任务)
            let timer
            return function () {
    
    
                let This = this
                let arg= arguments
                if(timer){
    
    
                    return;
                }
                timer = setTimeout(function () {
    
    
                    func.apply(This,arg)
                    // 等时间过去,不用清除定时,直接情况timer的值即可
                    // 因为这个清空是在延迟执行任务以后发生
                    timer = null
                }, delay)
            }
        }
        btn.addEventListener('click', throtte(pay, 1000))
    </script>
    方法二
     <script>
         const btn = document.querySelector('button')
        function pay() {
    
    
            console.log("已经购买");
            console.log(this);
        }
        // 节流函数
        function throtte(func, delay) {
    
    
            // 节流核心是如果timer被赋值了(有定时在就不进行操作,如果没有赋值就执行任务)
            let pre = 0;
            return function () {
    
    
                let This = this
                let arg= arguments
                let now = new Date()
              if(now - pre>dalay){
    
    
                fun.apply(This.arg);
                pre = now;
              }
            }
        }
        btn.addEventListener('click', throtte(pay, 1000))
    </script>

6. Routing jump and parameter passing

1. The first type of declarative navigation: Why is there a lag when using the router-link component?
router-link is a component: it is equivalent to an instance object of the VueComponent class. There are many instances (1000+) of new VueComponent in an instant
, which consumes a lot of memory, which leads to lag.
{ { c1. categoryName }}

2. The second programmatic navigation: push|replace

The three-level classification uses programmatic navigation because it will freeze when using router-link.
Because there are a lot of cascading, obtained by the v-for loop, during the loop process, the callback function will also be optimized in turn
: the bubbling principle of programmatic navigation + event delegation will bind a callback function, and it will be corresponding mapped to each child node

When routing jumps [home->search]: it is necessary to pass routing parameters [name of category, id of first, second, and third categories]

this.$router.push()
{
    
    
 name:'search',
 query:{
    
    
    categoryName:'电子书',
    category2Id:4
 }
}
// 三级联动路由跳转和传递参数的业务
    goSearch(event) {
    
    
      // alert(444)
      // 问题1:如何判断点击子节点的是A标签
      // 答:把子节点当中的a标签,加上自定义的属性,其余子节点是没有的(自定义属性:浏览器会将驼峰命名转换为一般的命名)
      // 问题2:如何判断是几级的目录?
      // 答:也是根据自定义属性加上的自身的ID值进行条件判断
      // 问题3:如何获取当前的事件 答:event

      // event.target :获取到的是触发事件的元素(h3,a,dt,dl)
      let node = event.target;
      // 节点有一个属性dataset属性,可以获取自定义属性与属性值 (这里一定要小写,不是给你说了么,浏览器会将自定义属性变为全部小写)
      let {
    
     categoryname, category1id, category2id, category3id } =
        node.dataset;
      console.log(event);
      // 当这个标签是A标签的时候才会进入判断
      if (categoryname) {
    
    
        /*         {
        name:'search',
        query:{
            categoryName:'电子书',
            category2Id:4
        } */
        // 准备路由跳转的参数 设置对象
        let location = {
    
     name: "search" };
        let query = {
    
     categoryname: categoryname };
        // 一级目录
        if (category1id) {
    
    
          query.category1id = category1id;
        } else if (category2id) {
    
    
          query.category2Id = category2id;
        } else {
    
    
          query.category3id = category3id;
        }

        // 路由跳转前要合并参数
        // 1.判断路由中是否有params参数,有则进行合并
        if (this.$route.params) {
    
    
          // 动态的给location添加params属性
          location.params = this.$route.params;
          // 动态的给location添加query属性
          location.query = query;
        }
        this.$router.push(location);
      }
    },

7. Three-level linkage and transition animation in the search module

In the home module, a three-level linkage function is used---->[typeNav]
In the search module, a three-level linkage function is also used------->[typeNav]

TypeNav component business analysis?

  • The three-level linkage is displayed normally in the home module
  • The three-level linkage will be displayed for a while and hidden for a while in search—solution: control the display and hiding of the three-level linkage through a responsive attribute To put it
    bluntly: you need to let the three-level linkage component know who is using it.
  • Let the components distinguish under which module through the route Solution: 1. Add v − show to the Type N av component for dynamic binding 2. Set the initial value of show in the data method 3. Let the components distinguish under which module through the route Solution : 1. Add v-show to the TypeNav component for dynamic binding 2. Set the initial value of show in the data method 3. Passro u t e let the components distinguish under that module Solution: 1. Add v to the T y p e N a v components h o w performs dynamic binding 2. Set the initial value of s h o w in the d a t a method 3. Distinguish through route routing information
    // 当鼠标移入时,全部商品分类列表进行展示
    enterShow() {
    
    
      if (this.$route.path != "/home") {
    
    
        this.show = true;
      }
    },
    // 当鼠标离开的时候,全部商品类别进行影藏
    leaveShow() {
    
    
      if (this.$route.path != "/home") {
    
    
        this.show = false;
      }
  • When the route jumps, the corresponding component will be destroyed and recreated ----[kepp-alive]

4) Transition effects

  • When I first came into contact with it: CSS3
  • There are also transition animation effects in Vue—transition built-in components are completed
 HTML<transition name="sort"> 相应的节点和组件</transition>
 CSS// 过渡动画的样式
    // 开始进入状态
    .sort-enter {
    
    
      height: 0;
    }
    // 结束状态
    .sort-enter-to {
    
    
      height: 461px;
    }
    // 定义动画的时间和速率
    .sort-enter-active {
    
    
      transition: all 0.5s linear;
    }
  • Note 1, in Vue, you can add transition animation effects to (a certain node) | (a certain component)
  • The node|component must have the v-if|v-show instruction before it can be used.

8. Why do you frequently send requests to the server to obtain the data of the three-level linkage?

  • The data of the three-level linkage is a global component, and jumps are made in the used components, because when the routing jumps, the component will be destroyed [created of the home component: dispatching actions to vuex, so the data of the three-level linkage is frequently obtained ], you only need to send a request once to get the data of the three-level linkage, and you don't need to do it multiple times.
  • Final solution: moutend in App will only be executed once
  • Although main is also executed once, it is not a component. Without this, the component has the $store attribute

9. Merge parameters

When entering the search page, various parameters need to be passed, so as to send a request to the server to obtain the corresponding data

  • Combine parameters
    Why do you need to combine parameters (query|params): Because these parameters are useful for search, because search
    sends requests to the server through these parameters, and these parameters need to be carried to the server, and the server will return the corresponding user's search Data, search can be displayed.

1. The developed three-level linkage business, when you click the a label, it will jump to the route, and pass the product name and id to the search module----(query) 2. When the search button is clicked, the
user The entered keyword will be passed to the search module through the params parameter when the button is clicked -----(params)
3. Routing jump (home->search), two places, three-level linkage (typeNav), Header Component (Search Button)

 // 路由跳转前要合并参数
        // 1.判断路由中是否有params参数,有则进行合并
        if (this.$route.params) {
    
    
          // 动态的给location添加params属性
          location.params = this.$route.params;
          // 动态的给location添加query属性
          location.query = query;
        }
        this.$router.push(location);
      }

9. mock data

If the interface is not well written, the front-end personnel can mock some data [some fake interfaces simulated by the front-end programmers themselves]. When the project is launched during work, it is necessary to replace the mock data with the interface data given by the background.

10. Communication between components

props: parent-child
slot: parent-child
custom event: parent-child
global event bus $bus: universal
pubsub: universal
Vuex: universal
$ref: parent-child communication

11. The user needs to make multiple requests to render the corresponding data in the search module

Start: Put it in the mounted lifecycle hook, only one request will be made.
Solution: The $route method of watch and route monitors whether the information of the route changes.

// 数据监听,监听组件实例身上的属性值发生变化  从而用户可以重复的根据组件身上的数据去重复的发送请求
  watch: {
    
    
    // 监听路由的信息是否发生变化
    $route(newValue,oldValue) {
    
    
      // 再次向服务器发送请求之前整理数据带给服务器
      Object.assign(this.searchParams,this.$route.params,this.$route.query)
      // console.log(this.searchParams);
      // 再次发送请求 解决只能一次去发送请求
       this.getData();
      //  每一次请求的时候,应该把相应的123级ID清空,让他接收下一次的相应的123ID
      // 分类和关键字不用清理,因为每次路由发生变化的时候,会给他重新赋值
      this.searchParams.category1Id = ''
       this.searchParams.category2Id = ''
       this.searchParams.category3Id = ''
    },
  },

おすすめ

転載: blog.csdn.net/qq_59079803/article/details/124140934