Vue基础知识

173 阅读3分钟

一、MVC和MVVM

 MVC

  •  Model, 数据模型
  •  View, 视图
  •  Controller, 控制器

MVVM

  • Model
  • View
  • ViewModel

MVC强调数据和视图分离,通过Controller协调页面的更新,MVVM的特点是数据绑定,通过抽象ModelView层,把数据和视图关联,从而实现数据和视图的同步。

Vue中是如何进行数据绑定的?

// Mustache
<template>
   <p>{{msg}}<p>
</template>

// v-model,双向绑定
<template>
   <input v-model="msg">
</template>

二、.vue文件的语法

vue3.0提倡使用composition api,相比2.0的选项式更加灵活,不需要再按照选项式的语法书写代码,可以按照业务逻辑等自由组织代码,直接书写js代码,更加符合前端开发者的习惯。vue3是兼容vue2的。

选项式API

export default {
  name: "HelloWorld",
  props: {
    msg: String,
  },
  data() {
    return {
      count: 0,
    };
  },
  computed: {},
  methods: {},
  components: {},
};

组合式API

<script setup>
  import { ref, reactive } from "vue";
  const list = reactive([]); // 响应式数据 
  const add = () => {
    list.push(Date.now());
  };
</script>

三、Vue 模板的常见指令

  • v-bind: value, 缩写:value
  • v-model
  • v-on: click, 缩写: @click
  • v-show,通过display属性控制元素的显示和隐藏
  • v-if,v-else-if,v-else
  • v-for
  • v-once, 组件和元素只渲染一次,后续数据变化不会重新渲染
  • v-text
  • v-pre, 跳过{{}}的编译,显示原始数据
  • v-clock, 显示元素之前会先显示v-clock,直到元素渲染完成才会显示元素

四、生命周期

  • beforeCreate, 开始创建组件实例,注册事件等,此时实例还没有初始完成,无法访问实例上的数据
  • created, 实例初始完成,可以访问vue实例
  • beforeMounted, 模板编译完成,生成虚拟DOM, 真实DOM还没有渲染
  • mounted, DOM挂载完毕,可以操作DOM
  • beforeUpdate, 响应式数据发生变化之后,已生成对应的虚拟DOM,还没有更新真实DOM
  • updated, 响应式数据变化之后,DOM已经更新
  • beforeDestory, 组件销毁之前调用,通常用来清除effect,如定时器、事件监听的清除。
  • destoryed, vue实例销毁,与vue相关的事件监听等解绑 在vue3中beforeDestore和destoryed对应beforeUnmounted和unmounted

选项式api的生命周期

<script>
export default {
    name: "Option",
    beforeCreate() { },
    created() { },
    beforeMount() { },
    mounted() { },
    beforeUpdate() { },
    updated() { },
    beforeUnmount() { },
    unmounted() { },
}
</script>

组合式api的生命周期

组合式API使用setup替代了create阶段,setup在beforeCreate和created之间调用,此时实例没有初始化完成,不能访问组件实例。

 <script setup>
import {
    onBeforeMount,
    onMounted,
    onBeforeUpdate,
    onUpdated,
    onBeforeUnmount,
    onUnmounted
} from "vue";
onBeforeMount(() => { });
onMounted(() => { });
onBeforeUpdate(() => { });
onUpdated(() => { });
onBeforeUnmount(() => { });
onUnmounted(() => { });
</script>

父子组件的生命周期

  1. 父子组件加载过程: 父组件beforeate、父组件created、父组件beforemount、子组件beforecreate、子组件created、子组件beforemount、子组件mounted、父组件mounted。

  2. 父子组件更新过程: 父组件beforeupdate、子组件beforeate、子组件updated、父组件updated。

原因:所有的子组件完成之后,父组件才算完成,所以父组件的mounted必须要在所有子组件mounted之后调用。之所以在父组件beforemounted之后就开始子组件的解析,是因为这一步之后已经得到了父组件的虚拟dom,可以向下深度遍历子组件了。

五、组件通信

 1. 父组件通过props向子组件通信

// 子组件
<template>
   <span>{{ props.count }}</span>
</template>

<script setup>
import { defineProps } from "vue";
const props = defineProps({
   "count": {
       type: Number,
       required: true,
       default: 0,
   }
})
</script>

// 父组件
<template>
 <UserCard :count="count" />
</template>

<script setup>
import { ref } from "vue";
import UserCard from "./components/UserCard";
const count = ref(0);
</script>
  1. 子组件通过$emit与父组件通信
// 父组件
<template>
 <UserCard @message="message" />
</template>

<script setup>
import UserCard from "./components/UserCard";
const message = (msg) => {
 alert(msg);
};
</script>

// 子组件
<template>
   <button @click="sendMessage">发送当前时间给父组件</button>
</template>

<script setup>
import { defineEmits } from "vue";
const emit = defineEmits(["message"]);
const sendMessage = () => {
   emit("message", Date.now());
}
</script>

 其它:  事件总线、inject/provider、vuex、pinia、eventemitter。  vue3不再提倡使用事件总线,而是提倡使用eventemitter这样的三方库。

六、QA

6.1 为什么vue2中新增的对象属性不能触发响应式的页面更新,而vue3中可以?

vue2对使用definePropert对属性进行监听,只能监听到已有属性的修改。而vue3使用的ES6的proxy可以监听到对象的任何操作。

6.2 为什么data是一个函数不是一个对象?

为了做数据隔离,每个组件实例有单独的数据。