大佬教我写程序 发表于 2022-2-3 09:31:59

组件通信、插槽、动态组件、异步组件

修饰符


[*]lazy
   

[*]number
            

[*]trim
      组件化开发


[*]思想:提供了一种抽象,让我们可以开发出一个个独立可复用的小组件来构造我们的应用
[*]使用方法
1.使用Vue.extend()创建出来组件构造器对象
2.调用Vue.component()方法注册组件
3.使用组件
         
    综合写法,省略掉了Vue.extend(),但是component方法会自动调用extend函数
      
    Vue.component('mycpn', {      template: `                                        欢迎使用组件化开发

                                        这里是内容
                                        哈哈哈
                                    
`    })全局组件和局部组件

模板的两种写法

创建构造器&&注册组件
Vue.component('mycpn', {      template: '#cpn'    })<ul>

[*]标签
                   欢迎使用组件化开发

      这里是内容
      哈哈哈
   
    在模板里面添加数据


[*]模板里面的数据要存放在data函数当中
                            {{title}}

            这里是内容
            哈哈哈
            
      Vue.component('mycpn', {      template: '#cpn',      data() {      return {          title: '我是标题'      }      }    })

[*]为什么data是一个函数,而不是一个对象? 因为Vue让每个组件对象都返回一个新的对象,因为如果是同一个对象的,组件在多次使用后会相互影响。
组件通信

父到子通信



[*]props的三种写法
const cpn = {      template: '#npm',      // 1.数组类型写法      // props: ['cmessage']      props: {      /* 2.类型限制      cmessage: String */      // 3.提供一些默认值      cmessage: {          type: String,          default: 'aaaa',          //如果没有传值,默认为aaaa,且报错          required: true      },      cmovies: {          type: Array,          //type:object默认值必须是函数返回,目的是防止不要智指向 一个对象          default () {            return           }      }      }    }

[*]更多写法


[*]关于props里面驼峰命名时传参的方式



<hr>
在父组件中的自定义标签中,添加标签属性,那么在子标签中添加v-bind="$attrs",这样子组件中就会添加父组件自定义标签里的属性


<hr>
子到父的通信


[*]子到父数据的传递需要使用自定义事件
      
                      {{item.name}}      
      父子间双向通信

      
      props:{{pnum1}}

    data:{{cnum1}}

      props:{{pnum2}}

    data:{{cnum2}}

   
      父子组件通信之$children(Vue3已经弃用了)

      methods: {      btnClick() {          //以数组的形式输出所有的组件          console.log(this.$children);          //调用子组件的函数          this.$children.cfn()            //由于组件之间可能会插入其他的组件,所以但用数组的形式选择相应的子模块可能会出问题            //refs的用法          console.log(this.$refs); //输出一个对象,对象里包含组件中所有包含ref的组件,          console.log(this.$refs.aaa.message) //输出子数据      }      }子访问父之 $parent$root $el(可以拿到子组件整个模板)


[*]子组件应该尽量避免直接访问父组件的数据,因为这样耦合度太高了
[*]如果我们将子组件放在另外一个组件之内,很可能该父组件没有对应的属性,往往会引起问题
const app = new Vue({      el: '#app',      data: {      message: '我是父组件'      },      components: {      cpn: {          template: '#cpn',          methods: {            btnClick() {            //访问父组件            console.log(this.$parent);            console.log(this.$parent.message);            console.log(this.$root);            }          },          components: {            ccpn: {            template: '#ccpn',            methods: {                cbtnClick() {                  //访问根组件                  console.log(this.$root.message);                }            }            }          }      }      }    })

[*]$refs能够拿到所有绑定ref的DOM元素

非父子组件之间的访问(信息由高到低)

父组件添加新属性:
provide:{name:"why"age:18}

[*]provide里面的内容想要响应式处理需要用到computed,computed返回的是一个ref对象,需要取出其中的value来使用
[*]当前的this指向的是根组件本身,即this能够访问到data里面的值


子组件也添加新属性
inject:["name","age"]事件总线

在Vue2中

在Vue3中

如果想AB之间完成事件传递,那就要用到以下办法

[*]下载mitt库   npm install mitt
[*]封装一个工具

[*]导入工具并在B里面定义事件
btnClick() {      console.log("about按钮的点击");      emitter.emit("why", {name: "why", age: 18});      // emitter.emit("kobe", {name: "kobe", age: 30});      }

[*]在A里面监听函数
created() {      emitter.on("why", (info) => {      console.log("why:", info);      });      emitter.on("kobe", (info) => {      console.log("kobe:", info);      });//所有的事件type:事件名,info:传过来的信息      emitter.on("*", (type, info) => {      console.log("* listener:", type, info);      })    }

[*]取消事件


插槽


[*]模板中slot标签里没有内容的时候,可以通过自定义组件标签里添加内容插入
[*]模板中slot标签中有内容的时候,那就是默认插入的内容,若自定义组件标签里有内容,则会对其就行替换


具名slot


[*]如果自定义模板标签里的内容没有写name属性,则会替换所有无名slot标签内容


[*]v-slot:center 可以缩写成 #center
插槽作用域改变

         {{info.data.join(' - ')}}      
                              
    vue3中

动态组件


[*]component 是内置组件,通过里面的is属性指定是哪个组件显示


keep-alive


[*]include:只有匹配到name属性的组件才会被缓存
[*]exclude:匹配到任何之间的名称都不会被缓存
[*]max:最多可以缓存的数目,超过这个数目之后,会把最久未使用的组件删除缓存


在webpack打包的时候,将不同的函数分包

异步组件


[*]通过定义异步组件的方式引入组件,并注册组件之后再使用组件,那webpack在进行打包的时候会进行分包处理
[*]写法一:
import Home from './Home.vue';const AsyncCategory = defineAsyncComponent(() => import("./AsyncCategory.vue"))

[*]写法二:
const AsyncCategory = defineAsyncComponent({    loader: () => import("./AsyncCategory.vue"),    loadingComponent: Loading,    // errorComponent,    // 在显示loadingComponent组件之前, 等待多长时间    delay: 2000,    /**   * err: 错误信息,   * retry: 函数, 调用retry尝试重新加载   * attempts: 记录尝试的次数   */    onError: function(err, retry, attempts) {    }})异步组件和Suspense


[*]Suspense:内置的全局组件,它里面有两个插槽,一个名叫:default(默认显示),另一个是:fallback(default能显示就不会显示该组件)
[*]

注册Suspense组件之后,使用组件,

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: 组件通信、插槽、动态组件、异步组件