IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> Vue3(撩课学院)笔记02-创建组件,全局组件,局部组件,父子组件,组件标签化,组件的data数据共享,组件间通讯,props,父传子$ref,子传父$parent -> 正文阅读

[JavaScript知识库]Vue3(撩课学院)笔记02-创建组件,全局组件,局部组件,父子组件,组件标签化,组件的data数据共享,组件间通讯,props,父传子$ref,子传父$parent

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–只指定名称

步骤

  • 在页面中定义数据
  • 在组件中定义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、页面中或是父组件中绑定事件监听
@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.msgthis.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>
  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-07-17 11:49:36  更:2021-07-17 11:50:28 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/3 9:17:06-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码