vue基础

1.Vue框架是什么?

        Vue是一款以响应式数据为核心驱动页面渲染的Web页面渲染引擎,在Vue框架中一切响应式的数据变化都可以驱动视图更新。同时Vue框架使用虚拟DOM的方式异步的执行视图更新。

2.vue生命周期?

总共分为8个阶段创建前/后,载入前/后,更新前/后,销毁前/后。

创建前/后: 在beforeCreate阶段,vue实例的挂载元素el和数据对象data都为undefined,还未初始化。在created阶段,vue实例的数据对象data有了,el为undefined,还未初始化。

载入前/后:在beforeMount阶段,vue实例的$el和data都初始化了,但还是挂载之前为虚拟的dom节点,data.message还未替换。在mounted阶段,vue实例挂载完成,data.message成功渲染。

更新前/后:当data变化时,会触发beforeUpdate和updated方法

销毁前/后:在执行destroy方法后,对data的改变不会再触发周期函数,说明此时vue实例已经解除了事件监听以及和dom的绑定,但是dom结构依然存在

3.Vue框架和传统的DOM框架对比,有何区别?

        DOM 

        遍历DOM树获取DOM对象;确认需要操作的视图属性;更改对象的属性触发视图更新,视图执行一次更新;

        Vue

        初始化框架构建虚拟DOM树,将响应式数据对象映射到虚拟DOM树中。更改需要更新的属性,将更新队列中的任务一次进入虚拟DOM中,将虚拟DOM中需要变更的部分一次设置到DOM对象中。

        总结

        通过对比得知传统的DOM框架采用的视图更新机制是同步方式进行的,所以一旦涉及到操作DOM属性就会触发DOM树进行一次渲染,当页面有N步数据更新的时候就算N步数据是同时改的,视图部分也会进行N次渲染。

        而Vue框架是采用非直接DOM操作的方式进行页面渲染,这样可以将视图更新时的多次更改放到一个任务队列中,最终将本次更改的N次变化统一由一次渲染替代真实的DOM对象,这样可以实现N次变更,一次渲染。在性能上更优于传统的DOM框架。

4.为什么vue组件中data必须是一个函数?

      对象为引用类型,当复用组件时,由于数据对象都指向同一个data对象,当在一个组件中修改data时,其他重用的组件中的data会同时被修改;而使用返回对象的函数,由于每次返回的都是一个新对象(Object的实例),引用地址不同,则不会出现这个问题。

5.Vue响应式数据模式指的是什么?

        Vue框架的核心特点就是他的响应式数据。Vue的响应式数据系统也叫做MVVM架构。

        MVVM介绍

        MVVM分为三个部分:分别的M(Model,模型层),V(View,视图层),VM(ViewModel,V与M连接的桥梁,也可以看作控制器)。

        M:模型层,主要负责业务数据相关;

        V:视图层,负责视图相关;

        MV:V与M沟通的桥梁,负责监听M或者V的修改,是实现MVVM双向数据绑定的要点。

6.vue中v-if和v-show有什么区别?

         v-if和v-show看起来似乎差不多,当条件不成立时,其所对应的标签元素都不可见,但是这两个选项是有区别的:

        1、v-if在条件切换时,会对标签进行适当的创建和销毁,而v-show则仅在初始化时加载一次,因此v-if的开销相对来说会比v-show大。

        2、v-if是惰性的,只有当条件为真时才会真正渲染标签;如果初始条件不为真,则v-if不会去渲染标签。v-show则无论初始条件是否成立,都会渲染标签,它仅仅做的只是简单的CSS切换。

7.Vue2的属性更新限制和解决方案有哪些?

        当我们使用VM对象更新userInfo 中初始化就存在的属性时,视图会自动触发更新,而当我们对userInfo 内部不存在的属性设置值的时候视图不更新,这是因为Vue2.x 底层的数据响应式系统使用的是Object.defineProperty()来实现的,

        Vue 在初始化的时候会递归的将data选项中的属性绑定 setter 和 getter,通过两者来观察属性的行为,一旦初始化完成便不会再次执行本操作,所以更改已知属性的时候Vue实例是有感知并执行默认处理行为的,当我们操作对象内部不存在的属性时,由于其没有setter 和 getter ,Vue 将无法观察到这些属性的赋值和取值,视图更新操作也无法进行。

        解决方案

        1. $set(obj,key,value)---- 推荐

        针对Vue2.x 底层能力限制,后定义的属性由于没有在初始化时绑定监听,所以Vue 无法捕捉后定义属性的行为,为了弥补这种场景无法触发视图更新的问题,Vue 在实例上提供了一个$set函数,用来辅助更新视图

        2.&forceUpdate() --- 不推荐

        除了$set 之外,Vue 还提供了一个API 名为 &forceUpdate 来实现视图的更新,它同样挂载在Vue 的实例对象上,不同于 $set ,&forceUpdate不需要指定要更新的属性,他会在执行的时候强制Vue 实例重新执行一次渲染,这样视图层所有的内容都会重新执行一次更新,在这之前的如果有后定义的属性进行更改同样也会体现在视图上,这种方式只适用于特殊场景否则会让渲染性能开销增大。  VM.&forceUpdate()

8.computed和watch的区别

计算属性computed:

        支持缓存,只有依赖数据发生改变,才会重新进行计算

        不支持异步,当computed内有异步操作时无效,无法监听数据的变化        

        computed 属性值会默认走缓存,计算属性是基于它们的响应式依赖进行缓存的,也就是基于data中声明过或者父组件传递的props中的数据通过计算得到的值

        如果一个属性是由其他属性计算而来的,这个属性依赖其他属性,是一个多对一或者一对一,一般用computed

        如果computed属性属性值是函数,那么默认会走get方法;函数的返回值就是属性的属性值;在computed中的,属性都有一个get和一个set方法,当数据变化时,调用set方法。

侦听属性watch:

        不支持缓存,数据变,直接会触发相应的操作;

        watch支持异步;

        监听的函数接收两个参数,第一个参数是最新的值;第二个参数是输入之前的值;

        当一个属性发生变化时,需要执行对应的操作;一对多;

        监听数据必须是data中声明过或者父组件传递过来的props中的数据,当数据变化时,触发其他操作,函数有两个参数:

9.$nextTick是什么?

        vue实现响应式并不是数据发生变化后dom立即变化,而是按照一定的策略来进行dom更新。

        nextTick 是在下次 DOM 更新循环结束之后执行延迟回调,在修改数据之后使用nextTick,则可以在回调中获取更新后的 DOM

10.v-for key的作用

        当Vue用 v-for 正在更新已渲染过的元素列表是,它默认用“就地复用”策略。如果数据项的顺序被改变,Vue将不是移动DOM元素来匹配数据项的改变,而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素。

        为了给Vue一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一 key 属性。key属性的类型只能为 string或者number类型。

        key 的特殊属性主要用在Vue的虚拟DOM算法,在新旧nodes对比时辨识VNodes。如果不使用 key,Vue会使用一种最大限度减少动态元素并且尽可能的尝试修复/再利用相同类型元素的算法。使用key,它会基于key的变化重新排列元素顺序,并且会移除 key 不存在的元素。

11.封装 vue 组件的过程

        首先,组件可以提升整个项目的开发效率。能够把页面抽象成多个相对独立的模块,解决了我们传统项目开发:效率低、难维护、复用性等问题。

        然后,使用Vue.extend方法创建一个组件,然后使用Vue.component方法注册组件。子组件需要数据,可以在props中接受定义。而子组件修改好数据后,想把数据传递给父组件。可以采用emit方法。

12.组件传值

        父传子 (通过props传递)

//子组件 Child.vue
<template>
    <div id="container">
        {{msg}}
    </div>
</template>
<script>
export default {
  data() {
    return {};
  },
  props:{
    msg: String
  }
};
</script>
<style scoped>
#container{
    color: red;
    margin-top: 50px;
}
</style>
//父组件 
<template>
    <div id="container">
        <input type="text" v-model="text" @change="dataChange">
        <Child :msg="text"></Child>
    </div>
</template>
<script>
import Child from "@/components/Child";
export default {
  data() {
    return {
      text: "父组件的值"
    };
  },
  methods: {
    dataChange(data){
        this.msg = data
    }
  },
  components: {
    Child
  }
};
</script>

        子传父(this.$emit )

//子组件
<template>
    <div id="container">
        <input type="text" v-model="msg">
        <button @click="setData">传递到父组件</button>
    </div>
</template>
<script>
export default {
  data() {
    return {
      msg: "传递给父组件的值"
    };
  },
  methods: {
    setData() {
      this.$emit("getData", this.msg);
    }
  }
};
</script>
<style scoped>
#container {
  color: red;
  margin-top: 50px;
}
</style>
//父组件
<template>
    <div id="container">
        <Child @getData="getData"></Child>
        <p>{{msg}}</p>
    </div>
</template>
<script>
import Child from "@/components/Child";
export default {
  data() {
    return {
      msg: "父组件默认值"
    };
  },
  methods: {
    getData(data) {
      this.msg = data;
    }
  },
  components: {
    Child
  }
};
</script>

        兄弟组件传值

//bus.js
import Vue from 'vue';  
export default new Vue(); 
<template>
    <div>
        <h2>这是demo01组件</h2>
        <button @click="add"> 点击向dome02组件发送消息 </button>
    </div>
</template>

<script>

import Bus from '../utils/bus'

export default {
    methods:{
        // 点击按钮发送Bus消息
        add(){
            // 发送 myMsg 主题 的Bus消息
            Bus.$emit('myMsg', "你好啊,我叫XXX");
            // 打印一下日志
            console.log("dome01组件发送完消息:bus事件触发了")
        }
    }
}
</script>

        

<template>
  <div>
    <h2>这是dome02组件</h2>
    <h3>这个地方展示dome01组件的命令</h3>
    <!-- 把 dome01 发过来的消息渲染到下面 -->
    <span>{{msg}}</span>
  </div>
</template>

<script>

// 引入bus.js文件
import Bus from '../utils/bus'

export default {
  data() {
    return {
      msg: "XXX"
    };
  },
  // 在mounted钩子里面就开始定阅myMsg主题的消息
  mounted() {
      Bus.$on('myMsg', myMsg => {  
            console.log("dome02组件收到bus消息:",myMsg);  
            this.msg = myMsg
        });  
  }
};
</script>

13.class绑定?

        class 绑定一般为对象或者是数组

        class 绑定不会覆盖原始标签的class 

<div class="static" v-bind:class="{ active: isActive, 'text-danger': hasError }"></div>

<script>
    data(){
       return {
            data: {
              isActive: true,
              hasError: false
            }
       } 
    }
</script>



<div v-bind:class="[activeClass, errorClass]"></div>
<script>
    data(){
       return {
            data: {
              activeClass: 'active',
              errorClass: 'text-danger'
            }
       } 
    }
</script>

14.vue如何获取dom

        先给标签设置一个ref值,再通过this.$refs.domName获取,例如:

<div ref="app"></div>
const dom = this.$refs.app

15.v-on可以监听多个方法吗?

<input type="text" v-on="{ input:onInput,focus:onFocus,blur:onBlur, }">

16.slot插槽

        有时,我们封装了一个子组件之后,在父组件使用的时候,想添加一些dom元素,这个时候就可以使用slot插槽了,但是这些dom是否显示以及在哪里显示,则是看子组件中slot组件的位置了。

17.vue初始化页面闪动问题

        在vue初始化之前,看到类似于{{message}}的字样,虽然一般情况下这个时间很短暂,但是这个问题还是可以再优化的。在css中添加如下代码。

[v-cloak] {
    display: none;
}

18.在Vue对象中存在 createApp 方法(vue3.x)

const app = Vue.createApp({
    data(){
        return {}
    }
//渲染函数使用mount而非 $mount
}).mount('#app')
//输出app会发现它是一个 Proxy 对象,所以 Vue3 中的数据响应式系统显然时代理对象
console.log(app)

Vue3.x  主要更新的内容是重构依赖库的依赖关系,并且对 TS 的类型检测做个完整的支持,在原始基础上重构了数据响应式系统,增加了函数式编程的新开发策略,其他总体上更新更趋近 React 框架,现在的 Vue 与 React 很像,既可以使用对象编程的方式也可以使用函数编程的方式,两种可以并存。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值