1、创建一个组件

  • 首先要创建一个根组件进行挂载
  • 再创建一个子组件,完成子组件的逻辑
  • 子组件主要使用template模板来完成布局和逻辑
  • 把子组件通过根组件.component的方法挂载到根组件上
<body>
<div id="app"><div class="component"><button-counter></button-counter></div>
</div>
<script>
const app=Vue.createApp({data(){return {msg:''}},})
//创建一个新的全局组件
app.component('button-counter',{data(){return {count:0,}},methods:{addcount(){this.count++}},template:`<button @click="addcount">你点击了按钮{{count}}次</button>`
})
app.mount('#app')</script>
</body>

2、页面中存放多个vue实例,虽然这样不合适

<body>
<div id="app"></div><div id="root"></div>
<script>
const app=Vue.createApp({data(){return {msg:'我是模板111'}},template:`<p>模板1{{msg}}</p>`}).mount('#app')const root=Vue.createApp({data(){return {msg:'我是模板222'}},template:`<p>模板2{{msg}}</p>`}).mount('#root')</script>
</body>

3、全局组件

全局组件:全局注册,可以在页面级页面中的子组件中使用
局部组件:只能在他定义的子组件中使用,不能在页面中使用

全局组件案例:

<body>
<div id="app"><div id="home"><button-counter></button-counter><span>首页</span></div><div id="message"><button-counter></button-counter><span>消息</span></div><div id="mine"><button-counter></button-counter><span>我的</span></div><button-counter></button-counter>
</div><script>const app=Vue.createApp({data(){return {msg:''}}})//注册全局组件app.component('button-counter',{data(){return {count:0}},methods:{add(){this.count++}},template:`<button @click="add">点击增加计数{{count}}</button>`,})
app.mount('#app')</script>
</body>

4、局部组件

  • 局部组件是通过常量来接收的,在页面根对象中注册(在components里注册,一定要是键值对的形式,简写出问题)
  • 局部组件不可以在不在局部注册的情况下嵌套,全局组件可以嵌套,
  • 如果局部组件要嵌套,必须在自己被嵌套的组件内部注册components。
<body>
<div id="app">
<p>====使用全局组件====</p><button-counter></button-counter>
<p>====使用局部组件====</p><area-com></area-com>
</div><script>//创建一个局部组件const area={data(){return {}},template: `<p>这是个局部组件</p>`}const app=Vue.createApp({data(){return {msg:''}},components:{'area-com':area//注册了局部组件},})//注册全局组件app.component('button-counter',{data(){return {count:0}},methods:{add(){this.count++}},template:`<button @click="add">点击增加计数{{count}}</button>`,})
app.mount('#app')</script>
</body>

局部组件嵌套案例

<body>
<div id="app">
<p>====使用全局组件====</p><button-counter></button-counter>
<p>====使用局部组件====</p><area-com></area-com><dance-com></dance-com>
</div><script>const dancer={data(){return{}},template:`<p>这是另外一个局部组件</p>`}//创建一个局部组件const area={data(){return {}},components: {'dance-com':dancer//在area里注册了这个组件,就可以在这个局部组件里面嵌套其他局部组件},template: `<b><dance-com></dance-com></b><p>这是个局部组件</p>`}const app=Vue.createApp({data(){return {msg:''}},components:{'area-com':area,//注册了局部组件'dance-com':dancer},})//注册全局组件app.component('button-counter',{data(){return {count:0}},methods:{add(){this.count++}},template:`<button @click="add">点击增加计数{{count}}</button>`,})
app.mount('#app')</script>
</body>

5、父子组件

父子组件中注册的子组件,不要在实例中直接去使用,也就是说,只能把组件用在template模板中

6、组件标签化

  • 使用script标签,也就是把template模板内的内容,独立到script标签里去了,从而减少组件内代码量
<body>
<div id="app">
<dancer-com></dancer-com>
</div>
<!--把模板标签化了,这里一定要使用taype=’text/template’-->
<script type="text/template" id="dancer"><p>这是dancer组件</p>
</script>
<script>const dancer={data(){return{}},template:'#dancer'//这里类似于jquery选择器}const app=Vue.createApp({data(){return {msg:''}},components:{'dancer-com':dancer},})app.mount('#app')</script>
</body>
  • 使用template标签,也就是把template模板内的内容,独立到template标签里去了,从而减少组件内代码量
<body>
<div id="app">
<dancer-com></dancer-com>
</div>
<!--把模板标签化了,这里一定要使用taype=’text/template’-->
<template id="dancer"><p>这是dancer组件,使用template标签容纳</p>
</template>
<script>const dancer={data(){return{}},template:'#dancer'}const app=Vue.createApp({data(){return {msg:''}},components:{'dancer-com':dancer},})app.mount('#app')</script>
</body>

7、组件data数据共享问题

组件内部data数据只能组件自己使用,不能共享出去,实际上就是组件具有封装性

<body>
<div id="app"><p>{{msg}}</p><p>-----------</p>
<dancer-com></dancer-com>
</div>
<!--把模板标签化了,这里一定要使用taype=’text/template’-->
<template id="dancer"><p>{{msg}}</p><p>这是dancer组件,使用template标签容纳</p>
</template>
<script>const dancer={data(){return{msg:'子组件dancer定义的内容'}},template:'#dancer'}const app=Vue.createApp({data(){return {msg:'页面中定义的数据'}},components:{'dancer-com':dancer},})app.mount('#app')</script>
</body>

8、组件的data选项必须是函数

  • 主要是为了数据能够隔离开,没创建一个新的组件就开创一个新的对象,而不是共用一个对象。
  • 共用一个对象的结果就是每个组件内部的数据会受到其他组件的修改,应为多个组件指向同一个内存堆控件

9、组件间通讯

不要在子组件中直接修改父组件的状态数据()
数据和处理数据的函数应该在同一模块内

组件通信的常用方式:

  • props
  • 自定义事件
  • 消息订阅与发布
  • vuex(消息和状态管理机制)

10、组件间通讯-props

  • 只指定名称
  • 指定名称和类型
  • 指定名称、类型和默认值

11、组件间通讯-props–只指定名称

  • 1、实际是父向子传值
  • 2、子组件内写props数据,并且在子组件内自己用
  • 3、父组件写发给props的数据代用
  • 4、在组件标签内,将子组件props里的属性和父组件内的属性绑定起来

步骤

  • 在页面中定义数据
  • 在组件中定义props(可以是数组,也可以是对象)
  • 在html中引用组件,并以属性及属性值的形式向props传值(键名是数组元素名称)
  • 传值完毕后,在子组件的template中引用该props数组元素的名称
<body>
<div id="app"><!--这里要使用绑定语法--><study-com :university="msg1" :course="msg2"></study-com>
</div>
<!--把模板标签化了,这里一定要使用taype=’text/template’-->
<template id="study"><p>--------</p><h3>这是一个子组件</h3><h3>{{university}}</h3>//直接使用props数组中的元素<h3 v-for="(item,index) in course" :key="index">{{item}}</h3><p>--------</p>
</template>
<script>const study={data(){return {}},//用来接收父组件传来的数据props:['university','course'],template:'#study'}const app=Vue.createApp({data(){return {msg1:'北京大学',msg2:['JavaScript','ios','android']}},components:{'study-com':study},})app.mount('#app')</script>
</body>

12、父子组件间通讯-props–指定名称和类型

<body>
<div id="app"><uni-com :uni="msg1" :courses="msg2"></uni-com><uni-com :uni="msg3" :courses="msg4"></uni-com>
</div>
<!--把模板标签化了,这里一定要使用taype=’text/template’-->
<template id="university"><p>这是一个子组件</p><h3>这里显示学校名称 {{uni}}</h3><p>这里遍历学院名称</p><ul><li v-for="(item,index) in courses" :key="index" >{{item}}</li></ul>
</template>
<script>//创建一个子组件const university={data(){return {}},props:{uni:String,courses:Array},template:'#university'}const app=Vue.createApp({data(){return {msg1:'清华大学',msg2:['经管学院','建筑学院','文法学院'],msg3:'北京大学',msg4:['数学学院','考古','新闻传播学院'],}},components:{'uni-com':university}})app.mount('#app')</script>
</body>

更复杂的形式,对props传来的数据做名称,类型,必须与否等,默认值的限定

<body>
<div id="app"><uni-com :uni="msg1" :courses="msg2"></uni-com><uni-com :uni="msg3" :courses="msg4"></uni-com>
</div>
<!--把模板标签化了,这里一定要使用taype=’text/template’-->
<template id="university"><p>这是一个子组件</p><h3>这里显示学校名称 {{uni}}</h3><p>这里遍历学院名称</p><ul><li v-for="(item,index) in courses" :key="index" >{{item}}</li></ul>
</template>
<script>//创建一个子组件const university={data(){return {}},props:{uni: {type:String,default:'天津大学',required:true},courses: {type:Array,default: [],required: true}},template:'#university'}const app=Vue.createApp({data(){return {msg1:'清华大学',msg2:['经管学院','建筑学院','文法学院'],msg3:'北京大学',msg4:['数学学院','考古','新闻传播学院'],}},components:{'uni-com':university}})app.mount('#app')</script>
</body>

13、props注意事项

  • props数据验证的类型

String
Number
Boolean
Array
Object
Date
Function
Symbol
自定义类型

  • 此方式用于父组件向子组件传递数据
  • 所有标签属性都会成为组件对象的属性,模板页面可以直接引用
  • 如果需要向非子后代传递数据必须多层逐层传递
  • 兄弟组件间也不能直接props通信,必须借助父组件才可以

14、子组件通过自定义事件向父组件传递数据

  • 1、子组件添加一个函数,用来发射之间,使用this.$emit(‘事件名’,数据),将发射出去
  • 2、子组件模板触发添加的函数,实际地将这个事件发射出去
  • 3、父组件添加对应的函数,用来执行接收来的事件

只适合父子组件之间的数据传递(实际上是子向父传递),不适合隔代组件和兄弟组件传递数据
两个步骤

  • 1、页面中或是父组件中绑定事件监听
@click=“***”
this.$emit('函数名',{数据对象}

2、子组件触发事件

@btnclick='deletep'
deletep(){相关逻辑
}

案例1:接受发射的事件,但不接受数据

<body>
<div id="app"><subcom @recivefromsub="revicefunction"></subcom>
</div>
<!--把模板标签化了,这里一定要使用taype=’text/template’-->
<template id="mysub"><p>=============</p><h3>这是我的子组件</h3><button @click="btnClickForEmit">发射一个自定义事件给父组件</button><p>=============</p>
</template>
<script>//1、创建一个子组件const sub={data(){return {}},methods: {//发射一个自定义事件给父组件btnClickForEmit(){this.$emit('recivefromsub')}},template:'#mysub'}//这里是父组件const app=Vue.createApp({data(){return {msg:'默认信息'}},methods: {//执行发生过来的自定义事件的回调函数revicefunction(){console.log('接受到了子组件发射过来的数据,但没有接受数据')}},components:{//在父组件注册这个子组件'subcom':sub}})app.mount('#app')</script>
</body>

案例2:接受发射的事件,同时接受数据(数据可以是个对象也可以是其他数据类型)

  • 子组件发射时间的过程中,同时也发送数据额
  • 父组件使用发射过来的自定义事件名,同时也接受了传递的数据,并在回调函数隐含了一个datas(名字自取)的参数。
<body>
<div id="app"><subcom @recivefromsub="revicefunction"></subcom>
</div>
<!--把模板标签化了,这里一定要使用taype=’text/template’-->
<template id="mysub"><p>=============</p><h3>这是我的子组件</h3><button @click="btnClickForEmit">发射一个自定义事件给父组件</button><p>=============</p>
</template>
<script>//1、创建一个子组件const sub={data(){return {}},methods: {//发射一个自定义事件给父组件btnClickForEmit(){// this.$emit('recivefromsub','来自子组件的数据信息1','来自子组件的数据信息2')const obj={name:'子组件的数据信息',intro:'可以使用一个对象来传递数据信息'}this.$emit('recivefromsub',obj)}},template:'#mysub'}//这里是父组件const app=Vue.createApp({data(){return {msg:'默认信息'}},methods: {//执行发生过来的自定义事件的回调函数/*revicefunction(item1,item2){console.log('接受到了子组件发射过来的数据')console.log(item1)console.log(item2)}*/revicefunction(datas){//回调函数默认携带了子组件传递过来的数据console.log('接受到了子组件发射过来的数据')console.log(datas)}},components:{//在父组件注册这个子组件'subcom':sub}})app.mount('#app')</script>
</body>

15、组件通信之PubSub发布订阅(见后续章节)

16、父子组件相互访问–父组件访问子组件$refs

主要步骤

  • 1、给子组件绑定一个ref信息
<subcom ref=‘info’></subcom>

2、在父组件通过事件,在回调函数中通过this.$refs获取这个ref信息

this.$refs

获取来的信息在this. r e f s . i n f o . m s g 中 此 外 也 可 以 获 取 子 组 件 的 方 法 , 方 法 存 在 于 t h i s . refs.info.msg中 此外也可以获取子组件的方法,方法存在于this. refs.info.msg中此外也可以获取子组件的方法,方法存在于this.refs.info.方法名

<body>
<div id="app">
<!--  给子组件绑定一个ref--><subcom ref="info"></subcom><button @click="getChildrenCom">获取子组件</button>
</div>
<!--把模板标签化了,这里一定要使用taype=’text/template’-->
<template id="sub"><p>======</p><h3>这是一个子组件</h3><button @click="clickSub">点击了子组件的按钮</button><p>======</p>
</template><script>//1、创建一个子组件
const sub={data(){return {msg: '子组件的信息'}},methods: {printinfo(){console.log('来自子组件中的方法')},clickSub(){alert('点击了子组件的按钮')}},template:'#sub'
}//这里是父组件const app=Vue.createApp({data(){return {msg:'默认信息'}},methods: {getChildrenCom(){//this.$refs获取子组件的数据console.log(this.$refs.info.msg)this.$refs.info.printinfo()}},components:{'subcom':sub}})app.mount('#app')</script>
</body>

17、父子组件相互访问–子组件访问父组件$parent

一般不建议子组件访问父组件,会破坏父组件的复用性

<body>
<div id="app"><sub-Box></sub-Box>
</div>
<!--把模板标签化了-->
<template id="subbutton"><h3>这是第一个subbutton子组件</h3><button @click="subtbclickTime">点击了按钮{{count}}次</button>
</template><!--把模板标签化了-->
<template id="subBox"><p>这是subBox组件</p><subbuttoncom></subbuttoncom>
</template>
<script>//1、创建一个子组件const subbutton={data(){return {count:0}},methods:{subtbclickTime(){this.count++//子组件访问父组件// console.log(this.$parent.parentInfo)// console.log(this.$parent.$parent)//子组件访问root符// console.log(this.$root)console.log(this.$root.msg)}},template:'#subbutton'}//2、再创建一个子组件const subBox={data(){return {parentInfo:'父组件的默认信息'}},components: {'subbuttoncom':subbutton},template:'#subBox',}//这里是根组件const app=Vue.createApp({data(){return {msg:'这是根组件的默认信息'}},components:{'subBox':subBox}})app.mount('#app')</script>
</body>

Vue3(撩课学院)笔记02-创建组件,全局组件,局部组件,父子组件,组件标签化,组件的data数据共享,组件间通讯,props,父传子$ref,子传父$parent相关推荐

  1. Vue3(撩课学院)笔记07-vueRouter路由,创建路由,路由重定向,路由跳转,动态路由,路由懒加载,路由嵌套,路由参数穿传递的两种形式,通过事件来跳转路由

    1.vueRouter路由的两种模式 哈希模式:以#号分割,前端路由一般用hash模式比较多,可以兼容ie8以上,井号后面不发起请求 历史模式:putstate()和replaceState()方法入 ...

  2. Vue3(撩课学院)笔记09-axios简介,发起get请求的两种方式,发起带参的get及post请求,发起并发请求,并发请求结果将数组展开,axios全局配置,axios配置及封装,请求和响应拦截

    1.axios简介 axios是基于promise可以用于浏览器和node.js的网络请求库,在服务器端使用原生node.js,在浏览气短使用ajax(即XMLHttpRequests) 2.axio ...

  3. Vue3(撩课学院)笔记01-创建实例对象,v-for遍历,时间绑定,传参,时间修饰符,计算属性,v-if,v-show,深拷贝,v-model与各类表单的绑定

    1.创建vue实例对象 <!DOCTYPE html> <html lang="en"> <head><meta charset=&quo ...

  4. 撩课python视频下载_2018年撩课学院-Python+人工智能/JavaEE/Web全栈/全学科下载_IT教程网...

    教程名称: Python+人工智能/JAVAEE/Web全栈 作为Python编程语言的一本指南或者教程.它主要是为新手而设计,不过对于有经验的程序员来说,它同样有用.即便你对计算机的了解只是如何在计 ...

  5. Vue3(撩课学院)笔记04-高阶API-mixin混入,mixin自定义属性,全局配置mixin,自定义全局指令,自定义局部指令,自定义指令传入数据,teleport传送门

    1.Mixin混入 将课复用代码独立出来用于复用 通过创建Mixin对象将复用代码放在Mixin对象中 在根组件中添加mixins属性,通过数组来存放多个minxin对象(也就是把minin内容混入根 ...

  6. mysql 学习笔记 02创建表

    表结构的创建 比如: create table userinfo (id int unsigned comment 'id号'name varchar(60) comment '用户名'passwor ...

  7. vue3.0父传子,父传孙,子传孙,孙传父,孙传子的传值

    1.父组件 <template><div class="Parent" ref="Parent"><el-button @clic ...

  8. Vue3中的父传子和子传父如何实现

    大家都知道Vue2中父传子是通过父组件绑定一个属性,子组件再用props进行接收,子传父是通过this.$emit那么Vue3中有什么不同呢?以下为您解答谜团 #Vue3的父传子 一.现在父组件调用子 ...

  9. 【vue3.0学习】父传子 子传父

    父传子 <template><div id="app"><h1>父组件</h1><p>{{ money }}</p ...

最新文章

  1. Java 中文转拼音
  2. 浙江省计算机二级(C语言)通过经验+资料
  3. 轻轻松松,一键获取3000个外链
  4. linux网络编程之用socket实现简单客户端和服务端的通信(基于TCP)
  5. swig模板 PHP,如何使用nodejs前端模板引擎swig
  6. video4linux(v4l)使用摄像头的实例基础教程与体会
  7. sql动态sql给变量复值_在动态SQL中使用变量
  8. javaEE插件安装
  9. 课时46:魔法方法:描述符(property的原理)
  10. 非负矩阵分解 NMF(Non-negative Matrix Factorization )
  11. mysql数据库数据表的指令_mysql数据库和表操作命令
  12. HTML5基础学习(6):个人简历制作
  13. meltdown论文翻译
  14. iOS 开发者必不可少的 75 个工具,你都会了吗
  15. Dynamics 365 多租户?多实例?
  16. 树莓派与OpenCV实现人脸识别(OpenCV安装篇)
  17. 使用CSS中clip-path属性实现奥运五环
  18. 交换机access端口、hybrid端口、trunk端口配置
  19. 非暴力沟通--日常沟通的技巧与实践
  20. js下载文件的方法(H5、PC)(小程序)

热门文章

  1. 中科院刘康:低资源环境下的事件知识抽取
  2. 清览题库--C语言程序设计第五版编程题解析(3)
  3. MATLAB(一)——软件及基本操作介绍
  4. jdk11安装后没有jre的解决办法
  5. 计算机网络——云计算
  6. 计算机有60进制吗,60进制介绍
  7. 【C语言历程1.小球坠落】小球从100米处落下,每次落地后又反跳回来,高度返回到原来的1/2,然后再落下,问:第10次落地时,共经过了多少米?第10次反弹时的高度为多少?
  8. 测试的五个小分类--功能、界面、安全性、兼容性、易用性
  9. python最大堆_二叉堆 及 大根堆的python实现
  10. 根据两点经纬度计算两点距离...工具类