初识vue3.0

新特性(区别)

1、片段:vue3.0中template支持多个根标签;(vue2只能单个)

2、组合式API--setup:(2.0的称为选项式API)
(1)在组件创建前执行,且只能接受(访问)props和context的函数;
(2)返回的内容将暴露给组件其他部分(计算属性、方法、生命周期等)以及组件模板;
(3)在 setup 中注册生命周期钩子的方法。这要归功于从 Vue 导出的几个新函数。组合式 API 上的生命周期钩子与选项式 API 的名称相同,但前缀为 on:即 mounted 会看起来像 onMounted

3、ref函数:
(1)作用:使任何响应式变量在任何地方起作用;(通过对象的引用地址来实现响应)
(2)接受参数,并将其包裹在一个带有 value property 的对象中返回;【eg:const test = ref(1) // test.value === 1】
(3)toRefs函数:创建对props(猜测可能对对象某个属性也行)的某个属性响应式引用;

4、watch响应式更改
** 接收三个参数:

  • 一个我们想要侦听的响应式引用或 getter 函数;
  • 一个回调;
  • 可选的配置选项;
import { ref, watch } from 'vue'

const counter = ref(0)
watch(counter, (newValue, oldValue) => {
  console.log('The new counter value is: ' + counter.value)
})

5、独立的computed属性

import { ref, computed } from 'vue'

const counter = ref(0)
const twiceTheCounter = computed(() => counter.value * 2)

counter.value++
console.log(counter.value) // 1
console.log(twiceTheCounter.value) // 2   --注意这边是`.value`

6、Teleport(传送)
(1)作用:可指定包裹的html结构渲染在哪个DOM下;
(2)代码展示:

    <button @click="modalOpen = true">
      Open full screen modal! (With teleport!)
    </button>

    <teleport to="body"> // 渲染到body下面
      <div v-if="modalOpen" class="modal">
        <div>
          I'm a teleported modal! 
          (My parent is "body")
          <button @click="modalOpen = false">
            Close
          </button>
        </div>
      </div>
    </teleport>

(3)与 Vue components 一起使用
如果 <teleport> 包含 Vue 组件,则它仍将是 <teleport> 父组件的逻辑子组件:

const app = Vue.createApp({
  template: `
    <h1>Root instance</h1>
    <parent-component />
  `
})

app.component('parent-component', {
  template: `
    <h2>This is a parent component</h2>
    <teleport to="#endofbody">
      <child-component name="John" />
    </teleport>
  `
})

app.component('child-component', {
  props: ['name'],
  template: `
    <div>Hello, {{ name }}</div>
  `
})

在这种情况下,即使在不同的地方渲染 child-component,它仍将是 parent-component 的子级,并将从中接收 name prop。

7、定义触发事件:可直接在组件通过emits选项定义
(1)emits: ['inFocus', 'subimit'] 或对象也行,可像props一样校验传递参数;
(2)代码示例

app.component('custom-form', {
  emits: {
    // 没有验证
    click: null,

    // 验证submit 事件
    submit: ({ email, password }) => {
      if (email && password) {
        return true
      } else {
        console.warn('Invalid submit event payload!')
        return false
      }
    }
  },
  methods: {
    submitForm() {
      this.$emit('submit', { email, password })
    }
  }
})

8、多个v-model绑定

<user-name
  v-model:first-name="firstName"
  v-model:last-name="lastName"
></user-name>
app.component('user-name', {
  props: {
    firstName: String,
    lastName: String
  },
  emits: ['update:firstName', 'update:lastName'],
  template: `
    <input 
      type="text"
      :value="firstName"
      @input="$emit('update:firstName', $event.target.value)">

    <input
      type="text"
      :value="lastName"
      @input="$emit('update:lastName', $event.target.value)">
  `
})

9、v-model支持自定义修饰符,通过props中modelModifiers访问;

10、新的全局API:createApp
(1)被创建原因:2.0的全局配置会影响多个app实例:

// 这会影响两个根实例
Vue.mixin({
  /* ... */
})

const app1 = new Vue({ el: '#app-1' })
const app2 = new Vue({ el: '#app-2' }

(2)使用:

import { createApp } from 'vue'
import MyApp from './MyApp.vue'

const app = createApp(MyApp)
app.mount('#app')

(3)Vue.prototype 替换为 config.globalProperties

// 之前 - Vue 2
Vue.prototype.$http = () => {}
// 之后 - Vue 3
const app = createApp({})
app.config.globalProperties.$http = () => {}

(4)由于 use 全局 API 在 Vue 3 中不再使用,此方法将停止工作并停止调用 Vue.use() 现在将触发警告,于是,开发者必须在应用程序实例上显式指定使用此插件:

const app = createApp(MyApp)
app.use(VueRouter)

11、v-model默认prop由value改为modelValue,触发事件由$emit('input', newValue)改为$emit.('update:modelValue', newValue)

12、v-for变更
(1)可遍历对象:P1--value p2--key p3--index;
(2)可接受整数

<div id="range" class="demo">
  <span v-for="n in 10" :key="n">{{ n }} </span>
</div>

// 输出:12345678910

13、v-ifv-for优先级变更:3.x中v-if优先级更高;(尽量避免同时使用两者)

14、v-bind合并行为变更

// 2.x版本
<!-- template -->
<div id="red" v-bind="{ id: 'blue' }"></div>
<!-- result -->
<div id="red"></div>
// 3.x版本:以顺序为主,往前覆盖
<!-- template -->
<div id="red" v-bind="{ id: 'blue' }"></div>
<!-- result -->
<div id="blue"></div>

<!-- template -->
<div v-bind="{ id: 'blue' }" id="red"></div>
<!-- result -->
<div id="red"></div>

15、移除v-on.native修饰符:3.x新增emits选项定义自定义事件,未定义的默认为原生事件;(除非在子组件的选项中设置了 inheritAttrs: false)

16、v-for 中的 Ref 数组

<div v-for="item in list" :ref="setItemRef"></div>
import { onBeforeUpdate, onUpdated } from 'vue'

export default {
  setup() {
    let itemRefs = []
    const setItemRef = el => {
      if (el) {
        itemRefs.push(el)
      }
    }
    onBeforeUpdate(() => {
      itemRefs = []
    })
    onUpdated(() => {
      console.log(itemRefs)
    })
    return {
      setItemRef
    }
  }
}

17、异步组件:* [异步组件现在需要 defineAsyncComponent 方法来创建]

// 2.x 版本
const oldAsyncComponent = (resolve, reject) => {
  /* ... */
}

// 3.x 版本: loader 函数不再接收 resolve 和 reject 参数,且必须始终返回 Promise
const asyncComponent = defineAsyncComponent(
  () =>
    new Promise((resolve, reject) => {
      /* ... */
    })
)

18、渲染函数变更:h(它是 createElement 的传统别名))现在是全局导入,不是render中作为参数传入;

// Vue 2 渲染函数示例
export default {
  render(h) {
    return h('div')
  }
}

// Vue 3 渲染函数示例
import { h } from 'vue'

export default {
  render() {
    return h('div')
  }
}

19、统一普通插槽和作用域插槽;

20、自定义元素方式改变;(还有is和v-is)

// 2.x版本
// 这将使Vue忽略在Vue外部定义的自定义元素
// (例如:使用 Web Components API)

Vue.config.ignoredElements = ['plastic-button']

// 3.x版本
// webpack 中的配置
rules: [
  {
    test: /\.vue$/,
    use: 'vue-loader',
    options: {
      compilerOptions: {
        isCustomElement: tag => tag === 'plastic-button'
      }
    }
  }
  // ...
]

// 如果使用动态模板编译,请通过 app.config.isCustomElement 传递:
const app = Vue.createApp({})
app.config.isCustomElement = tag => tag === 'plastic-button'

21、destroyed 生命周期选项被重命名为 unmounted;beforeDestroy 生命周期选项被重命名为 beforeUnmount;
22、default prop 工厂函数不再可以访问 this 上下文;
23、* 自定义指令 API 已更改为与组件生命周期一致
24、* data 选项应始终被声明为一个函数

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,193评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,306评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,130评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,110评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,118评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,085评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,007评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,844评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,283评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,508评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,667评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,395评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,985评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,630评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,797评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,653评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,553评论 2 352

推荐阅读更多精彩内容