• [Vue深入组件-边界情况处理] 模板定义的替代品


    1. 内联模板

    即将要说的是一个很有意思的Vue边界应用。

    Vue开发者,通常都有着很敏感的组件规则。 我们写的组件全部都是以一个个组件组装到一起的。

    当涉及组件之间通信,调用时,会出现各种招数应对各种场景。 如果你要写一个嵌套组件。

    你必然会先创建两个单独的组件,然后在其中一个引入注册另一个(当然,我们刚说过了组件的互相循环调用)。 注册好之后,为了我们的组件易于维护。 我们严格的分清,什么应该写在调用组件中, 哪些内容又应该写在子组件中,我们会考虑数据怎么传递,嵌套组件的是怎么协同工作的。

    但是,假如,你可以在父组件中,写子组件的dom呢?

    这么说,可能很疑惑,我一开始因为完全不明白,因为这种模式,以往我们从未遇见过。

    以下是一个示例,看完就知道了:

    //index
    <template>
      <div>
        <Child></Child>
      </div>
    </template>
    <script>
    import Child from "./comps/index.vue";
    export default {
      components: {
        Child,
      },
    };
    </script>
    
    <template>
      <div>
        <p>
          <progress :value="count" max="100"> </progress>
        </p>
        <button @click="count++">click download</button>
      </div>
    </template>
    <script>
    export default {
      data() {
        return {
          count: 0,
        };
      },
    };
    </script>
    

    这是一个再简单不过的父子组件了:

    img

    我们在子组件中定义了一个进度条元素,这是H5的原生元素,然后我们通过点击,让进度条变化。

    现在,我们子组将中dom 上<template><template/> 包裹的所有内容,都叫做这个子组件的模板,我们跟习惯叫他dom, 即便它实际上编译成html文件中真正的dom还需要很复杂底层Vue实现的过程。

    Vue 允许我们有一种边界的应用方式,可以将模板内容不写在子组件,而写到父组件中去。

    要做到这样只需要:

    1. 在父组件中需要调用的地方,给子组件注册标签元素,指定inine-template 属性,将其标记为一个行内模板。
    2. 将子组件中模板内容尽数剪切到template元素中间。

    即:

    //index
    <template>
      <div>
        <Child inline-template>
          <div>
            <p>
              <progress :value="count" max="100"> </progress>
            </p>
            <button @click="count++">click download</button>
          </div>
        </Child>
      </div>
    </template>
    <script>
    import Child from "./comps/index.vue";
    export default {
      components: {
        Child,
      },
    };
    </script>
    
    //Child
    <template> </template>
    <script>
    export default {
      data() {
        return {
          count: 0,
        };
      },
    };
    </script>
    <style></style>
    
    

    它完全能够如期运行。

    image-20210926233346064

    是不是非常神奇且有意思?

    注意,你仅能在<Child></Child> 标签内方式 该子组件的实例内容。但是不能访问父组件中的实例内容。 也不能在父组件中访问这个子组件实例的内容。

    这意味着,直接想当然的像下面这样操作是不行的哦:

    <template>
      <div>
        <Child inline-template>
          <div>
            <p>
              <progress :value="count" max="100"> </progress>
            </p>
            <!-- vue.runtime.esm.js?2b0e:619 [Vue warn]: Error in render: "TypeError: Cannot read properties of undefined (reading 'toString')" -->
            {{ name.toString }}
            <button @click="count++">click download</button>
          </div>
        </Child>
        <!-- [Vue warn]: Property or method "count" is not defined -->
        <button @click="count++">click download outside</button>
      </div>
    </template>
    <script>
    import Child from "./comps/index.vue";
    export default {
      components: {
        Child,
      },
      data() {
        return {
          num: 123,
        };
      },
    };
    </script>
    

    想想看,是不是表现的就像是,除了把子组件的模板内容换到了父组件中去写,似乎没有任何差异?

    就是如此,父子组件依然是不能直接互相访问彼此实例的

    是不是想问, 那这样写有个球用 ? 我干嘛还单独写个子组件? 直接写一个组件里不就好了?

    实际上,确实一般情况下是用不着的。 Vue 文档也提醒我们,这样使用会让我们阅读起来不友好,不易维护,作用域甚至可能会用的很混乱。 但是好处是,如果你的子组件数据处理逻辑很庞大,这么写,就可以满足在父组件中写子组件模板的同时,又能分隔开来父子组件的数据处理。

    用不用是一回事,知不知道是另一回事嘛。

    2. X-Template

    <script type="text/x-template" />
    

    实际上,这并不是一个官方的MIME type , stackoverflow 有大佬给出了如下解释:

    image-20210926235934762

    https://stackoverflow.com/a/31460171

    Vue 文档中,使用了这种特例。

    实际上,被标记为type="text/x-template" 的script 标签并不会被标准解析执行。

    Vue 会在dom渲染后再对其进行额外处理,注意,是Vue 处理。

    Vue 提供这样一个接口的目的是怎么被使用的?

    其实,这是在你不使用webpack 、gulp 等工具的时候才会用得到,为了方便在那种模式下在js 中写模板繁琐而出现的。 假如组件的template的内容很冗长,如果都在JavaScript里面拼接脚本,效率是非常低的,因为不能像写HTML那样舒服。因此,Vue 提供了另外一种定义模板的方法:

    <!doctype html>
    <html lang="en">
     <head>
      <meta charset="UTF-8">
      <meta name="Generator" content="EditPlus®">
      <meta name="Author" content="">
      <meta name="Keywords" content="">
      <meta name="Description" content="">
      <title>Vue之X-Templates的使用</title>
     </head>
     <body>
      <div id="app">
      <my-component></mycomponent>
      <script type="text/x-template" id="my-component">
       <div>这是组件的内容</div>
      </script>
     </div>
    <!-- 开发环境版本,包含了有帮助的命令行警告 -->
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> 
    <script>
     Vue.component('my-component',{
      template:'#my-component'
     });
     var app = new Vue({
      el:'#app'
     })
    </script>
     </body>
    

    参考自 link

  • 相关阅读:
    冗余链接-684-并查集
    Chrome浏览器进程
    BFC布局规则
    Front-end 前端优化总结
    Flex弹性布局
    Browse兼容性问题
    组合关系与组合模式
    YUI3组件框架之plugin
    javascript数据类型及转换
    矩阵打印
  • 原文地址:https://www.cnblogs.com/jaycethanks/p/15345350.html
Copyright © 2020-2023  润新知