组件命名及调用
VUE是允许用大写字母来注册组件的,但当你直接在dom
中使用时得在驼峰命名的大写字母间加上”-“并都改为小写
,看下面代码
<div id="app">
<my-template></my-template>
</div>
<script>
Vue.component('myTemplate',{
template: '<h1>这里是自定义组件的内容</h1>'
})
new Vue({
el: '#app'
})
</script>
命名与调用都小写
也可以正常使用
<div id="app">
<mytemplate></mytemplate>
</div>
<script>
Vue.component('mytemplate',{
template: '<h1>这里是自定义组件的内容</h1>'
})
new Vue({
el: '#app'
})
</script>
定义组件名的方式有两种:
1、使用 kebab-case 短横线分隔命名
Vue.component('my-component-name', { /* ... */ })
当使用 kebab-case (短横线分隔命名) 定义一个组件时,也必须在引用这个自定义元素时使用 kebab-case,例如 。
2、使用 PascalCase 首字母大写命名
Vue.component('MyComponentName', { /* ... */ })
当使用 PascalCase (首字母大写命名) 定义一个组件时,在引用这个自定义元素时两种命名法都可以使用。也就是说 和 都是可接受的。注意,尽管如此,直接在 DOM (即非字符串的模板) 中使用时只有 kebab-case 是有效的。
vue如何调用自定义组件的方法
1,先定义一个中间通信文件js globalBus.js
import Vue from 'vue';
export const globalBus = new Vue();
2,A.vue组件的方法需要去调用B.vue组件的方法。
首先在b组件去声明方法,,loginTo为方法名 number为接受的参数
import { globalBus } from "../../components/globalBus.js";
mounted() {
globalBus.$on("loginTo", (number) => {
console.log('调用了这个'+number)
});
},
3,然后再A组件用方法调用 ,loginTo是调用的方法,后面111是传的值
import { globalBus } from "../../components/globalBus.js";
methods: {
gototoUserLogin(){
globalBus.$emit("loginTo",111);
},
}
global api 改为应用程序实例调用
vue2 :引入vue构造函数,主要依靠render( (creatElement) => {})创建app实例对象
//引入vue
import Vue from 'vue'
//引入App
import App from './App.vue'
//创建vm
new Vue({
el:'#app',
render: *h* *=>* h(App),
router:router
})//.$mount('#app')
vue3:按需引入,直接用引入的createApp创建实例对象
//引入的不再是vue构造函数,而是叫createApp的工厂函数
import { createApp } from 'vue'
import App from './App.vue'
//创建应用实例对象-app(类似于v2中的vm,但app比vm更轻)并挂载
createApp(App).mount('#app')
vue3可以在createApp()方法后.component
进行一些组件的设置
render
render 函数作用
render 函数 跟 template 一样都是创建 html 模板的,但是有些场景中用 template 实现起来代码冗长繁琐而且有大量重复,这时候就可以用 render 函数。
官网例子:子组件想要根据父组件传递的 level 值(1-6)来决定渲染标签 h 几。具体代码可以看文档。
render 函数讲解
render 函数即渲染函数
,它是个函数,它的参数也是个函数——即 createElement
,我们重点来说 createElement 参数。
render 函数的返回值(VNode)
VNode(即:虚拟节点),也就是我们要渲染的节点。
render 函数的参数(createElement)
createElement 是 render 函数 的参数,它本身也是个函数,并且有三个参数。
createElement 函数的返回值(VNode)
createElement 函数的返回值是 VNode(即:虚拟节点)。
createElement 函数的参数(三个)
一个 HTML 标签字符串,组件选项对象,或者解析上述任何一种的一个 async 异步函数。类型:{String | Object | Function}。必需。
一个包含模板相关属性的数据对象你可以在 template 中使用这些特性。类型:{Object}。可选。
子虚拟节点 (VNodes),由 createElement() 构建而成,也可以使用字符串来生成“文本虚拟节点”。类型:{String | Array}。可选。
虚拟DOM
Vue 通过建立一个虚拟 DOM 对真实 DOM 发生的变化保持追踪。请近距离看一下这行代码:
return createElement('h1', this.blogTitle)
createElement 到底会返回什么呢?其实不是一个实际的 DOM 元素。它更准确的名字可能是createNodeDescription,因为它所包含的信息会告诉 Vue 页面上需要渲染什么样的节点,及其子节点。我们把这样的节点描述为“虚拟节点 (Virtual Node)”,也常简写它为“VNode”。“虚拟 DOM”是我们对由 Vue 组件树建立起来的整个 VNode 树的称呼。
render
方法会传入一个createElement
函数,它是一个用于创建DOM元素或者用于实例化其他组件的构造方法。render
方法必须返回
一个createElement函数的调用结果
,也就是模版内的顶层元素(这个方法在vue2的习惯性使用中经常用h来命名)。
eg:
render示例:
export default {
render (createElement){
const menu_items = ["首页","搜索","分类","系统"]
return createElement('ul',{
{
class:{'uk-nav':true}
},
menu_items.map(item=>createElement('li',item))
})
}
}
上述render
方法用template
来写的话如下:
<template>
<ul>
<li v-for="item in menu_items">
{{ item }}
</li>
</ul>
</template>
正是因为vue2中render只能返回一个createElement,所以vue2一定要有顶层元素。
render方法内不能再使用任何指令标记。其次,对组件或网页元素之间的属性赋值是通过createElement函数的第二个参数data进行的,domProps会向元素传递标准的DOM属性,而propsDate则用于对其他的Vue组件的自定义属性(props内的定义)进行赋值。
createElement的定义
createElement(tag,data,children)
返回值vNode(虚拟节点)
参数说明:
tag 类型:String/Object/Function 说明:一个HTML标签,组件类型,或一个函数
Data 类型:Object 说明:一个对应属性的数据对象,用于向创建的节点对象设置属性值
Children 类型:String/Array 说明:子节点
向构造的VNode对象设置文本时可以直接传入字符串,例如:
createElement(‘div’,‘这是行内文本’)
输出结果就是:
clike <div>这是行内文本</div>
data对象属性表
{
// 和v-bind:class
一样的 API ‘class’: { foo: true, bar: false }, // 和v-bind:style
一样的 API style: { color: ‘red’, fontSize: ‘14px’ }, // 正常的 HTML 特性 attrs: { id: ‘foo’ }, // 组件 props props: { myProp: ‘bar’ }, // DOM 属性 domProps: { innerHTML: ‘baz’ }, // 事件监听器基于 on
// 所以不再支持如 v-on:keyup.enter
修饰器 // 需要手动匹配 keyCode。 on: { click: this.clickHandler }, // 仅对于组件,用于监听原生事件,而不是组件内部使用 // vm.$emit
触发的事件。 nativeOn: { click: this.nativeClickHandler }, // 自定义指令。注意,你无法对 binding
中的 oldValue
// 赋值,因为 Vue 已经自动为你进行了同步。 directives: [ { name: ‘my-custom-directive’, value: ‘2’, expression: ‘1 + 1’, arg: ‘foo’, modifiers: { bar: true } } ], // Scoped slots in the form of // { name: props => VNode | Array } scopedSlots: { default: props => createElement(‘span’, props.text) }, // 如果组件是其他组件的子组件,需为插槽指定名称 slot: ‘name-of-slot’, // 其他特殊顶层属性 key: ‘myKey’, ref: ‘myRef’}
生成一个组件comp,调用h方法
和以前vue2的区别:render()
方法中不再通过参数
的形式 调用h
这类的方法
因为是在main.js
里设置的,所以是全局组件
调用这个comp全局组件:
全局方法哪些可以用 并 在vue3的版本里的写法
removed
代表在vue3中已删除不可使用
以上就是vue3全局组件及方法的写法
vue3中已删除filter过滤器
global and internal Apis重构为可做摇树优化
把vue2中直接挂在构造函数上的global-api(例如Vue.nextTick()),单独抽取出来成为独立函数,这样**摇树优化
就可以把这些vue2时的dead code
** 排除掉
受影响的api:
observable
和reactive
响应式方法
version
判断版本
complie
直接用来做编译
set
用于动态设置一些属性
delete
用于动态删除一些属性
only in compat builds
意思是只能用于兼容版(compat)
有些浏览器可能不兼容这些特性,可能会回退到以前的defineproperty
的实现方式,才会出现vue.se
t和vue.delete
方法
v-model使用的变化
vue2写法:
创建一个VmodelTest组件并引用 示例:
组件写法:
变量名可以和v-model:的名字相同(变量名如果要修改的话)
上面组件内部的写法,包含了子传父 的写法
调用组件并包含 父传子 的写法
vue3和vue2的等效写法
vue3写法
渲染函数Api修改
render
以前的 特性和属性 都是分开的,包括 事件、原生事件也是分开的
vue3 的render
拍平 代表就不会发生嵌套
前面加on
就代表是 事件
h 的函数也不再通过作为参数(型参)的方式传进来
插槽也发生了变化:
以前是this.$scopedSlots
去访问作用域插槽(可以传参)
https://www.cnblogs.com/liuyuweb/p/13820427.html
vue3中scopedSlots(作用域插槽)
已删除,统一到slots
render 渲染函数
render
的写法 onClick拍平
render
的写法 需要参数props
onClick中this
的指向会变化 所以要先在外部声明
如果不想在外部声明this
标准化的写法:
在methods
中先写onClick
方法
vue2时 使用插槽
v-slot:content 具名插槽
在插槽中获取 具名插槽 中的内容content…
vue3中删除了this.$scopedSlots(作用域插槽)
,所以统一写为this.$slots
title是 默认插槽
获取默认插槽
this.$slots.default()
写法:
插槽内容的获取
默认插槽 可以写为v-slot:default
作用域插槽就是具名插槽中传参数
写法
v-slot:content=“参数”
content是插槽名 可随意更改
函数式组件
vue2中 函数式组件
https://blog.csdn.net/time141/article/details/121927589
vue3中不太推荐使用函数式组件
主要是 函数式组件带来的性能提升 可以忽略不计
所以使用的需求就比较小了
vue3中函数式组件 只能用 函数方式声明
Heading.props = [‘level’] 是静态属性的方式进行声明
调用:
效果:
组件中 输出的内容
template标签上的 functional不能使用了
异步组件的使用
一、异步组件的简介
所谓的异步组件就是通过import
或者require
导入的vue组件。
例如:const componentA = import(’@/components/componentA.vue’);
或者 const componentA = require(’@/components/componentA.vue’);
注: @/ 的意思是返回到根路径,如使用vue-cli创建的项目,则使用@/则返回到src目录下。
如果要访问最外层的public目录中的文件则直接使用 / 即可,不加 /public 。
二、使用异步组件的好处
可以避免页面一加载时就去加载全部的组件,从而导致页面访问时间变长的问题。使用异步加载组件后,只有当需要某个组件时才会去加载需要的组件。
必须使用defineAsyncComponent
方法创建
异步组件以前是component
,现在是loader
异步组件示例:
异步的方式 要放入defineAsyncCompent()
中
组件内容(随便写了一个)
效果:
上图中的 异步 意思就是:异步执行一个叫NextPage的组件
vue3中异步组件 第一个不同就是
异步的方式 要放入defineAsyncCompent()
中
第二个不同:
带配置的异步组件中,component选项名称改为loader
vue3中,data没有对象形式,只有函数形式
自定义组件白名单
动画
transition
类名变更
例子:
动画的名称叫 fade
style
里 fade-enter-from
起始点
fade-leave-to
结束点
组件watch 选项 和实例方法 $watch 不再支持 点分隔符字符串路径
计算函数computed
vue3同时监听多个参数执行相同
的方法
watch([() => book.name, count], ([name, count], [preName, preCount]) => {
console.log("count或book.name改变了");
});