首页 > 其他分享 >Vue3 学习笔记

Vue3 学习笔记

时间:2022-12-28 18:33:49浏览次数:66  
标签:vue default 笔记 学习 export Vue3 组件 model modelValue

有 Vue2 的基础,笔记只记载之前不熟悉的知识

一、Vue 基本知识

1. Vue3 基本指令

1.1 v-pre

v-pre用于跳过元素和它的子元素的编译过程,显示原始的Mustache标签:

跳过不需要编译的节点,加快编译的速度;

<template>
	<div>
        <div v-pre>{{message}}</div>
		<div>{{message}}</div>
    </div>
</template>
  • 使用v-pre,将不会渲染message对应的内容,直接显示文本{{message}}

1.2 v-bind 用法

1.2.1 动态绑定属性名称

<template>
    <div>
        <div :[name]="value"></div>
        <!-- 上述渲染后相当于下方 -->
        <div abc="cba"></div>
    </div>
</template>
<script>
export default {
  data(){
    return {
	  name: 'abc',
	  value: 'cba'
    }
  }
}
</script>

1.2.2 v-bind绑定一个对象

绑定对象后,会将对象解构,赋值到相应的标签上。

作用于组件时,可一次性将子组件需要的props进行传递

<template>
    <div v-bind="info">哈哈哈哈</div>
    <div :="info">哈哈哈哈</div>
    <!-- 上述渲染后相当于下方 -->
    <div name="fct" age="18" height="1.88">哈哈哈哈</div>
</template>

<script>
export default {
  data() {
    return {
      info: {
        name: "fct",
        age: 18,
        height: 1.88
      }
    }
  }
}
</script>

1.3 v-for 中 key 的作用

主要是Diff算法运用

  1. key 这个特殊的 attribute 主要作为 Vue 的 虚拟 DOM 算法 提示,在比较新旧节点列表时用于识别 vnode

  2. 在没有 key 的情况下,Vue 将使用一种最小化元素移动的算法,并尽可能地就地更新/复用相同类型的元素。

    源码如图:

    image-20220824182920503
  3. 如果传了 key,则将根据 key 的变化顺序来重新排列元素,并且将始终移除/销毁 key 已经不存在的元素。

    源码如图:

    image-20220824182821053

  4. 同一个父元素下的子元素必须具有唯一的 key。重复的 key 将会导致渲染异常。

2. 侦听器 watch

2.1 函数形式

ownName为需要侦听的变量的名称,如:要侦听 data 中 userName 的改变,对应的 侦听器为 userName(new, old){}

但是当需要侦听的为对象或其他引用类型的值时,使用函数形式的侦听器只能侦听引用类型数据的地址改变,而不能侦听内部值的改变。

{
      data() {
        return {
          userInfo: { userName: 'fct', age: "18" },
          ownName: 'changqing'
        }
      },
      watch: {
        // 侦听 ownName
        ownName(newValue, oldValue) {
          // 处理逻辑
        },
        // 侦听 userInfo 对象
        userInfo(newValue, oldValue) {
          // 处理逻辑
        },
        // 侦听 userInfo 对象中的 userName的改变
        "userInfo.userName": function(newValue, oldValue) {
          // 处理逻辑
        }
      }
}

2.2 对象形式

  • 相当于函数形式:
watch: {
  userInfo: {
	handler(newValue, oldValue){
	  // 处理逻辑
	}
  }
}
  • 深度侦听
watch: {
  userInfo: {
	handler(newValue, oldValue){
	  // 处理逻辑
	},
    deep: true,	  // 深度侦听,能侦听到对象内值的改变
  }
}
  • 立即执行(第一次渲染后就执行一次侦听器,而不是等到侦听的值改变再执行第一次)
watch: {
  userInfo: {
	handler(newValue, oldValue){
	  // 处理逻辑
	},
    deep: true,	  // 深度侦听,能侦听到对象内值的改变
    immediate: true  // 立即执行
  }
}

2.3 $watch API

使用$watchAPI来侦听:

  • 第一个参数:侦听的源
  • 第二个参数:侦听的回调函数callback
  • 第三个参数配置选项对象:如deep、immediate
created(){
    this.$watch('userInfo', (newValue, oldValue) => {
        // 处理逻辑
    },{
      deep: true,
      immediate: true
    })
}

3. 组件

3.1 全局注册组件

// app 是全局根实例,APPObj是配置对象
const app = Vue.createApp(appObj);

// 全局注册组件
app.component('my-component', {
    // 配置对象 
})

二、Vue 组件化

1. $attrs

前提:当父组件传递参数给子组件时:

<son-component class="title" title="标题1" content="内容"></son-component>

对应的子组件有相应的props来接受titlecontent属性,而class属性属于非props属性,Vue默认会将非props属性传递给子组件的根元素来继承。而Vue3中组件可以不用设置根元素来包裹,所以当在子组件不设置根元素的话,vue控制台输出警告。

那如何消除警告?

  • 给子组件设置根节点元素。
  • 使用 $attrs取捕获非props属性,并加以使用
<template>
  <h2 :class="$attrs.class">陈平安</h2>
  <p>{{ title }}</p>
  <p>{{ content }}</p>
</template>

<script>
export default {
  props: ['title', 'content'],
  mounted() {
    console.log(this.$attrs);
    // { class: 'title' }
  }
};
</script>

2.子组件与父组件通信

Vue3 和 Vue2有区别:

Vue3 需要提前注册声明自定义事件。可以使用数组对象形式

export default {
 emits: ['自定义事件名称'],
 // 对象语法允许我们对触发事件的参数进行验证:
 emits: {
     '自定义事件名称1':null,
     '自定义事件名称2': (plaload1,....) => {
 		// 通过返回值为 `true` 还是为 `false` 来判断
 		// 验证是否通过
		}
 }
}

父组件:

<template>
  <div class="hello">
    <h2>{{ count }}</h2>
    <!-- 在子组件上注册事件接收 -->
    <count-operator @add="add" @reduce="reduce"></count-operator>
  </div>
</template>
<script>
import CountOperator from './CountOperator.vue';
export default {
  components: { CountOperator },
  data() {
    return {
      count: 0
    };
  },
  methods: {
    add() {
      this.count++;
    },
    reduce() {
      this.count--;
    }
  }
};
</script>

子组件

<template>
  <div>
    <button @click="increment">+</button>
    <button @click="decrement">-</button>
  </div>
</template>

<script>
export default {
  // 声明自定义事件
  emits: ['add', 'reduce'],
  methods: {
    increment() {
      // 触发自定义add
      this.$emit('add');
    },
    decrement() {
      // 触发自定义reduce
      this.$emit('reduce');
    }
  }
};
</script>

3. 非父子组件通信

3.1 provide、inject

用于一些深度嵌套的组件,孙组件想要获取父组件的部分内容;

父组件有一个 provide 选项来提供数据;

孙组件有一个 inject 选项来开始使用这些数据;

3.1.1 组件结构

App.vue----->Home.vue----->HomeNavBar.vue

App.vue

export default {
    provide: {
        fct: '我是app组件'
    }
}

HomeNavBar.vue

export default {
  inject: ['fct']
}

3.1.2 provide 的函数形式

如果Provide中提供的一些数据是来自data,那么我们可能会想要通过this来获取。

直接在provide对象中使用 this 会报错,是因为 provide 中的 this 指向的不是vue实例,而是当前vue组件的script标签的根this,而根 this 为 undefined。

要正确使用this,则需要更改provide为函数形式:

<script>
export default {
    data() {
        return {
            names: ['a', 'b']
        }
    },
    provide() {
      return {
        fct: '我是app组件',
        length: this.names.length
      }
    }
}
</script>

3.1.3 处理响应式数据

在上例的基础上,当我们在names数组中新增数组项,而provide提供给孙组件的数据没有变化,不是响应式数据。

这时我们需要Vue提供的响应式函数来解决:computed函数

<script>
import { computed } from 'vue'
export default {
    data() {
        return {
            names: ['a', 'b']
        }
    },
    provide() {
      return {
        fct: '我是app组件',
        length: computed(() => this.names.length)
      }
    }
}
</script>

在孙组件中,取值需要通过.value取值。因为computed函数返回的是一个ref对象

3.2 全局事件总线 mitt库

Vue3从实例中移除了 $on、$off 和 $once 方法,所以我们如果希望继续使用全局事件总线,要通过第三方的库:

  • Vue3官方有推荐一些库,例如 mitttiny-emitter

  • 这里我们主要讲解一下mitt库的使用;

3.2.1 安装:

npm i mitt

3.2.2 使用:

  1. 封装工具eventbus.js
import mitt from 'mitt';

const emitter = mitt();

export default emitter;
  1. 触发事件

App.vue

<script>
import emitter from './utils/eventBus';
export default {
  methods: {
      clickEvent() {
        emitter.emit('fct', { name: 'fct' });
      }
  }
};
</script>
  1. 监听事件

其他组件

<script>
import emitter from './utils/eventBus';
export default {
  created() {
    // 监听单一事件
    emitter.on('fct', (data) => {
      console.log('fct-', data);
    });
    // 监听所有事件
    emitter.on('*', (type, data) => {
      console.log('* event', type, data);
    });
  },
};
</script>
  1. Mitt事件的取消
// 取消mitter中所有的监听
emitter.all.clear()

// 定义一个函数
function onFoo() {}
emitter.on('foo', onFoo);	// 监听
emitter.off('foo', onFoo);	// 取消监听

4. 插槽

插槽 Slots

5.动态组件

动态组件

动态组件有时会配合keep-alive使用,因为当使用 <component :is="..."> 来在多个组件间作切换时,被切换掉的组件会被卸载。通过 KeepAlive组件 强制被切换掉的组件仍然保持“存活”的状态。

6. 异步组件

异步组件

常用:

import { defineAsyncComponent } from 'vue'

const AsyncComp = defineAsyncComponent(() =>
  import('./components/MyComponent.vue')
)

搭配 Suspense 使用

异步组件可以搭配内置的 <Suspense> 组件一起使用, Suspense 中查看。

可进行设定异步组件加载失败后展示的组件

7. $refs、$parent、$root

$refs获取在template模板中设置有ref属性的标签或组件。

<!-- 模板引用 -->
<input ref="input">

<script>
  this.$refs.input.focus()
</script>

$parent获得当前组件的父组件的引用。

$root获得当前组件的所在的根组件。

Vue3已经移除$children属性

8.组件的v-model

标签:vue,default,笔记,学习,export,Vue3,组件,model,modelValue
From: https://www.cnblogs.com/fuct/p/17010984.html

相关文章

  • 【强化学习】数据科学,从计算到推理
    作为专栏的第零篇,编外篇,我们也是考虑到在正式开始强化学习专栏内容介绍之前,给大家树立一些基础知识和学习框架。大部分关注专栏的同学都是具有数据处理、数据分析、数据挖掘......
  • 【杂谈】如何从数据准备,模型设计与调优,训练到部署完成整个深度学习算法流程...
    文/编辑|言有三对于一个深度学习算法工程师来说,拥有丰富的项目经历当然是重要的,但是拥有完成整个从数据准备到模型上线的能力更加重要。这意味着可以独立承担项目,也是......
  • Java学习之if---elif语句
    publicclasselif1{publicstaticvoidmain(String[]args){inttestScore=50;chargrade;if(testScore>=90){grade='A';}elseif(testScore>=80){grade=......
  • Java学习之do---while语句
    do—while1/*do-while结构如下do{循环体}while(条件表达式)特点:无条件的执行一次循环体,再来判断条件表达式的值,至少循环一次*/importjava.util.*;publicclassdh1......
  • Java学习之do-while-if语句实操
    //filenamedwif.java//题目要求:求100以内的素数,并输出/*由题目可知最小素数为2,其余偶数均为非素数,对于一个奇数k,使用3√k的每个整数j去除k,如果找到一个整数j能除尽k,则k......
  • Java学习之数组
    数组1//filenamesu.java数组讲解/*使用java数组一般需要经过三个步骤:①声明数组②分配空间③创建数组元素并赋值前两个步骤语法如下:数据类型[]数组名;//声明一维......
  • Java学习之字符串
    /*字符串:字符串就是一系列字符的序列。在java语言中字符串是一对双引号("")括起来的字符序列声明:字符串常量与字符常量不同,字符常量是用单引号(’)括起来的字符,而字符串......
  • 2022.12.28笔记
    1、父组件调用子组件中的方法【函数】:(1)通过ref直接调用子组件的方法;参考链接:https://www.cnblogs.com/effortandluck/p/16355992.html 2、音频属性的认识;  ......
  • vue框架学习笔记
    #webpack使用 概念:webpack是前端项目工程化的具体解决方案主要功能:提供前端模块化开发支持、代码压缩混淆、处理浏览器端JavaScript的兼容性、性能优化等;//使用Node.j......
  • .NET Core 学习笔记
    .net是一个开发平台。包含.netframwork、netcore等,具体开发的语言主要是C#一、.netframwork和.netcore二者的区别①、.netframework是系统基本安装,相互影响(所......