Vue基础自测45题


1.什么是Vue?Vue的核心理念是什么?

Vue是一套构建用户界面的渐进式框架
与其他重量级框架不同的是,Vue 采用**自底向上增量开发**的设计。
Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。
核心理念组件化开发、数据驱动视图 ( 双向数据绑定 )


2.什么是MVC和MVVM?

MVC是前后端未分离时的分层开发概念,MVVM是前后端分离后的前端开发的概念;

细说就是( 以下为个人理解,或有谬误,欢迎指正 ):

  1. MVC和MVVM中的Model层都用于数据操作,但是二者有本质区别,MVC中的Model是真正的服务端数据库,
    MVVM中的Model本身的数据量很小,大部分所需数据都是从服务端请求回来的;

  2. MVVM中的View视图层,是用户能够看到并进行交互的客户端界面;
    整个MVVM都属于MVC中的View视图层。

  3. MVC中的 Controller 业务逻辑层负责收集用户输入的数据,向相关Model请求数据并返回相应的视图来完成交互请求

  4. MVVM中的ViewModel层也是业务逻辑层,或者说调度层,是MVVM中的核心概念,它实现了双向数据绑定:
    可以把Model层的数据渲染到View视图层,同时View视图层的数据发生改变也可以自动同步到Model层中;
     
    VM解放了前端程序员的双手,前端程序员不用再进行不必要的DOM操作了,只需关心前端的业务逻辑即可


3.框架和库的区别?

框架是一套完整的解决方案;对项目的侵入性较大,项目如果需要更换框架,则需要重新架构整个项目。
例如:node中的express

库(插件):提供某一个小功能,对项目的侵入性较小,如果某个库无法完成某些需求,可以很容易切换到其它库实现需求。
例如:从Jquery 切换到 Zepto


4.插值表达式

插值表达式: {{}} , 使用v-once指令可以执行一次性的插值,当数据改变时,插值处的内容不会更新


5.vue指令界面防止闪烁

v-cloak

<style>
  [v-cloak] {
    display: none;
  }
</style>
<div v-cloak>{{msg}}</div>

原理:数据没加载好之前隐藏显示,加载好之后再显示


6.vue指令v-html和v-text的异同

①相同之处:v-html 和 v-text 都会覆盖元素原来的内容
②不同之处:v-html 可以解析富文本,但 v-text 不行


7.vue属性绑定指令及简写:

指令: v-bind:
简写为冒号:


8.vue事件绑定指令及简写:

指令:v-on:
简写为艾特符号@


9.vue事件修饰符有哪些

.self.once.stop.prevent.capture
事件修饰符可以连用,即链式书写,但.once和.prevent连用会引发一个问题
(例如在表单提交按钮下使用,第一次提交失效后,再按就会刷新页面,然后又可以继续提交并刷新页面)


10.vue指令-双向数据绑定

一般只在 input 标签中使用,指令:v-model:value=“”,简写:v-model=“”


11、v-for如何遍历对象、数组、数字

a)遍历数组:(item,index) in list :key="index"
b)遍历对象:(value,key,index) in obj :key="value.id"
c)遍历数字:num in 1234 :key="num"


12、v-for为什么设置key,key值有什么要求

  1. 让界面元素和列表里的每个元素进行记录绑定,提高重排效率,提升渲染速度,可以实行 “就地复用” 策略
  2. key只能是字符串或者数字
  3. key必须是唯一的

13、v-if 和 v-show 的区别

v-if 是删除和添加dom元素,v-show 是设置元素的display属性来完成显示与隐藏效果


14、vue绑定class类名的方式

  1. 字符串 :class="'normal'"
  2. 对象 :class="{'big':true}" 对象的键是样式的名字,值是Boolean类型
  3. 数组 :class="[csgo,styleArr]"
  4. 数组内置对象 :class="[csgo,{ bigFontSize : flag }]"
  5. 三目表达式 :class="flag ? csgo : styleArr"
  6. 函数返回值

15、vue绑定style内联样式的方式

  1. 直接在:style=""里写样式对象,记得加单引号
    :style="{'font-size':'30px'}"

  2. 在data里定义样式对象然后直接引用

  <p :style="innerStyle">data里定义一个对象,对象里直接设置样式</p>

  innerStyle: {
    color: 'red',
    fontSize: "25px"
  }
  1. 通过数组引用多个data中的样式对象
    :style = "[innerStyle, innerStyle2, innerStyle3]"
  2. 函数返回值
 <p :style="setStyle()"> csgo </p>
   setStyle() {
      return { color: "green", fontSize: "25px" }
    }

16、vue过滤器的全局和局部声明方式及使用

全局:
    Vue.filter("过滤器名称",function(data,format){
      return ......
    })

局部:
    filters:{
      过滤器名称:function(data,format){
        return ......
      }
    }

过滤器可以用在两个地方:插值表达式和 v-bind 表达式 (后者从 2.1.0+ 开始支持)。
插值表达式:{{ message | filterA | filterB }}
v-bind表达式:<div v-bind:id="rawId | formatId"></div>

17、vue键盘修饰符设置别名

  Vue.config.keyCodes = {
    v: 86,
    f1: 112,
    // camelCase 驼峰命名法不可用
    // mediaPlayPause: 179,
    // 取而代之的是 kebab-case 我称之为横杠连接法,且用双引号括起来
    "media-play-pause": 179,
    up: [38, 87]
  }
  或单个按键:Vue.config.keyCodes.j = 74

18、vue自定义指令的全局和局部声明方式及使用

全局定义:

<script>
    Vue.directive('focus', {
      // 只调用一次,指令第一次绑定到元素时调用。
      //在这里可以进行一次性的初始化设置。
      bind(el, bingding) {
        el.style.color = "red"
      },
      // DOM元素渲染完毕后执行
      inserted(el) {
        el.focus()
      },
      // 元素有更新时执行
      update(el) {
        el.style.fontSize = '18px'
      }
    })
</script>

局部定义:

let vm = new Vue({
    el: "#box",
    data: {
      color: "hotpink"
    },
    methods: {
    },
    directives: {
      big: {
        bind(el, binding) {
          el.style.fontSize = binding.value
        }
      },
      color: {
        bind(el, binding) {
          el.style.color = binding.value
        }
      },
      'focus-auto': {
        // 只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
        bind(el, binding) {
          el.style.color = "red"
        },
        // 元素渲染完毕后执行
        inserted(el) {
          el.focus()
        },
        // 元素有更新时执行
        update(el) {
          el.style.fontSize = '18px'
        }
      }
    }
  })

el:指令所绑定的元素,可以用来直接操作 DOM;
binding是一个对象,里面有n多属性,value是其中的一个
使用: DOM元素里添加 v-自定义指令名称=“binding.Value”

<input v-focus-auto="" type="text">

19、vue生命周期钩子函数有哪些?

1. beforeCreate()
2. created()
3. beforeMount()
4. mounted()
5. beforeUpdate()
6. updated()
7. beforeDestroy()
8. destroyed()

20、vue生命周期钩子函数各阶段特点及可以用来作什么?

  beforeCreate生命周期钩子函数:
  初始化尚未完成,data数据,methods方法都未挂在在vue实例上
  一般用于页面重定向

  created生命周期钩子函数:
  初始化已经完成,data数据,methods方法都可以被调用了
  是第一个能操作data中数据对象和调用methods方法的生命周期,
  一般用于接口请求+数据初始化

  beforeMount生命周期钩子函数:
  进入运行阶段前;此时虚拟dom尚未挂载,页面元素尚未更新

  mounted生命周期钩子函数:
  dom元素挂载后,如果需要操作dom,可以在此mounted周期执行

  beforeUpdate生命周期钩子函数:
  元素发生更新时,元素更新前的阶段;可以执行0次到多次;

  updated生命周期钩子函数:
  元素发生更新时,元素更新完成的阶段;同样可以执行0次到多次;

  beforeDestroy生命周期钩子函数:
  vue销毁前的阶段,一般用来清除定时器等操作。

  destroyed生命周期钩子函数:
  vue销毁后的阶段,好像没什么用。

21、vue-resource如何发送get,post请求

GET请求:this.$http.get(URL)

POST请求:this.$http.post(URL, {参数} , {emulateJSON})
{ emulateJSON } 默认为false


22、vue-resource发送post请求时第三个参数是什么,有什么作用?

第三个参数是: {emulateJSON}

用来设置POST请求提交的参数编码类型是否为 application/x-www-form-urlencoded

值为 false 时参数类型默认为application/json,默认编码格式为charset=UTF-8 。


23、axios如何发送get,post请求

发送GET请求:axios.get(URL)

发送POST请求:axios.post(URL,{JSON参数})

如果参数类型不是application/json则需要使用内置参数对象


24、axios发送post请求时使用的内置参数对象是什么

  1. 传参格式为 formData: let formData = new FormData();
     
    (全局请求头:‘Content-Type’= ‘application/x-www-form-urlencoded’
    (request的Header:‘Content-Type’= ‘multipart/form-data’

 

  1. 传参格式为 query 形式: let params = new URLSearchParams();
     
    (全局请求头:‘Content-Type’= ‘application/x-www-form-urlencoded’
    (request的Header:‘Content-Type’= ‘application/x-www-form-urlencoded’

25、vue中过渡动画类名有哪些

v-enter(vue3中为v-enter-from)、v-enter-to、v-enter-active
v-leave(vue3中为v-leave-from)、v-leave-to、v-leave-active

26、vue中过渡动画结合第三方插件使用

引入animate.css,直接使用它的类名:

enter-active-class = "animated slideInRight"
leave-active-class = "animated bounceOutRight"

27、vue中过渡动画中钩子函数的使用

@before-enter @enter @after-enter

<transition
    @before-enter="beforeEnter"
    @enter="enter"
    @after-enter="afterEnter">
      <div v-if="isshow" class="show">OK</div>
</transition>

定义三个 methods 钩子方法:

  methods: {
      beforeEnter(el) { // 动画进入之前的回调
        el.style.transform = 'translateX(500px)';
      },
      enter(el, done) { // 动画进入完成时候的回调
        el.offsetWidth;
        el.style.transform = 'translateX(0px)';
        done();
      },
      afterEnter(el) { // 动画进入完成之后的回调
        this.isshow = !this.isshow;
      }
    }

28、vue中如何设置v-for列表动画

需要使用 <transition-group> 组件把v-for循环的列表包裹起来

  <transition-group tag="ul">
     <li v-for="(item, i) in list" :key="i">{{item}}</li>
  </transition-group>

29、vue中如何声明组件?

先写一个组件标签:

  <template id="tmpl">
    <div><a href="#">登录</a> | <a href="#">注册</a></div>
  </template>

全局声明方式:

  Vue.component("组件名",{
  	 template:"#组件id"
  })

私有声明方式:

  const vm = new Vue({
	  el: '#app',
	  data: {
	    flag: true
	  },
	  methods: {},
	  components: {
	    "register": {
	      template: "#register"
	    },
	    "test": {
	      template: "#login"
	    },
    // 必须写ID,不可以写类名
    // "lll": {
    //   template: ".lllllll"
    // }
    }
  })

30、vue中如何父组件给子组件传值

  1. 子组件中设置 props属性 配置项(和data同级),在props属性中设置接收数据的名称与类型,可以使用数组设置多个接收类型,也可以使用 default函数 设置默认值;
  2. 设置完成后在子组件标签中绑定props中定义的参数,属性值可以是父组件中的数据或者其他字符串:
    <course :type="theFree"></course>
    <script>
     Vue.component("course", {
        template: "#course",
        props: {
          type: String,
          'page-num': [Number, String],
          'page-size': [Number, String],
          test: {
              type: String,
              default: function () {
                return '这是一个默认的名字'
              }
            },
        },
        data() {
          return {
            courseList: [],
          }
        },
      })
    </script>

31、vue中如何子组件给父组件传值

  1. 子组件标签中绑定自定义事件,在子组件的methods里声明自定义事件,书写方法体, 调用this.$emit('自定义事件名称',传递数据)方法

  2. 父组件的methods里声明自定义事件的接收方法(@xxxx=“xx”    后面的xx)

  3. 触发自定义事件,子组件传值,父组件接收(接受方法中的第一个参数data就是传来的数据,也可以第一个参数传 $event,第二个参数接收数据)


32、vue中如何使用插槽,两种插槽的区别

使用: 在组件中声明<slot></slot>标签,填充插槽时直接在组件标签里写填充内容

区别: 默认插槽声明时直接写<slot></slot>,使用时可以直接在组件标签里写填充内容;

具名插槽在声明时要加一个name属性,<slot name=""></slot>
填充时要写template标签:<template v-slot:插槽名>填充内容</template>


33、前端路由和后端路由的区别

  1. 后端路由:
    所有的超链接都是URL地址,所有的URL地址都对应服务器上对应的资源,切换页面时每次都向后台服务器发出请求,服务器响应请求,会打开新页面或者刷新页面

  2. 前端路由:
    对于单页面应用程序来说,主要通过URL中的 hash(#号) 来实现不同页面之间的切换,每次跳转到不同的URL都是使用前端的锚点路由,不会重新请求和刷新页面。
     
    同时,hash有一个特点:HTTP请求中不会包含hash相关的内容;
    这种通过hash改变来切换页面的方式,称作前端路由(其中的一种,还有一种history模式,不带#号)


34、vue中如何使用路由

  1. 引入js文件,这个js需要放在vue.js后,自动安装(提供了一个VueRouter的构造方法)

  2. 使用 new VueRouter() 构造方法创建路由实例,构造方法可以接收一个参数,参数类型为对象类型

  3. 在参数对象中配置属性 routes:[],这个数组中的元素是路由对象,路由对象里包含path属性和component属性
     
    path属性是 路由的路径,即在哪个路径下显示哪个组件 ,component属性就是这个路径下要显示的组件(直接传组件对象,不加引号)

  4. 创建的router需要和vue实例关联一下,将路由实例挂载在vue实例上

  5. 在可操作区域中预留路由的显示位置,即指定在特定路径时,路由中的组件显示在哪个位置,需要使用标签:<router-view></router-view>


35、路由跳转两种方式(声明式,函数式)

  1. 路由的声明式跳转需要使用:router-link 标签,标签中有一个 to 属性,它的属性值是路由的路径;<router-link to="/index">去首页</router-link>

  2. 函数式跳转:this.$router.push({ path: '/index' })

<button @click="toIndex">回到主页按钮</button>
<script>
  toIndex() {
    this.$router.push({ path: '/index' })
  }
</script>

36、路由传参两种方式(声明式,函数式)

  1. 声明式:
       query传参:
<!-->问号拼接后参数<-->
<router-link to="/index/login/personal?id=1&name=张三" tag="button">去个人中心页</router-link>
<!-->模板字符串<-->
<router-link :to=`/index/login/personal?id=${id}&name=${name}` tag="button">去个人中心页</router-link>
<!-->对象形式<-->
<router-link :to="{path:'/index',query:{id,name}}" tag="button">去个人中心页</router-link>

         params传参:

                 需要先在路由对象的path属性中声明参数占位符
                path: "personal/:id/:name"

<!-->直接传参<-->
<router-link to="/personal/666/张三" tag="button">去个人中心页</router-link>
<!-->模板字符串的形式<-->
<router-link :to=`/index/login/personal/${id}/${name}` tag="button">去个人中心页</router-link>
<!-->对象的形式<-->
<router-link :to="{name:'personal',params:{id:'666',name:'张三'}}">去个人中心页</router-link>
  1. 函数式:传参则必须配置name别名,不能使用path
     
    query传参:
    this.$router.push({ name:'index', query:{id:666,name:"张三"} })
     
    params传参:
    this.$router.push({ name:"personal", params:{id:666,name:"张三"} })

37、路由如何嵌套

  1. 创建路由实例时,在路由对象中设置 children属性,它的属性值是一个数组,数组里的元素是路由对象,
  2. 这个数组中的路由对象对应的组件在显示时就会渲染在它父组件的<router-view>中。
  3. 只要是路由对象都可以设置children属性,故可以层层嵌套!
const router = new VueRouter({
    routes: [
      {
        // 初始页面路径重定向
        path: '/',
        redirect: '/index'
      },
      {
        path: '/index',
        component: index,
        children: [
          {
            // 不加/使用的是相对路径,后面也可以直接跟参数什么的
            path: 'login',
            component: login,
            children: [
              {
                path: "personal",
                component: personal
              }
            ]
          }
        ]
      },
    ]
  })

38、路由高亮

Vue-router 提供了一个现成的类名 .router-link-active 来设置选中路由的样式,
我们只需要在 CSS 中自定义自己喜欢的样式即可,比如选中后变红,字体变大

自定义选中路由高亮类名只需配置这个配置项:linkActiveClass: “iChooseYou”


39、ref的使用

  1. 应用在HTML标签上获取的是真实的DOM元素
  2. 应用在组件标签上获取的是组件实例对象。
<p ref="test">我是p标签,我打了个ref标识</p>
<course ref="test2">我是自定义组件,我打了个ref标识</course>

获取元素:this.$refs.xxx 例如 :在可操作区域内,this.$refs.test 就能拿到这个DOM元素


40、属性计算,属性监听

  1. 属性计算 - computed
    computed:{
       属性名:{
         get(){
           return ...
         },
         set(newValue){
           ...
         }
       }
     }

需要双向绑定:<input type="text" v-model="属性名">

当你确定了属性只会被读取而不会被改变时可以采用简写的方式:
                              属性名(){return ...}

  1. 属性监听 - watch
  watch:{
      需要监视的属性名:{
      	//初始化时让handler调用一下
        immediate:true,
        handler(newValue,oldValue){
          //handler在监视的属性的属性值发生变化时调用
          ......
        }
      }
    }

如果你确定不需要用到 immediate 和深度监视 deep,那么就可以使用简写,
用到其中的任何一个都不能使用简写:
需要监视的属性名(newValue,oldValue){......}


41、什么是vuex?

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式 + 库。
它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。


42、为什么用vuex?解决了什么问题?

①当我们的应用遇到多个组件共享状态时,单向数据流的简洁性很容易被破坏
②vuex解决了多组件之间状态共享的问题,不用再把数据互相传来传去了。

官方单向数据流示意:
状态:驱动应用的 数据源
视图:以声明方式将 状态映射 到视图;
操作:响应在视图上的用户输入导致的状态变化
在这里插入图片描述


43、Vuex的核心模块?

Vuex有五大核心概念(模块),即:

  1. State(状态)
  2. Mutation (改变State,必须是同步函数)
  3. Action (提交Mutation来改变State,可包含异步操作)
  4. Module (模块化管理)
  5. Getter (加工Store库中的数据,不改变元数据,产生新数据)

关于它们的具体作用及如何使用可移步至:Vue基础 -Vuex


44、Vuex状态刷新重置问题如何解决

由于Vuex的数据是存储在内存中的,相当于memory cache,当页面刷新的时候内存被清空重载新内容,原来的数据就丢了。

为了解决这个我们可以借助浏览器的本地存储来解决,即:

  1. localStorage - 本地长期存储
  2. sessionStorage - 会话期间存储

根据需求自行选择即可,一般使用sessionStorage,因为localStorage太持久了。

或者,还有一种特殊情况,比如验证用户是否已经是登录状态,如果登录状态存储在Store中,每次刷新页面这个登录状态数据就没了。

此时也可以在后台专门设置一个接口来返回用户登录状态,每次刷新页面都重新请求这个接口也可以达成目的。(只是一种方法,不是最优解)


45、什么是路由守卫?如何配置?

路由守卫是路由在跳转前、后过程中的一些钩子函数,这些函数可以让你操作一些其他的事,在后台管理中设置权限时经常看到,在实现路由跳转前校验是否有权限,有权限就可以通过,反之就会被执行其他操作,如返回首页。

路由守卫的参数:

  1. to:目标路由对象

  2. from:即将要离开的路由对象

  3. next():放行(可选参数)

路由守卫分为:全局守卫,组件内的守卫,路由独享守卫

  1. 创建 全局前置守卫
const router = createRouter({ ... })

router.beforeEach((to, from) => {
  // ...
  // 返回 false 以取消导航
  return false
})
  1. 创建组件守卫
const UserDetails = {
  template: `...`,
  beforeRouteEnter(to, from) {
    // 在渲染该组件的对应路由被验证前调用
    // 不能获取组件实例 `this` !
    // 因为当守卫执行时,组件实例还没被创建!
  },
  beforeRouteUpdate(to, from) {
    // 在当前路由改变,但是该组件被复用时调用
    // 举例来说,对于一个带有动态参数的路径 `/users/:id`,在 `/users/1` 和 `/users/2` 之间跳转的时候,
    // 由于会渲染同样的 `UserDetails` 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
    // 因为在这种情况发生的时候,组件已经挂载好了,导航守卫可以访问组件实例 `this`
  },
  beforeRouteLeave(to, from) {
    // 在导航离开渲染该组件的对应路由时调用
    // 与 `beforeRouteUpdate` 一样,它可以访问组件实例 `this`
  },
}
  1. 创建路由独享守卫
const routes = [
  {
    path: '/users/:id',
    component: UserDetails,
    beforeEnter: (to, from) => {
      // reject the navigation
      return false
    },
  },
]

更多详情请移步至此博主:元元元缘官方文档

Logo

前往低代码交流专区

更多推荐