vue 中级基础考察面试题

vue 生命周期有哪些
 beforeCreate
 created
 beforeMount
 mounted
 beforeUpdate
 updated
 activated
 deactivated
 beforeDestroy
 destroyed
 errorCaptured
初始化请求数据在那个生命钩子里
// 最好放到 created 钩子里,在页面没有渲染之前
mounted
// mounted 钩子,是在dom 渲染完成后调用的钩子,当需要dom 加载完成后执行的操作,需要放到 该钩子函数中
activated deactivated
// 重复进出缓存组件的同时,需要做一下操作时很有用
activated 激活该组件时调用,初次进入也是调用,只要激活该组件
deactivated 组件失活时调用
父子组件渲染过程
----父子组件加载过程----
//父beforeCreate => 父created => beforeMount => 子 beforeCreate => 子created => 子beforeMounted => 子mounted => 父mounted
----父子组件更新过程----
// 父beforeUpdate => 子 beforeUpdate => 子updated => 父updated
----父子组件销毁过程----
// 父beforeDestroy => 子beforeDestroy => 子destroyed => 父destroyed
父组件怎么监听子组件的生命周期(两种方法)
方法一
// 自定义事件,当触发子组件对应的生命钩子函数时,通过$emit 通知父组件
-----------------------父组件-----------------
<template>
    <div>
        <child @gouzi="gouzi"></child>
    </div>
</template>
<script>
import child from './child.vue'
export default {
    name:'parent',
    components:{
        child
    },
    methods:{
        gouzi(val) {
            console.log(val)
        }
    }

}
---------子组件-----
<template>
    <div>
         <el-button @click="add">增加金额</el-button>
    </div>
</template>
<script>
export default {
    name:'child',
    mounted() {
        this.$emit('gouzi','子组件的mounted 钩子')
    }
}
</script>
方法二
// 通过 hook 方法监听子组件的钩子函数,以监听子组件 mounted 钩子为例
-----------------------父组件-----------------
<template>
    <div>
        <child @hook:mounted="doCallback"></child>
    </div>
</template>
<script>
import child from './child.vue'
export default {
    name:'parent',
    components:{
        child
    },
    methods:{
        doCallback() {
            console.log('监听子组件 钩子函数 的回调')
        }
    }

}
---------子组件-----
<template>
    <div>
       子组件
    </div>
</template>
<script>
export default {
    name:'child',
    mounted() {
       console.log('子组件 mounted 钩子')
    }
}
// 子组件 mounted 钩子
// 监听子组件 钩子函数 的回调
</script>
vue 常用的指令
 v-if
 v-show
 v-model
 v-on
 v-bind
 v-for
 v-slot
v-if v-show 的区别
 两者都是有隐藏的功能,区别如下
 v-if 是dom元素的插入和删除
 v-show 是dom元素的显示和隐藏,操作的css样式 display:none/block
vue 父子组件传值的方法有几种
父子组件传值
1,父组件通过 prop 传值,子组件通过 $emit 向父组件 传值
2,通过v-model value input 传值(看下面示例)
3,通过 update sync 进行传值(看下面示例)
4,通过事件总线eveBus
5,直接操作子组件的数据 子组件通过$parent 向父组件传值
6, vuex
// 通过v-model 进行父子组件之间的传值
// v-model 就是一个语法糖 父组件通过默认属性 value传值,子组件通过默认事件 input 向父组件传值
-----------------------父组件-----------------
<template>
    <div>
        <model v-model="price"></model>
    </div>
</template>
<script>
import model from './model.vue'
export default {
    name:'parent',
    components:{
        model
    }
}
---------子组件-----
<template>
    <div>
         <el-button @click="add">增加金额</el-button>
    </div>
</template>
<script>
export default {
    name:'child',
    props: ['value'], // 接受值 value
    methods: {
        add() {
          this.$emit('input', '我是子组件传的值')  // 通过默认时间 input 向父组件传值
        }
    }
}
</script>
// sync update 配合使用
<template>
    <div>
       <atest :dialogVisible.sync="dialogVisible"></atest>
       <button @click="open">显示 弹框 {{ dialogVisible }}</button>
    </div>
</template>
<script>
import atest from './atest.vue'
export default {
    name:'parent',
    components:{
        atest
    },
    data(){
        return{
           dialogVisible: false
        }
    },
    methods: {
        open () {
          this.dialogVisible = !this.dialogVisible
        }
    }
}
------子组件----
<template>
    <div>
      <span v-if='dialogVisible'>
        <el-button @click="close">取 消</el-button>
      </span>
    </div>
</template>
<script>
export default {
    name:'child',
    props: ['dialogVisible'],
    methods: {
        close() {
             this.$emit('update:dialogVisible', false)
        }
    }
}
</script>
vue 组件跨代传值(爷孙组件及更深层组件)的方法
1. $attr $listeners(看示例)
2, provide/inject。(看示例)
3,通过事件总线eveBus
4,直接操作子组件的数据 子组件通过$parent 向父组件传值
5, vuex
$attr $listeners 组件跨代传值
// 父组件
<template>
    <div>
        <child :price="price" :from='from' :num='num' @upRocket="reciveRocket"></child>
    </div>
</template>
<script>
import child from './child.vue'
export default {
    name:'parent',
    components:{
        model
    },
    data() {
        return {
           // child 组件接受的参数
            from:{
                name:'wg',
                age:18
            },
            price:200,
            num:2
        }
    },
    methods:{
       // 要传递的函数
       reciveRocket () {
            console.log("reciveRocket success")
       }
    }
}
// 子组件
<template>
  <div class="a">
    <div>子组件</div>
    <grandson :pageNum='pageNum' :pageSize='pageSize' v-bind="$attrs" v-on="$listeners"></grandson>
  </div>
</template>
<script>

import grandson from './grandson.vue'


export default {
  name: 'child',
  props: ['from'], // 通过props 接受一个from
  components: {
    grandson
  },
  data () {
    return {
        pageNum:1,
        pageSize:10
    }
  },
  mounted() {
    console.log(this.$attr,'attr')  
    console.log(this.$listeners,'listeners')
    // price num 'attr'   (父组件传进来 from price num, 子组件通过props 接受了 from, $attr 就剩下 price num)
    // upRocket  'listeners'  父组件定义的函数
  },
  methods: {

  }
}
</script>
// 孙子组件
<template>
  <div class="grandson">
    <div>孙子组件</div>
    <button></button>
  </div>
</template>
<script>

export default {
  name: 'grandson',
  components: {
    grandson
  },
  data () {
    return {
    }
  },
  mounted() {
    console.log(this.$attr,'attr')  
    console.log(this.$listeners,'listeners')
    // pageNum pageSize price num  'attr'  => attr 接受除props 接受的外的 所有属性
    // upRocket  'listeners'  接受父组件绑定的函数,(父组件直接绑定的爷组件定义的函数)
  },
  methods: {

  }
}
</script>
如果跨代很多,$attr $listeners就会有点太繁琐,可以考虑 provide/inject
父组件通过 provide传值, 子组件 通过 inject 接受值,不过不是响应式的,具体参考官网(详细)点击这里
// 父级组件提供 'foo'
var Provider = {
  provide: {
    foo: 'bar'
  },
  // ...
}

// 子组件注入 'foo'
var Child = {
  inject: ['foo'],
  created () {
    console.log(this.foo) // => "bar"
  }
  // ...
}
兄弟组件传值
  // 1,eventBus
  // 2,vuex
  // 实际开发中,更倾向于子组件通过$emit 触发父组件函数,父组件再改变值传给 兄弟组件
watch computed 有什么区别
1. 当一个对象改变需要做一些逻辑处理或者开销比较大的时候,考虑使用watch
2. 当多个变量都会对某一个产品影响时,考虑使用 computed
$set 什么用途
// vue2.0 中,数据视图响应式是根据 Object.defineProperty 劫持属性的getter和setter 结合发布订阅者模式实现的,新加的属性实现响应,要用$set 对该属性进项劫持才能实现响应式
怎么缓存组件或者页面
// 用keep-alive,进行缓存,(不需要重新创建卸载 => 缓存) 
路由有哪几种模式
// 浏览器端 hash 模式 history模式, 服务端 Abstract 模式,主要介绍浏览器端
// hash 变现为 url路径有#,原理是 通过监听 hashChange 进行路由的转换
// history 是Html5 新加的 History模式,原理是通过监听 pushState popState replaceState 进行路由的转换
路由传参有那些方式 三种方法
// 动态路由 路由表中配置占位符
   {
     path: '/list/:id',
     name: 'list',
     component:list
   }
// 通过 push 跳转
  this.$router.push({
    path: `/particulars/${id}`,
  })
// 通过 this.$route.params.id 取参
// path 方法传参
        this.$router.push({
          path: '/list',
          query: {
            name: 'wg'
          }
        })
// 通过 this.$route.query.name 取参
// name 方法传参
       this.$router.push({
          name: 'list',
          params: {
            age: '18'
          }
        })
// 通过 this.$route.params.age 取参
路由懒加载有几种 两种 require import
// require 方式
    {
      path: '/about',
      name: 'About',
      component: resolve => require(['../pages/About.vue'], resolve)
    }
// import 方式
  {
    path: '/HelloWorld',
    name: 'HelloWorld',
    component: () => import("@/components/HelloWorld") // @ 通过webpack 配置,默认 指向src 文件
  }
vuex 有那几个模块组成
// state   定义变量
// getters   派生状态 类似于计算属性
// mutations 改变 store 中的状态
// actions  主要操作异步操作,在组件中通过 this.$store.dispatch('xxx') 去触发actions方法
// modules  把store 分为细小的模块,应用于复杂的模块
mutations 和 actions 的区别
// mutations 主要用于同步操作 store.commit('xxx') 触发
// actions 主要用于异步操作 store.dispatch('xxx') 触发actions, actions 在通过触发 mutations 更改 state状态 
怎么解决 vuex 刷新数据丢失的问题
// 把数据存到 sessionStorage中,当页面刷新时 store的初始值 从 sessionStorage中取
// 其关键点在于 把store的值什么时候存到 sessionStorage中,建议是 当页面刷新之前,可以再入口app.vue组件created钩子中 添加监听 beforeunload 进行处理赋值

最后一个 vue2.0 中 双向绑定的原理 (基础版)
// vue通过 Object.defineProperty 劫持data中各个属性的getter和setter,结合发布订阅者模式 进行数据和视图的响应
posted @ 2021-10-14 17:20  一晃十年  阅读(351)  评论(0编辑  收藏  举报
业精于勤荒于嬉 行成于思毁于随