vue自己复习用

92 阅读4分钟

一、 计算属性和方法的区别

  1. 计算属性:(computed)计算属性值会基于其响应式依赖被缓存,一个计算属性仅会在其响应式依赖更新时,才重新计算。
  2. 方法:(methods)方法调用宗师会在重渲染发生时再次执行函数

二、 侦听器

  1. watch:在watch中,函数名必须与侦听的数据对象保持一致
<template>
  <div class="count" @click="addCount">click me {{count}}</div>
</template>

<script>
// import Vue 不是必须的,需要手动指定 Vue 的版本时,可以解开注释
// import Vue from 'vue';

export default {
  data() {
    return {
      count: 0,
    };
  },
  methods: {
    addCount() {
      this.count += 1;
    },
  },
  watch:{
    count(newvalue,oldvalue){
      console.log(newvalue)
      console.log(oldvalue)
    }
  }
};
</script>

<style>
.count {
  color: red;
}
</style>
      

三、 v-model

    <input type="text" v-model.lazy="message" >
    <p>{{message}}</p>

默认情况下,v-model会在每次input事件后更新数据,你可以添加lazy修饰符改为每次change事件后更新。 v-model也提供了修饰符:lazy,number,trim

四、模板引用-获取DOM操作

$ref : 元素可以使用ref获取元素,this.$refs.name

五、组件组成

组件最大的优势就是可复用性

当使用构建步骤时,我们一般会将vue组件定义在一个单独的.vue文件中,这被叫做单文件组件(简称SFC)

**引用组件分为三个步骤:**

***//第一步:引入组件***

###### 1.在app.vue中,import mycompoent from  "./compoents/mycompoent.vue"

***//第二步:注入组件***

###### 2.在components中,写入mycompoent

**//第三步:显示组件**

###### 3.在template中,写入组件
<mycompoent />

组件的注册方式

一个vue组件在使用前需要先被“注册”,这样vue才能在渲染模板时找到其对应的实现,组件注册有俩种方式:全局注册和局部注册

全局注册:在main.js中注册组件

全局注册虽然方便,但是有以下几个问题:

1.全局注册,但并没有被使用的组件无法在生产打包时自动移出(也叫:tree-shaking),如果全局注册了一个组件,即使他没有被实际使用,他仍然会出现在打包后的JS文件中

2.全局注册在大型项目中使用项目的依赖关系变得不那么明确,在父组件中使用子组件时,不太容易定位子组件的实现。和使用过多的全局变量一样,这可能会影响应用长期的可维护性

局部注册需要使用 components 选项

import { createApp } from 'vue';
import App from './App.vue';
import router from './router';
import store from './store';
import { apiAxios, apiBaseUrl } from '../src/common/js/api';

const app = createApp(App);

// 将API基础URL和axios挂载到Vue实例上
app.config.globalProperties.$apiBaseUrl = apiBaseUrl;
app.config.globalProperties.$apiAxios = apiAxios;
// 全局注册组件
import SiteHeader from "./views/page/SiteHeader.vue";
app.component("SiteHeader", SiteHeader);

app.use(store).use(router).mount('#app');

组件的传递数据

props:['title'],

父传子props传递数据,只能从父级传到子级,不能反其道而行 props是只读的数据,不允许修改

    <p>{{ newval.name }}</p>
    <p>{{ newval.age }}</p>
    <ul>
        <li v-for="(item, index) of arr" :key="index">{{ item }}{{ index }}</li>
    </ul>
props: {
        // 类型检查
        arr: Array,
        // 必填项
        newval: {
            type: Object,
            required: true,
            // 默认值
            default: function () {
                return {
                    name: '张三', age: 18
                }
            }
        },
    },

$emit子传父

子页面:
data() {
        return {
            msg: 'hello'
        }
    },
    // 子组件向父组件传值,通过$emit()方法触发事件,并传递参数
    // 父组件通过v-on监听子组件传递的事件,并接收参数
    methods: {
        clickhandled() {
            this.$emit('someEvent', this.msg)
        }
    }
    
    
 父页面
<AppSiteChild :newval="sscode" :arr="arr" @someEvent="gethandle" />
  methods:{
        gethandle(data){
            console.log(data,'666');
        }
    }

组件之间相互动态实时获取数据 在子组件中,通过v-model创建一个动态变量,

<input type="text" v-model="seachData">

通过watch侦听器实时将最新的数据传递给父组件

data() {
    return {
      seachData:''
    };
  },
watch: {
    seachData(newValue,oldValue){
      // 将newValue发送给父组件
      this.$emit('seachData',newValue)
    }
  },
  emits: ['seachData'], // 声明组件可以发出的自定义事件

在父组件中接收自定义事件

<appSerch @seachData="getSeachData" />
getSeachData(data){
      this.message = data
      console.log(this.message);
    }

六、vue中插槽slot的使用 元素是一个插槽的出口(slot outlet),标识了父元素提供的插槽内容(slot content)将在哪里被渲染

image.png 1. 插槽内容可以访问到父组件的数据作用域,因为插槽内容本身是在父组件模板中定义的

image.png

2.具名插槽

.vue父级页面
    <appBase >
        <template v-slot:tempi>
          <h3>第一个插槽内容</h3>
        </template>
        <template v-slot:tempo>
          <h3>第二个插槽内容</h3>
        </template>
    </appBase>
    
.vue子级页面
    <template>
        <h3>顶部内容</h3>
        <slot name="tempi"></slot>
        <h5>中间内容</h5>
        <slot name="tempo"></slot>
    </template>

v-slot有对应简写的‘#’,因此<template v-slot:tempi> 也可以写成<template #tempi>,其意思就是将这部分模板片段传入子组件的tempi插槽中

image.png 3.插槽中传递数据(包含具名插槽传递数据)

 //子组件传值
<template>
    <h3>顶部内容</h3>
    <slot name="tempi" :msg="message"></slot>
    <h5>中间内容</h5>
    <slot name="tempo" :obj="demo"></slot>
</template>
<script>
export default {
    data () {
        return {
            message: '子组件的msg传给父元素,重新渲染到子组件的插槽中',
            demo:{
                name:'名字'
            }
        }
    }
}
</script>
    
//父组件接收并渲染给子组件
<appBase>
    <template #tempi="slotProps">
          <h3>第一个插槽内容</h3>
          {{ slotProps.msg }}
        </template>
        <template v-slot:tempo="slotPropsobj">
          <h3>第二个插槽内容</h3>
          {{ slotPropsobj.obj.name }}
     </template>
</appBase>

七、vue生命周期 基础生命周期

    /**
     * vue生命周期
     * 1.创建前/后 beforeCreate created
     * 2.挂载前/后 beforeMount mounted
     * 3.更新前/后 beforeUpdate updated
     * 4.销毁前/后 beforeDestroy destroyed
     * 5.keep-alive专属activated/deactivated
     * 6.错误处理钩子 errorCaptured
     * 7.路由专属 beforeRouteEnter(进入路由前) beforeRouteUpdate(更新路由前) beforeRouteLeave(离开路由前
     */

八、异步组件加载

因为vue在加载的时候会先加载完子组件之后,才把父组件给加载了,这样如果子组件加载时间过长,就会导致页面出现长时间的空白,使用异步组件就可以解决这个问题。

vue3提供了 defineAsyncComponent,它可以更简洁地定义异步组件。0只需要传递一个返回 import() 函数的参数,该函数会在需要时动态加载组件。这样可以减少手动编写异步加载的代码。 代码:

import { defineAsyncComponent, Suspense } from 'vue';
 
const AsyncComponent = defineAsyncComponent(() => 
    import('./components/AsyncComponent.vue')
 );
 
export default {
  // ...
  components: {
    AsyncComponent
  },
  // ...
  template: `
    <div>
      <Suspense>
        <AsyncComponent />
      </Suspense>
    </div>
  `
};

九、依赖注入,父级组件传值给深层子组件

provideinject,一个父组件相对于其所有的后代组件,会作为依赖提供者,任何后代的组件树,无论层级多深,都可以注入由父组件提供给整条链路的依赖

provideinject只能由上到下的传递