文章目录

  • 前言
  • 一、全局组件
    • 子组件应用
    • 组件优点:组件的可复用性
    • 全局组件缺点描述
  • 二、局部组件
    • 创建与注册局部组件(认识components属性)
    • 局部组件的默认规定(组件名称首字母全都大写)
  • 三、父子组件的传值(静态、动态)
    • 3.1、静态传值(name="技小胖")
    • 3.2、动态传值(v-bind:xx="xx"配合子组件中的props数组接收)
      • 动态传递值
      • 动态传递函数
    • 3.3、三种校验方式
      • ①类型校验(props需要写成{}形式)
      • ②必填校验与默认值设置(required与default)
      • ③精准校验(validator)
  • 四、单项数据流
    • 4.1、父子组件传递属性补充
      • ①以对象形式传递多个参数
      • ②xx-xx=''传递,props中xxXx接收
    • 4.2、认识单项数据流
    • 4.3、解决方案:实现在子组件中修改父组件传递过来的参数
    • 4.4、设计单向数据流原因
  • 五、No-Props属性
    • 5.1、不使用props传递时效果(默认会继承到子组件中,仅仅是单标签情况)
    • 5.2、认识$attrs
  • 六、父子组件通信(子组件来发出指示让父组件执行指定函数)
    • 6.1、$emit来向外触发父组件函数(无参与有参)
    • 6.2、emits属性(方便管理向外触发的函数名称,有警告效果,数组以及对象形式)
    • 6.3、v-model配合$emit():实现非调用父组件函数来修改父组件对象属性值
      • 6.3.1、v-model="xxx"默认值接收
      • 6.3.2、v-model:属性="xxx"(设置别名接收)
  • 七、slot插槽(5个知识点)
  • 八、动态组件(切换组件)
    • 8.1、原生切换组件方式(借助v-if、v-show,keep-alive标签保存input状态)
    • 8.2、动态组件(component标签以及:is)
  • 九、异步组件(实现异步加载组件)
  • 十、补充知识点
    • 10.1、v-once(让某个元素标签只渲染一次)
    • 10.2、$refs(定位获取到指定设置ref的dom元素)
    • 10.3、provide属性以及inject属性(嵌套组件中传递值)
      • 10.3.1、引出provide以及使用
      • 10.3.2、注意点provide属性绑定inject属性并不是双向绑定!!!

前言

本篇博客是在学习技术胖-Vue3.x从零开始学-第一季 基础语法篇过程中记录整理的笔记,若文章中出现相关问题,请指出!

  • 当前该链接失效了,有需要的小伙伴可以去b站或者技术胖官网去找相应的视频与笔记。

所有博客文件目录索引:博客目录索引(持续更新)


一、全局组件

子组件应用

<body><div id="app"></div>
</body><script>//根组件(全局组件)const app = Vue.createApp({//直接应用两个自组件template: `<website /><describe />`});//子组件app.component('website', {template: ` <h2>JSPang.com</h2>`})app.component('describe', {template: ` <h2>技术胖的博客</h2>`})app.mount("#app");
</script>

组件优点:组件的可复用性

优点:组件与组件之间互不干扰,相互独立。

<body><div id="app"></div>
</body><script>//根组件const app = Vue.createApp({//复用多个组件template: `<m-count /><m-count /><m-count />`});//子组件(全局组件)app.component('m-count', {data() {return {count: 0}},methods: {addFun() {this.count++;}},template: `<sapn>{{count}}</sapn><button @click="addFun()">增加</button><br/>`})app.mount("#app");
</script>

全局组件缺点描述

一旦定义了,就会占用系统资源,它是一直存在的,你在任何地方都可以使用这个全局组件,对性能产生影响。

全局组件(通过vue实例调用component())的概括:只要定义了,处处可以使用,性能不高,但是使用起来简单。


二、局部组件

创建与注册局部组件(认识components属性)

创建局部组件:直接使用一个对象{}来表示。

注册局部组件:需要配合传入到components对象属性中。

示例:

<body><div id="app"></div>
</body>
<script>//1、创建局部组件:直接在一个对象中设置参数const counter = {data() {return {count: 0}},template: `<div>{{count}}<button @click="count++">增加1</button></div>`};const app = Vue.createApp({//2、注册局部组件,其完整写法:components: { counter:counter },前面一个是设置的别名,后一个是实际局部组件名称//下面我演示别名的写法,若是不使用别名使用components: { counter }即可!!!components: { changlu: counter },template: `<h2>JSPang.com</h2><changlu />`});const vm = app.mount("#app")</script>


局部组件的默认规定(组件名称首字母全都大写)

对于组件的名称采用全部首字母大写(驼峰命名法),示例如下:

const XieDaJiao = {template: `<h2>谢大脚</h2>`
}

三、父子组件的传值(静态、动态)

父子组件的传值,包括静态传值和动态传值。

3.1、静态传值(name=“技小胖”)

静态传值

核心:直接在标签中使用name="技小胖",该种方式vue会进行自动解析并传入到props数组中。

<body><div id="app"></div>
</body>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/3.0.2/vue.global.js"></script>
<script>const app = Vue.createApp({//1、通过属性name传入到子组件中template: `<h2>JSPang.com</h2><Son name="技小胖" />`});app.component('Son', {//2、通过使用props数组形式根将值接收到name属性里props: ['name'],template: `<div>{{name}} div </div>`})const vm = app.mount("#app");
</script>

效果:动态传值使用props属性接收后,对应的标签中不会有该键值了!


3.2、动态传值(v-bind:xx="xx"配合子组件中的props数组接收)

动态传递值

动态传值

将这个可改变的动态值放置在data对象里,之后使用v-bind动态从data对象中找到属性值并赋值给指定属性:

<body><div id="app"></div>
</body>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/3.0.2/vue.global.js"></script>
<script>const app = Vue.createApp({data() {return {//在data对象中包含一个可修改的属性值(动态的)name: "cl"}},//1、绑定data对象中的name值也就是cl赋值到name参数并传递到全局组件中template: `<h2>JSPang.com</h2><Son v-bind:name="name" />`})app.component('Son', {//2、同样使用name属性来进行接收这个属性值props: ['name'],template: `<h2>JSPang.com</h2><div>{{name}}</div>`})const vm = app.mount("#app");
</script>

注意点:静态传值一定传的是字符串string,而动态传值是根据data对象中的属性来决定!!!


动态传递函数

动态传递函数:本质与上面传递值相同,都是传递的data对象里的值。

示例:

<body><div id="app"></div>
</body>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/3.0.2/vue.global.js"></script>
<script>const app = Vue.createApp({data() {return {appFun: () => alert("我是根组件的appFun()方法")}},//1、还是老样子,编写v-bind:appFun = "appFun"来绑定对应data对象中的属性进行动态传函数template: `<h2>JSPang.com</h2><Son :appFun="appFun" />`})app.component('Son', {//2、接收该函数props: ['appFun'],methods: {divClick() {//3、调用传入进行的函数this.appFun();}},//为标签添加点击事件来间接调用动态传入的父组件的函数template: `<h2>JSPang.com</h2><div @click="divClick()">点我试试</div>`})const vm = app.mount("#app");
</script>


3.3、三种校验方式

①类型校验(props需要写成{}形式)

此时props需要写成{}形式,key为得到的数据,value表示需要校验的值:这种方式只是会在console中报出黄色警告信息,依旧还是将值传递过来的!

  • Vue支持的校验类型包括:String、Boolean、Array、Object、Function和Symbol。

效果:仅仅有警告信息,传递依旧会执行。

app.component('Son', {//校验name是否为string类型props: {name: String},template: `<div>{{name}} div </div>`
})


②必填校验与默认值设置(required与default)

required

required(布尔值true,false):必须传递参数,若是设置了类型参数就必须要校验指定传递的类型。

效果:会报黄色警告信息,传递空值也就是阻止传递,程序也会依旧运行!

注意:与default同时存在时,default失效!

示例

const app = Vue.createApp({data() {return {name: 123}},//进行传递值,只是传递的是number类型template: `<h2>JSPang.com</h2><Son :name="name"/>`
})app.component('Son', {//包含requred属性进行校验是否为String类型,不是就会阻止传递进来props: {name: {type: String,// required: falsedefault: 'i am changlu'}},template: `<div>{{name}} div </div>`
})

default

default(默认值):没有传递指定参数会设置默认值给指定参数。

效果:当没有传递过来指定值时,就会使用默认参数(没有required情况下)。

示例:

const app = Vue.createApp({data() {return {name: 123}},//没有进行传递值template: `<h2>JSPang.com</h2><Son />`
})app.component('Son', {//由于name没有接受到传递值并且没有required,就会使用default默认值props: {name: {type: String,default: 'i am changlu'}},template: `<div>{{name}} div </div>`
})


③精准校验(validator)

validator:精准校验是一个函数:通过布尔类型返回值来表示校验失败还是通过。

  • true:表示通过校验。
  • false:表示没有通过校验,仅仅在console上报警告信息,传值同样成功

示例:

<body><div id="app"></div>
</body><script src="https://cdn.bootcdn.net/ajax/libs/vue/3.0.2/vue.global.js"></script>
<script>const app = Vue.createApp({data() {return {name: 'xxxSPan'}},template: `<h2>JSPang.com</h2><Son :name="name"/>`})app.component('Son', {props: {name: {type: String,//validator属性是一个函数用于进行简单校验,根据返回值来表示是否通过//与default不会有任何联系,记住default只是没有传递值的时候进行设置默认值的validator: function (value) {console.log(value.search("JSPang"))return value.search("JSPang") != -1},default: 'JSPang.com'}},template: `<div>{{name}} div </div>`})const vm = app.mount("#app")
</script>


四、单项数据流

4.1、父子组件传递属性补充

①以对象形式传递多个参数

之前仅仅学习了单个值单个值传递,若是参数有多个在父组件标签中需要写大量的绑定传值,造成冗余。

效果:将要传递的多个参数封装到一个对象中传递即可!

示例

<body><div id="app"></div><script src="https://cdn.bootcdn.net/ajax/libs/vue/3.0.2/vue.global.js"></script><script>const app = Vue.createApp({data() {return {//1、将多个参数绑定至一个对象params: {content: 'xxx内容',a: 'a',b: 'b'}}},//2、使用v-bind='xx',来绑定某个对象进行传值template: `<exerTab v-bind="params" />`});app.component('exerTab', {//3、可直接使用对象内部的属性名来接收props: ['content', 'a', 'b'],template: `<span>{{ content }}-{{ a }}-{{ b }}</span>`});app.mount("#app");</script>
</body>


②xx-xx=''传递,props中xxXx接收

静态传递带有-号的属性:content-aa='xxx内容',需要使用props: ['contentAa']接收。

  • content-aa => contentAa,去掉-,并且之后字母大写拼接来接收!

示例

<body><div id="app"></div><script src="https://cdn.bootcdn.net/ajax/libs/vue/3.0.2/vue.global.js"></script><script>const app = Vue.createApp({//1、传递带有-的参数:content-aatemplate: `<exerTab content-aa='xxx内容' />`});app.component('exerTab', {//2、对应该类参数props接收,需要去掉-以及其后大写:contentAaprops: ['contentAa'],template: `<span>{{ contentAa }}</span>`});app.mount("#app");</script>
</body>

4.2、认识单项数据流

单项数据流:子组件可以使用父组件传递过来的数据,但是决定不能修改传递过来的数据!(可以想成调用函数时传递过来的是基本类型,而非地址引用传递)

效果:若是在子组件中修改父组件传递过来的值时就会报出warning提示并且会阻止修改该值!

<body><div id="app"></div><script src="https://cdn.bootcdn.net/ajax/libs/vue/3.0.2/vue.global.js"></script><script>const app = Vue.createApp({data() {return {content: '父组件中的content'}},template: `<exerTab :content='content' />`});app.component('exerTab', {props: ['content'],methods: {modifyContent() {this.content = '子组件修改了content';}},//绑定单击事件来尝试修改template: `<span @click="modifyContent()">{{ content }}</span>`});app.mount("#app");</script>
</body>


4.3、解决方案:实现在子组件中修改父组件传递过来的参数

方案:通过在data对象中设置一个新属性来接收传递来的参数,之后对该新属性进行赋值修改也能够达成目的!

示例

<body><div id="app"></div>
</body>
<script>const app = Vue.createApp({data() {return {count: 0}},template: `<div><changlu :count="count"/></div>`});app.component('changlu', {props: ['count'],data() {return {//1、创建一个属性来进行代替countmycount: this.count}},methods: {//2、对新创建的属性进行赋值操作handlerClick() {this.mycount++;}},template: `<span @click="handlerClick()">{{mycount}}</span>`});app.mount("#app");
</script>


4.4、设计单向数据流原因

核心:通过父组件传递到子组件中的data对象里的值不能够随意更改否则就会影响到其他复用的组件了!!!


五、No-Props属性

5.1、不使用props传递时效果(默认会继承到子组件中,仅仅是单标签情况)

简而言之:就是不使用props属性来接收的属性!

<body><div id="app"></div>
</body>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/3.0.2/vue.global.js"></script>
<script>const app = Vue.createApp({data() {return {count: 0}},template: `<div><changlu msg="hello,cl!"/></div>`});app.component('changlu', {//若是不使用props接收默认就会放置在template的标签中template: `<span>changlu组件</span>`});app.mount("#app");
</script>

效果:可以看到对应的键值对继承到了子组件标签中。若是不想让键值对继承到子组件上,可以在组件对象中添加如下属性:

inheritAttrs: false


5.2、认识$attrs

若是不使用props属性接收且template模板有多个标签:不会生效

若此时有个需求就是让某个标签具有对应的属性:此时就使用到了$attrs对象

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5AmAOaDB-1652144855684)(C:\Users\93997\AppData\Roaming\Typora\typora-user-images\image-20210708223102983.png)]

实际应用$attrs

this.$attrs:一个代理对象,其中包含了所有父组件传递子组件时的键值对中,可以从这里获取!

示例:

<body><div id="app"></div>
</body>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/3.0.2/vue.global.js"></script>
<script>const app = Vue.createApp({data() {return {count: 0}},template: `<div><changlu msg="hello,cl!" msg1="changlugege"/></div>`});app.component('changlu', {methods: {//this.$attrs:是一个代理对象,该对象中包含父组件传值过来的所有属性handleClick() {console.log(this.$attrs);}},//v-bind:msg="$attrs.msg1" =>  绑定单个值//v-bind="$attrs" => 绑定所有父组件传递过来的值template: `<span @click="handleClick()">changlu组件</span><span v-bind:msg="$attrs.msg1">changlu组件</span><span v-bind="$attrs">changlu组件</span>`});app.mount("#app");
</script>


六、父子组件通信(子组件来发出指示让父组件执行指定函数)

目的:通过子组件来调用父组件的函数来改变父组件的data对象中的属性。

6.1、$emit来向外触发父组件函数(无参与有参)

无参向外触发

this.$emit('addOne');:意思是子组件向外发出了一个addOne的信号,外部可使用@add-one="handleAdd"来表示收到信息并执行父组件中的handleAdd()函数!

  • 这里@add-one并不是必须要使用的,xx-xx比较特殊对应的是xxXx,对于普通名称也是可以的。

示例

<body><div id="app"></div>
</body>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/3.0.2/vue.global.js"></script>
<script>const app = Vue.createApp({data() {return {count: 0}},methods: {//1、父组件定义方法函数来操控data对象中的属性handleAdd() {this.count++;}},//2、:count="count":父组件向子组件传递属性//   @add-one="handleAdd":其中addOne为子组件向外进行触发的动作,handleAdd为父组件中本身的方法template: `<div><changlu :count="count" @add-one="handleAdd"/></div>`});app.component('changlu', {//来接收传递过来的属性props: ['count'],methods: {handleClick() {//重要:向外触发父组件的函数(通过传递的方式)this.$emit('addOne');}},template: `<span @click="handleClick()">{{count}}</span>`});app.mount("#app");
</script>

有参向外触发

方式:将需要向父组件传递的参数写在第二个参数中即可,如this.$emit(信号名,参数)


6.2、emits属性(方便管理向外触发的函数名称,有警告效果,数组以及对象形式)

目的:配合$emit向外抛出的名称填写,用于方便查看该组件向外触发的函数!

使用方式:直接在组件对象中设置属性emits: ['xxx','xxx']来进行声明表示向外触发的函数!

效果:一旦使用了该emits属性,那么就会对内部向外发出($emit)的函数名称进行校验,若是向外触发的没有在数组中显示就会出现警告信息,依旧执行父组件函数的!

数组形式

对象形式

附加功能:使用对象形式你能够编写对应的一个校验函数,若是返回true表示校验通过不会有警告信息,若是没有通过就会有警告信息依旧向外触发执行!


6.3、v-model配合$emit():实现非调用父组件函数来修改父组件对象属性值

6.3.1、v-model="xxx"默认值接收

方式:原本需要先将指定值进行传递之后配合$emit()向外抛出执行命令来进行执行,使用了v-model直接让父组件的对象某属性与子组件进行绑定连通在子组件中即可对其进行修改只不过需要配合​$emit使用`

示例如下

<body><div id="app"></div>
</body>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/3.0.2/vue.global.js"></script>
<script>const app = Vue.createApp({data() {return {count: 0}},//1、直接使用v-model来进行绑定对应属性值template: `<div><changlu v-model="count"/></div>`});app.component('changlu', {//2、使用v-model传递的默认必须使用modelValue来接收props: ['modelValue'],methods: {handleClick() {//3、依旧调用$emit()函数来执行,其中第一参数必须为update:modelValue//参数一:必须为update:modelValue//参数二:对于modelValue的操作,也就是说可以直接对外部属性进行修改this.$emit('update:modelValue', this.modelValue + 3);}},template: `<span @click="handleClick()">{{modelValue}}</span>`});app.mount("#app");
</script>


6.3.2、v-model:属性=“xxx”(设置别名接收)

针对于6.3.1进行简单修改即可!

好处:不用再在外部组件专门写一个方法来让内部向外触发调用了以及通过使用v-bind:xxx来进行传参!这里的方式更加的简洁明了推荐使用!!!


七、slot插槽(5个知识点)

①目的。②引用父组件还是子组件值。③插槽默认值。④具名标签(区分传递指定插槽)。⑤作用域插槽(子组件传值到父组件要传递的插槽内容中)。

1、slot插槽目的是为了从父组件中传递指定标签到子组件中来进行使用。

2、父组件中的插槽内容若是使用了{{}}就是引用的父组件中的值,在子组件中使用{{}}就是引用的子组件值。

const app = Vue.createApp({data() {return {content: '我是父组件'}},//将传递的标签内容写在<子组件></子组件>中template: `<changlu><span>{{content}}</span></changlu>`
});
app.component('changlu', {//在对应的位置使用<slot></slot>即可插入template: `<div><slot></slot></div>`
});

3、插槽默认值:若是父组件中没有传递指定插槽内容,slot标签就会失效。若是我们想要给插槽中添加一些默认值(可以是标签或值),直接写在slot标签中即可!但要注意一旦父组件传递了插槽内容就不会显示定义在插槽中的默认值了!

//<slot>标签中可以定义默认内容,若是父组件不传递就会使用默认内容!传递就使用传递过来的内容
template: `<div><slot><button @click="handleclick()">点我下试试</button>    </slot></div>
`

4、若是插槽中有多个标签,此时不同的标签我们想用在不同位置,就可以使用具名标签,也就是使用template标签包裹并使用v-slot:xxx来进行标识写在template中,可简写为#,在子组件中的slot标签里并配置name="xxx" 来进行配对父组件传递过来的

//父组件:将传递的内容模块化<template v-slot:xxx></template>
//v-slot:btn1 => #btn1,可进行简化
template: `<changlu><template v-slot:btn1><button >按钮1</button></template><template v-slot:btn2><button >按钮2</button></template></changlu>
`//子组件:对应slot标签中设置name="xxx"来指定接收
template: `<div><slot name="btn1"></slot><div>content</div><slot name="btn2"></slot></div>
`

5、作用域插槽:若是我们想要遍历父组件传递的插槽内容时,如何让插槽内容能够引用子组件里的data对象的值?

在插槽中使用:xx="xx"用来传递到父组件,在父组件使用子组件标签中使用v-slot="obj"来接收,传递来的值以键值对形式保存在obj对象里中,之后即可使用该对象中的属性进行{{}}显示操作了!!!

<body><div id="app"></div>
</body>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/3.0.2/vue.global.js"></script>
<script>const app = Vue.createApp({data() {return {content: '我是父组件'}},//v-slot="{item}"来接收子组件传递过来的值,这里使用到了对象解构template: `<changlu v-slot="{item,dataArr}"><span>{{item}}</span></changlu>`});app.component('changlu', {data() {return {dataArr: [1, 2, 3]}},//使用:item="item"来进行传值绑定//可以传多个值都是可以的,因为是通过对象的形式来接收的template: `<div><slot v-for="item in dataArr" :item="item" :dataArr="dataArr"></slot></div>`});app.mount("#app");
</script>

八、动态组件(切换组件)

8.1、原生切换组件方式(借助v-if、v-show,keep-alive标签保存input状态)

原生切换自定义组件

v-if来进行切换时input标签中的内容会清空,不会保存状态。若是想要保存状态使用<keep-alive>标签包裹。

v-show会保存状态。(原理是display:none,仅仅只是隐藏组件)

//父组件的template
data() {return {isSpan: true}
},
methods: {//改变isSpan的布尔值达到切换效果handleclick() {this.isSpan = this.isSpan ? false : true;}
},
template: `<m-span v-if="isSpan"></m-span><keep-alive><m-input v-if="!isSpan" ></m-input></keep-alive><button @click="handleclick">点我切换</button>
`//两个子组件
app.component('m-span', {template: `<span>span标签显示</span>`
});
app.component('m-input', {template: `<input type="text"/>`
});

8.2、动态组件(component标签以及:is)

好处:解放了之前切换组件时要将多个组件都写在template模板里,切换几个就需要写几个之后通过控制data对象里的布尔属性来进行静态显示!

方式<component :is="自定义标签名"></component>,就是这么简单,我们只需要在data对象中定义对应的自定义标签名就能够实现动态切换不同的组件,牛逼!

  • 特殊:对于input标签,我们要想保存切换前的状态就需要在外面包裹<keep-alive>标签。

示例

<body><div id="app"></div>
</body>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/3.0.2/vue.global.js"></script>
<script>const app = Vue.createApp({data() {return {//目标要显示的自定义组件名showlabel: 'm-span'}},methods: {handleclick() {//更改标签名this.showlabel = this.showlabel == 'm-span' ? 'm-input' : 'm-span';}},//动态组件实现:不需要通过v-if、v-show来进行判断显示,而是直接通过:is="组件名"的显示动态显示组件//<component :is="showlabel"></component>  => 动态组件//<keep-alive> => 保存input输入框状态template: `<keep-alive><component :is="showlabel"></component></keep-alive><button @click="handleclick">点我切换</button>`});//自定义的两个组件app.component('m-span', {template: `<span>span标签显示</span>`});app.component('m-input', {template: `<input type="text"/>`});const vm = app.mount("#app");
</script>

九、异步组件(实现异步加载组件)

原本之前我们直接定义的{},或者app.component('组件名',{})定义的组件都是同步组件。

异步组件目的:通过使用异步组件来动态的加载一些组件,可以将一些大型的项目拆分为小的js文件,在需要这些组件的时候就可以进行引入并进行使用组件

  • 在父标签中若是使用了异步组件就会进行异步加载组件,不是同步加载了!

核心

1、Vue.defineAsyncComponent(函数),需要传入一个函数。

2、函数要返回一个Promise,也就是异步,最终通过resolve({})reject({})将对应的组件对象传递出去就称为异步组件!

//自定义异步组件
app.component('asynCom', Vue.defineAsyncComponent(() => {//返回一个Promise对象return new Promise((resolve, reject) => {setTimeout(() => {resolve({template: `<span>异步显示的span</span>`});//将对应的组件进行传递!!!}, 3000);})
}));

示例:令组件延时3秒出现,可以看出异步的效果

<body><div id="app"></div>
</body>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/3.0.2/vue.global.js"></script>
<script>const app = Vue.createApp({data() {return {item: 'synCom'}},template: `<asynCom/><br/><synCom/>`});//自定义的两个组件app.component('synCom', {template: `<span>span标签显示</span>`});//自定义异步组件app.component('asynCom', Vue.defineAsyncComponent(() => {//返回一个Promise对象return new Promise((resolve, reject) => {setTimeout(() => {resolve({template: `<span>异步显示的span</span>`});//将对应的组件进行传递!!!}, 3000);})}));const vm = app.mount("#app");
</script>

十、补充知识点

10.1、v-once(让某个元素标签只渲染一次)

v-once:只显示一次值在页面上,之后若是动态修改值也不会进行渲染。(实际值进行了修改)

示例:

<body><div id="app"></div>
</body>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/3.0.2/vue.global.js"></script>
<script>const app = Vue.createApp({data() {return {count: 1}},methods: {handleclick() {this.count += 1;}},//v-once="xxx"进行绑定template: `<span v-once="count">{{count}}</span><button @click="handleclick">点我切换</button>`});const vm = app.mount("#app");
</script>

10.2、$refs(定位获取到指定设置ref的dom元素)

方式:在某个标签中添加ref="xxx",之后可通过js中使用$refs.xxx来获取到指定标签!

应用:获取到某个结点之后可以对其中内容来进行一些操作,最好还是操作dom元素!

示例:点击按钮之后来更改按钮中的值(其实完全可以进行双向绑定修改值的)

<script src="https://cdn.bootcdn.net/ajax/libs/vue/3.0.2/vue.global.js"></script>
<script>const app = Vue.createApp({data() {return {count: 1}},methods: {handleclick() {//2、获取到指定设置ref的dom元素console.log(this.$refs.mspan);//应用:插入新的内容this.$refs.mspan.innerHTML = "changlu";}},//1、在指定标签上定义ref="xxx"template: `<button ref="mspan" @click="handleclick">{{count}}</button>`});const vm = app.mount("#app");
</script>


10.3、provide属性以及inject属性(嵌套组件中传递值)

10.3.1、引出provide以及使用

引出provide以及inject属性

若是我们定义了两个子组件,在父组件中使用了第一个子组件,接着在第一个子组件中复用了第二个子组件,此时第二个子组件想要使用父组件中的值就需要一层一层借助通:xx="xx"+props属性来进行一层层往下传递。

弊端:若是有大量嵌套组件,需要重复进行v:bind以及props设置传参!

使用provide以及inject属性

方式:父组件定义provide: {}属性,孙子组件或其他子组件使用inject: ['xx']即可拿到!

注意provide对象想要动态使用this.属性拿到父组件data对象里的值,需要写成如provide(){ return {xxx=this.xxx}}

//想要拿到data对象里的值,需要编写provide函数接着子啊返回对象里进行获取!
provide() {return {count: this.count}
},

示例

<body><div id="app"></div>
</body>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/3.0.2/vue.global.js"></script>
<script>const app = Vue.createApp({data() {return {count: 1}},//1、定义可供其他组件使用的provide属性provide: {count: 1},template: `<firstspan></firstspan>`});//子组件:嵌套了子组件app.component('firstspan', {template: `<secspan/>`});//子组件//2、想要获取到provide对象中的属性,需要使用inject数组设置对应属性名来进行接收app.component('secspan', {inject: ['count'],template: `<span>{{count}}</span>`})const vm = app.mount("#app");
</script>


10.3.2、注意点provide属性绑定inject属性并不是双向绑定!!!

使用了provide属性可以方便父组件与嵌套组件方便进行传值,但是需要注意的是provide属性绑定inject属性并不是双向绑定,父组件中的值发生改变并不会重新传值过去来让子组件进行修改。

解决方案:之后会使用高级的语法来进行解决!(笨方法就是:xxx绑定以及使用props进行接收)


我是长路,感谢你的耐心阅读。如有问题请指出,我会积极采纳!
欢迎关注我的公众号【长路Java】,分享Java学习文章及相关资料
Q群:851968786 我们可以一起探讨学习
注明:转载可,需要附带上文章链接

Vue.js学习笔记 02、Vue组件篇笔记相关推荐

  1. Vue.js学习系列七——Vue服务器渲染Nuxt学习

    我又回来啦~这次我们来学习Vue的服务器渲染SSR. 关于SSR的文章网上很多,一开始看得我云里雾里.然后去Vue.js 服务器渲染指南和nuxt官网看了看,发现文章大多都是搬运官网的内容,真正讲的清 ...

  2. Vue.js 学习笔记 十二 Vue发起Ajax请求

    首先需要导入vue-resource.js,可以自己下载引入,也可以通过Nuget下载,它依赖于Vue.js. 全局使用方式: Vue.http.get(url,[options]).then(suc ...

  3. Vue.js 学习笔记 十一 自定义指令

    之前看到过v-bind,v-on等指令,Vue还可以自定义指<div id="divApp"        <div v-focus></div> & ...

  4. Vue.js 学习笔记 十 自定义按键事件

    <div id="divApp"><!--任何键盘动作都会触发--><input type="text" v-on:keyup=& ...

  5. Vue.js 学习笔记 九 v-if和v-show

    <p v-if="flag">v-if</p><p v-show="flag">v-show</p> flag是 ...

  6. Vue.js 学习笔记 八 v-for

    v-for指令,是用来循环的,常用的情况有以下4种 <div id="divApp"><!--迭代数字--><p v-for="n in 5 ...

  7. Vue.js 学习笔记 七 控制样式

    Vue.js可以灵活的控制样式 我们首先随便写2个样式 <style>.divCss {background-color: green;width:400px;height:400px;} ...

  8. Vue.js 学习笔记 六 v-model 双向绑定数据

    之前说的v-bind指令,可以绑定数据,但是是单向的,从model向view绑定,下面介绍v-model,可以双向绑定数据 <div id="divApp"><p ...

  9. Vue.js 学习笔记 五 常用的事件修饰符

    介绍几个常用的事件修饰符 直接上代码 <div id="divApp"><div class="divColor" v-on:click=&q ...

  10. Vue.js 学习笔记 四 用一,二,三的知识做个跑马灯

    做个简单的跑马灯效果 页面定义2个按钮,绑定2个方法. <div id="divApp"><input type="button" value ...

最新文章

  1. 报错You may use special comments to disable some warnings.vue-cli脚手架关闭eslint的步骤
  2. Spring Cloud第四章:熔断器Hystrix
  3. 在现有K8S集群上安装部署JenkinsX
  4. IntelliJ IDEA中文乱码问题
  5. vscode 里解决跨域的插件_VSCode里的逆天插件,可边写代码边画逻辑流程图了
  6. MQTT.fx客户端MQTT接入阿里云物联网平台,登录、订阅、发布消息
  7. Java FileWriter示例
  8. HTML5对表单的约束验证
  9. 『NLP学习笔记』AllenNLP的注册机制
  10. 新浪再传将被转手 盛大卖股TOM集团接盘?
  11. 深夜看了张一鸣的微博,让我越想越后怕
  12. 2012年8月26日
  13. 神经网络编程的34个案例,神经网络程序实例100篇
  14. portal服务器认证系统有哪些,Portal技术简介
  15. 计算机应用基础教师授课视频,利用微课促进《计算机应用基础》教学的有效途径...
  16. 使用ffmpeg将mp4格式视频元数据信息转到视频第一帧、转换mp4为ts格式视频
  17. MACbook安装双系统,启动转换助理提示“需要64位windows10或更高版本的ISO文件”
  18. java学习第109天,p665-676(05/07),12集干的漂亮
  19. 宝捷信注塑机PS系列采集方案
  20. linux安装nuke教程下载,Nuke7.0v8下载为windonws、Mac和Linux

热门文章

  1. 神经网络的可解释性——Network Dissection: Quantifying Interpretability of Deep Visual Representations
  2. 关于AD转换的按键检测想法
  3. 2022张宇考研基础30讲 线性代数 第四讲 线性方程组
  4. 轩逸车联网功能怎么用_2020款轩逸中控屏幕按键功能介绍
  5. linux中查找文件命令
  6. Mac 压缩软件Keka
  7. 八、分组查询(group by)
  8. 小学语文教师如何利用好多媒体计算机,对多媒体在小学语文教学中的几点思考...
  9. C++11新特性之POD类型
  10. Visual Studio设置背景图