Vue3你需要知道的组件化知识点

组件命名

官方建议我们使用大驼峰命名法注册组件,因为:

  1. 驼峰命名是合法的JS标识符,导入、注册组件会更简单,IDE会自动完成。
  2. <Pascalcase />使Vue组件比原生HTML元素更醒目。

例如,使用组件Pascalcase.vue

<script setup>
import Pascalcase from './Pascalcase.vue'
</script>

<template>
  <h1>使用驼峰命名组件!</h1>
  <Pascalcase />
</template>

属性定义

使用更细节的方式定义属性:

<script setup>
// 不推荐
// const props = defineProps(['foo'])

// 推荐
const props = defineProps({
  foo: {
    type: String,
    default: ''
  }
})
console.log(props.foo)
</script>

事件定义

自定义事件的名称会被自动做转换,我们通常使用驼峰做事件名,但监听时需要转换为肉串方式。

例如:

<!-- MyComponent -->
<button @click="$emit('someEvent')">click me</button>
<MyComponent @some-event="callback" />

script setup中定义

<script setup lang="ts">
const emit = defineEmits(['someEvent'])
emit('someEvent')
</script>

透传特性

在vue3中,那些没有明确在组件props和emits中声明的特性或事件监听器称为透传特性,以前叫非属性特性。比如class,styleid特性。当组件只有单根时,透传特性自动被添加到根元素上作为其特性。例如:

<MyButton class="large" />
<button class="large">click me</button>

如果不想自动继承特性,可以使用inheritAttrs: false禁止

<script>
// use normal <script> to declare options
export default {
  inheritAttrs: false
}
</script>

<script setup>
// ...setup logic
</script>

Vue3中插槽的变化是移除scopeSlots,只需要访问slots对象,且包括default插槽都是函数形式。

访问透传特性

<script setup>
import { useAttrs } from 'vue'

const attrs = useAttrs()
</script>

插槽

如果要传递模板内容给子组件,我们使用插槽。

<script setup>
import { useSlots } from 'vue'

const slots = useSlots()
const defaultContent = slots.default()
</script>

提供/注入 provide/inject

隔代传参时,使用provide/inject这组API。

<script setup>
import { provide } from 'vue'
// 祖代提供数据
provide(/* key */ 'message', /* value */ 'hello!')
</script>
import { inject } from 'vue'

export default {
  setup() {
    // 后代注入数据
    inject(/* key */ 'message', /* value */ 'hello!')
  }
}

Composables

利用Composition API封装的可重用状态逻辑称为composables

约定composables函数命名时加上use前缀,例如:

// mouse.js
import { ref, onMounted, onUnmounted } from 'vue'

// by convention, composable function names start with "use"
export function useMouse() {
  // state encapsulated and managed by the composable
  const x = ref(0)
  const y = ref(0)

  // a composable can update its managed state over time.
  function update(event) {
    x.value = event.pageX
    y.value = event.pageY
  }

  // a composable can also hook into its owner component's
  // lifecycle to setup and teardown side effects.
  onMounted(() => window.addEventListener('mousemove', update))
  onUnmounted(() => window.removeEventListener('mousemove', update))

  // expose managed state as return value
  return { x, y }
}

传入refs参数代替原始值

import { unref } from 'vue'

function useFeature(maybeRef) {
  // if maybeRef is indeed a ref, its .value will be returned
  // otherwise, maybeRef is returned as-is
  const value = unref(maybeRef)
}

总是返回包含refs的对象

// x and y are refs
const { x, y } = useMouse()

组件通信

组件通信常⽤⽅式,vue3中有很多变化:

  • props:父子通信,传入一个属性
{
  props: { msg: String }
}

除了props选项,vue3.2还出了script setup的新写法

const props = defineProps({
  model: { type: Object, required: true }
});
props.model
  • $emit:

现在只剩下派发事件的emit方法

this.$emit('add', good)

vue3.2还出了script setup的新写法

const emit = defineEmits(['update:model-value', 'validate'])
const emit = defineEmits<{
  (e: "update:model-value", value: string): void;
  (e: "validate"): void;
}>();
emit("update:model-value", inp.value);

o n , on, ononce, $off被移除了!

上述3个⽅法被认为不应该由vue提供,因此被移除了,可以使⽤其他库实现等效功能。

import mitt from 'mitt'

const emitter = mitt()

// 发送事件
emitter.emit('foo', 'foooooooo')

// 监听事件
emitter.on('foo', msg => console.log(msg))
  • event bus

vue2时代我们常常使用一个vue实例来做事件总线,现在不行了:

所以我们就使用上面的mitt方案来代替就好了!

// vue2时代,现在因为没有$on不行了
Vue.prototype.$bus = new Vue()

// 组件里面
this.$bus.$emit('xxx')

// 其他组件
this.$bus.$on('xxx', () => {})
  • vuex/pinia

vuex 4.x中的composition api写法:

const store = useStore()
store.commit('add')
store.dispatch('add')
  • parent/root

兄弟组件之间通信可通过共同祖辈搭桥。

// brother1
this.$parent.$on('foo', handle)
// brother2
this.$parent.$emit('foo')
  • $children

vue3中移除了该选项,官方建议我们访问子组件时使用$refs

  • $refs

获取指定元素或组件

// parent
<HelloWorld ref="hw"/>
mounted() {
  this.$refs.hw.xx = 'xxx'
}
  • provide/inject

能够实现祖先和后代之间传值

在composition中有对应的api

// ancestor
provide() {
  return {foo: 'foo'} 
}
// descendant
inject: ['foo']
import {provide, inject} from vue
// 提供数据
provide(key, value)
// 注入数据
inject(key)
  • $attrs:

a t t r s 会包含那些没有声明的组件特性, v u e 3 中移除了 attrs会包含那些没有声明的组件特性,vue3中移除了 attrs会包含那些没有声明的组件特性,vue3中移除了listeners,只剩下$attrs:

// child:并未在props中声明foo
<p>{{$attrs.foo}}</p>
// parent
<HelloWorld foo="foo"/>

通过 v-bind=“$attrs” 透传到内部组件——在创建⾼级别的组件时⾮常有⽤:

// 给Grandson隔代传值,parent.vue
<Child2 msg="lalala" @some-event="onSomeEvent"></Child2>

// Child做展开
<Grandson v-bind="$attrs"></Grandson>

// Grandson使⽤
<div @click="$emit('some-event', 'msg from grandson')">
 {{msg}}
</div>

插槽

插槽语法是Vue 实现的内容分发 API,⽤于复合组件开发。该技术在通⽤组件库开发中有⼤量应⽤。

匿名插槽

slot称为匿名插槽,作为占位符存在,将来被替换为传入内容。

// comp1
<div> 
  <slot></slot>
</div>
// parent
<comp>hello</comp>
具名插槽

slot加上name就称为具名插槽,可以将内容分发到⼦组件指定位置

// comp2
<div> <slot></slot> <slot name="content"></slot>
</div>
// parent
<Comp2>
<!-- 默认插槽⽤default做参数 -->
<template v-slot:default>具名插槽</template>
<!-- 具名插槽⽤插槽名做参数 -->
<template v-slot:content>内容...</template>
</Comp2>
作⽤域插槽

分发内容要⽤到⼦组件中的数据

// comp3
<div> <slot :foo="foo"></slot>
</div>
// parent
<Comp3>
<!-- 把v-slot的值指定为作⽤域上下⽂对象 -->
<template v-slot:default="slotProps">
来⾃⼦组件数据:{{slotProps.foo}}
</template>
</Comp3>

Vue3中组件相关API变化总结

global-api改为实例⽅法

全局静态⽅法引发⼀些问题,vue3将global-api改为app实例⽅法

// vue2中
// Vue.component()

// vue3中
const app = createApp({})
 .component('comp', {template: '<div>i am comp</div>'})
 .mount('#app')
移除.sync,统⼀为v-model

以前.sync和v-model功能有重叠,容易混淆,vue3做了统⼀。

<div id="app"> 
  <comp v-model="data"></comp>
  <comp :model-value="data" @update:model-value="onxxx"></comp>
  <comp :data="data" @update:data="onxxx"></comp>
</div>
app.component('comp', {
  props: {
    modelValue
  },
  template: `
    <div @click="$emit('update:model-value', 'new value')">
      i am comp, {{modelValue}}
    </div>
  `,
  props: ['modelValue'],
})
渲染函数api修改

不再传⼊h函数,需要我们⼿动导⼊;拍平的props结构。scopedSlots删掉了,统⼀到slots

import {h} from 'vue'

export default {
  render() {
    const emit = this.$emit
    const onclick = this.onclick
    return h('div', [
      h('div', { onClick(){ emit('update:modelValue', 'new value')} }, 
        `i am comp, ${this.modelValue}`),
       h('button', { onClick(){ onclick() }}, 'buy it!')
    ])
  },
}
组件emits选项

该选项⽤于标注⾃定义事件及其校验等。

createApp({}).component("comp", {
  template: `...`,
  // emits标明组件对外事件
  emits: ['buy', '...']
  // 还能对事件进行校验
  emits: {
    'update:modelValue': null, // 不做校验
    buy(p) { // 校验buy事件
      if (p === 'nothing') {
        console.warn('参数⾮法');
        return false
      } else {
        return true
      }
    }
  },
})
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 作为一个AI语言模型,我很高兴能够回答您的问题。关于入门Vue需要了解的知识点,以下是一些基本的知识点: 1. HTML、CSS和JavaScript基础知识 2. Vue.js框架的基本概念和特点 3. Vue组件的概念和使用 4. Vue指令的概念和使用 5. Vue模板语法和表达式 6. Vue路由和路由参数的使用 7. Vue状态管理的基础知识和使用 8. Vue生命周期钩子函数的使用 9. Vue开发调试工具的使用 以上是入门Vue需要掌握的基本知识点。当然,还有很多其他的知识点需要不断学习和掌握,祝您在学习Vue的过程中取得成功! ### 回答2: 入门Vue需要知道以下知识点: 1. HTML和CSS基础:Vue是一个用于构建用户界面的JavaScript框架,了解HTML和CSS将有助于理解Vue的基本概念和使用方式。 2. JavaScript基础:Vue是基于JavaScript的框架,对JavaScript的基本语法和概念要有一定的了解,包括变量、函数、循环、条件判断等。 3. Vue的基本概念:了解Vue的核心概念,如组件、指令、生命周期、数据绑定等。掌握Vue的基本语法和使用方式,如Vue实例、模板语法、计算属性等。 4. Vue组件开发:学习组件开发的思想和方式,将应用拆分成多个组件,每个组件负责一部分功能,通过组件之间的通信来构建整个应用。 5. Vue的路由管理:学习使用Vue Router来管理页面的路由,实现单页应用(SPA)的效果,了解路由的基本概念和使用方式。 6. Vue的状态管理:了解Vuex来管理应用的状态,实现数据的共享和响应式更新,学习使用store、state、mutations、getters等概念。 7. Vue的异步请求:学习使用Vue提供的插件或库来进行异步请求,如axios、vue-resource等,掌握发送请求、处理响应的基本方式。 8. Vue的打包和部署:了解如何使用构建工具(如webpack)来打包Vue应用,将代码部署到生产环境,学习如何处理资源文件、优代码等。 9. Vue的周边生态:了解Vue的周边生态系统,掌握常用的插件和库,如Vue Router、Vuex、Element UI等,学习如何使用它们来扩展Vue的功能。 10. 实际项目开发经验:通过练习和实际项目开发,不断积累经验和问题解决能力,深入理解Vue的使用和应用场景,提升自己的技能水平。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

林多多@

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值