首页 > 其他分享 >Vue3.3 的新功能的一些体验

Vue3.3 的新功能的一些体验

时间:2023-05-16 17:46:19浏览次数:57  
标签:功能 vue const name 体验 value Vue3.3 props 组件

Vue3 在大版本 3.3 里面推出来了一些新功能(主要是语法糖),网上有各种文章,但是看起来似乎是一样的。
我觉得吧,有新特性了,不能光看,还要动手尝试一下。

DefineOptions 宏定义

先来一个简单的,以前我们有时候想设个name,有时候不想让组件自动继承属性,这时候需要单独设置一个script进行设置,现在简化了操作,直接使用 defineOptions 即可。

<script setup lang="ts">
defineOptions({
  name: 'Foo',
  inheritAttrs: false,
  // ... 更多自定义属性
})
</script>

defineModel

defineModel 这是一个语法糖,目前需要手动开启,否则无法识别。

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue({
    script: {
      defineModel: true,
      propsDestructure: true // 解构 props
    }
  })],
})

有人嫌弃 组件内部 v-model 的实现方式有点繁琐,所以就做了这个语法糖给大家减少代码量,我们也来体验一下。

const modelValue = defineModel()
console.log(modelValue)

我们看看 的结构

{__v_isRef: true}
    value: (...)
    __v_isRef: true
    get value: ƒ value()
    set value: ƒ value(value)

只是一个普通的对象看不出来有什么名堂,我们来看一下内部的实现方式:

function useModel(props, name, options) {
  const i = getCurrentInstance();
  if (process.env.NODE_ENV !== "production" && !i) {
    warn(`useModel() called without active instance.`);
    return ref();
  }
  if (process.env.NODE_ENV !== "production" && !i.propsOptions[0][name]) {
    warn(`useModel() called with prop "${name}" which is not declared.`);
    return ref();
  }
  if (options && options.local) {
    const proxy = ref(props[name]);
    watch(
      () => props[name], // 监听外部组件的值的变化
      (v) => proxy.value = v // 赋值给内部属性
    );
    watch(proxy, (value) => { // 监听内部属性的变化
      if (value !== props[name]) {
        i.emit(`update:${name}`, value); // 提交给外部组件
      }
    });
    return proxy;
  } else {
    return {
      __v_isRef: true,
      get value() {
        return props[name]; // 返回外部组件的值
      },
      set value(value) {
        i.emit(`update:${name}`, value); // 内部组件赋值,提交给外部组件
      }
    };
  }
}

前面各种判断,然后option模式下返回一个 ref,setup 模式下返回一个对象。取值的时候,返回 props[name]

Props 的响应式解构

我个人是不喜欢解构的,直接使用不香吗?其实vue表面上不让我们用,其实内部悄悄的在用,比如上面那个useModel 不就是嘛。

这个也是实验性的,想要体验需要手动设置,设置方法在上面。

const { name } = defineProps<{ name: string }>()
watchEffect(() => {
  console.log(`name is: ${name}`)
})

const aa = computed(() => { return name + '响应'})

看打印效果,只是普通的string,那么是如何实现响应的呢?还得看看“编译后”的代码是什么样子的。

  setup(__props, { expose: __expose }) {
    __expose();
    watchEffect(() => {
      console.log(`name is: ${__props.name}`);
    });
    const aa = computed(() => {
      return __props.name + "\u54CD\u5E94";
    });

编译后会生成一个 setup 函数,props 通过 参数 __props 传入,需要监听的地方,会把 name 变成 __props.name,这样就实现响应性了。也就是说,还是一个语法糖。

从外部文件引入 props 的定义( 单文件组件类型导入)

从外部引入 props 的定义,这个功能非常实用,以前封装UI库,想实现共享属性定义的时候卡了好久,使用OptionAPI,还是使用CompositionAPI,都各有优缺点,最后只好折中一下。

现在支持外部导入那就方便多了。

比如我们先在一个ts文件里面定义一个接口:

export interface IFromItemProps {
  /**
   * 表单的 model
   */
  model: {[key: string]: any},
  /**
   * 对应的字段名称
   */
  colName: string,
  /**
   * 控件的备选项,单选、多选、等控件需要
   */
  optionList?: Array<{
    label: string,
    value: string | number | boolean,
    disabled: boolean
  }>,
  /**
   * 是否显示可清空的按钮,默认显示
   */
  clearable?: boolean,
  /**
   * 浮动的提示信息,部分控件支持
   */
  title?: string,
  /**
   * 组件尺寸
   */
  size?: string
}

text

然后我们可以 基于 el-input 做一个自己的 nf-text ,然后引入接口定义,还可以在 nf-list 等里面引入,这比以前使用的方式正规多了,也能更好的支持TS。

<template>
  <el-input
    v-model="model[colName]"
    v-bind="$attrs"
    :id="'c' + colName"
    :name="'c' + colName"
    :size="size"
    :clearable="clearable"
  >
  </el-input>
</template>
<script setup lang="ts">
  // 引入 类型定义
  import type { IFromItemProps } from './base'
  // 定义 props
  const props = defineProps<IFromItemProps>()
  console.log('props - text', props)
  
</script>

看看效果

  Proxy {model: Proxy, colName: 'name', title: '姓名', size: 'small', clearable: true, …}
    [[Handler]]: Object
      [[Target]]: Proxy
        [[Handler]]: Object
          [[Target]]: Object
            clearable: true
            colName: "name"
            model: Proxy {name: 'jyk', city: Array(0), time: ''}
            optionList: undefined
            size: "small"
            title: "姓名"
            [[Prototype]]: Object
          [[IsRevoked]]: false
      [[IsRevoked]]: false

list

你可能会觉得,这封装的有意义吗?只看一个确实没啥意思,不过表单里面不是只有文本框这一种,还需要其他类型,定义接口就是为了统一风格。

我们再封装一个select看看:

<template>
  <el-select
    v-model="model[colName]"
    v-bind="$attrs"
    :id="'c' + colName"
    :name="'c' + colName"
    :size="size"
    :clearable="clearable"
    :multiple="multiple"
  >
    <el-option
      v-for="item in optionList"
      :key="'select' + item.value"
      :label="item.label"
      :value="item.value"
      :disabled="item.disabled"
    >
    </el-option>
  </el-select>
</template>

这里处理了一下 el-option ,使用 v-for 创建 el-option。

<script setup lang="ts">
  import type { IFromItemProps } from './base'

  const props = defineProps<IFromItemProps & {multiple?: boolean}>()
  console.log('props - list', props)
 
</script>

最后看一下使用情况

import nfText from './form/text.vue'
import nfList from './form/list.vue'
import nfDatetime from './form/datetime.vue'

const model = reactive({
  name: 'jyk',
  city: '',
  time: ''
})

const myText = {
  colName: 'name'
}

const myList = {
  colName: 'city',
  multiple: true,
  optionList: [
    {
      label: '北京',
      value: 1
    },
    {
      label: '上海',
      value: 2
    }
  ]
}

  <nf-text :model="model" v-bind="myText"></nf-text>
  <nf-list :model="model" v-bind="myList"></nf-list>
  ...

封装之后,我们不用关心组件是否需要子组件(比如el-select需要设置 el-option),都是<nf-text v-bind="myText"></nf-text>这种简单粗暴的方式,而组件需要的属性,我们可以做成json的形式,这样更方便。

另外大家不要忘记 vue 提供的动态组件(component :is="xxx"),这样我们用 v-for 就可以把一个表单里的所有子组件都给遍历出来,不用一个一个的写了。

小结

目前只对这几个新特性感兴趣体验了一下,其他的还没来得及。还有一个 props 设置默认值的问题,可以使用 withDefaults:

  const props = withDefaults(defineProps< IFromItemProps >(), {
    clearable: true
  })

只是好像 默认值的部分需要直接写进去。这个,等待以后更新吧,估计以后都会支持外部导入的方式吧。

参考文档

  • Announcing Vue 3.3 | The Vue Point
  • Vue 3.3 主要新特性详解 - 三咲智子 Kevin Deng

参考资料

[1] Generic component enhancements - Discussion #436: https://github.com/vuejs/rfcs/discussions/436

[2] unplugin-vue-define-options - npm: https://www.npmjs.com/package/unplugin-vue-define-options

[3] Announcing Vue 3.3 | The Vue Point: https://blog.vuejs.org/posts/vue-3-3

[4] Vue 3.3 主要新特性详解 - 三咲智子 Kevin Deng: https://xlog.sxzz.moe/vue-3-3

Vue3.3 发布:十分钟速递

Vue3.3 正式发布!

官方帮助文档

标签:功能,vue,const,name,体验,value,Vue3.3,props,组件
From: https://www.cnblogs.com/jyk/p/17406348.html

相关文章

  • ASEMI代理亚德诺ADM3251EARWZ-REEL芯片的功能及应用介绍
    编辑-Z本文介绍了ADM3251EARWZ-REEL芯片的基本参数和优势,并从电气隔离、EMC滤波、数据速率和应用场景四个方面对其特点和应用进行详细阐述。最后总结了ADM3251EARWZ-REEL芯片的实际应用情况和前景。 一、电气隔离的作用ADM3251EARWZ-REEL芯片是一种带有电气隔离的RS-232收发......
  • 火山引擎DataLeap数据调度实例的 DAG 优化方案 (二):功能设计
    针对上面存在的问题以及对需求的分析,我们可以进行如下的功能实现与设计:首先是渲染方案的替换,将svg的渲染方案替换成canvas渲染,通过减少页面中DOM的数量,提高前端渲染性能。其次是不同场景的功能设计,通过上面的需求分析,火山引擎DataLeap研发人员设计了不同的功能模式以满足......
  • 知行之桥EDI系统2023版功能介绍——概览页面
    登录知行之桥EDI系统2023版,即可看到概览页面。默认情况下,会显示过去7天的各项指标。用户可以在页面右上角:显示过去的数据 下拉列表中手动选择需要的时间段,如:24小时、3天、7天等。关键指标的自定义配置概览页面具有灵活的可选性,用户可以对关键指标部分进行自定义的搭配。可以从......
  • 原型设计工具对比及使用体验
    一、原型设计工具对比随着软件市场的不断扩大,用户对于软件的要求也越来越高,除了功能实用之外,软件的美观度、简洁度也成为了评估软件好坏的重要因素。在原型设计中,设计工具的美观、简洁度同样至关重要。目前,市场上有许多常见的原型设计工具,其中一些具备良好的设计界面,如墨刀原型......
  • 企业培训APP开发功能
    企业培训APP开发可以通过以下步骤实现:确定需求:明确培训APP的目的和功能,确定开发的规模和项目进度。选择开发平台:选择适合企业需求的开发平台,比如AppStore或者小程序平台,或者使用第三方移动端开发服务。开发APP:根据需求分析,进行APP的界面设计、功能开发、数据库设计等工......
  • FX5U FX40SSC 程序 FX5U FX 40SSC运动控制模块程序块 自己整合的针对FX 40SSC模块的
    FX5UFX40SSC程序FX5UFX40SSC运动控制模块程序块自己整合的针对FX40SSC模块的功能块,支持点动故障码状态码相对定位绝对定位直接1指定轴号就可以控制对应的轴可以大幅缩短程序开发时间,减少BUG出现机率。ID:8715641034653828......
  • 量产直流无刷电机驱动器资料 功能支持模式:有霍尔和无
    量产直流无刷电机驱动器资料功能支持模式:有霍尔和无霍尔两种;速度信号:0-5V的模拟量(0-100%的PWM)或modbus两种选择方式;使能和正反转信号:开关量或者modbus两种选择方式;速度反馈信号:可变频率的脉冲,每换相一次会出现一个跳变沿,或者使用modbus读取;电机供电电压和电流:通过modbus读取;该模......
  • 开发板三菱FX3U底层源码,总体功能和指令可能支持在RUN中下载程序,支持注释的写入和读取,
    开发板三菱FX3U底层源码,总体功能和指令可能支持在RUN中下载程序,支持注释的写入和读取,支持脉冲输出与定位指令(包括PLSY/PWM/PLSR/PLSV/DRVI/DRVA等指令)。对于FX3U,支持波特率9600/19200/38400/57600/115200自适应ID:58199670048570922......
  • 用JFreeChart增强JSP报表的用户体验(2)
     三. 饼图在WebRoot目录下建立名为pie的子目录,用来存放本教程中饼图的实例jsp页面。下面让我们来看一个简单的三维饼图。首先在pie目录下建立一个名为sample1.jsp的页面。在JFreeChart中,与饼图绘制密切相关的类如下:1) PiePlot饼图绘制类,可以用来设置饼图的相关属性。例......
  • Nacos框架功能与原理概览
    Nacos的设计有两点很值得参考;首先是注册中心模块,服务状态动态感知是基于HTTP短链接+UDB通信来实现,其实正确来说,应该是基于UDP通信实现客户端与服务端的服务实例列表数据同步,利用http定时任务来做补偿。其次配置中心模块的配置信息动态监听基于HTTP长轮询实现,最大限度的保证了实时......