zoukankan      html  css  js  c++  java
  • Vue 中可以定义组件模版的几种方式

    前置知识回顾

    new Vue({...options})一些基本知识
    new Vue(options)的选项中,也可以拥有 data、methods、components、生命周期函数等等,和组件实例的 options 一样。如下例子

    <div id="app">
      {{uname}}
      <hello-word></hello-word>
    </div>
    <script>
      Vue.component("HelloWord", {
        data() {
          return {
            msg: "你好,世界!",
          };
        },
        template: "<div>HelloWord组件-{{msg}}</div>",
      });
    
      var app = new Vue({
        el: "#app",
        data() {
          return {
            uname: "小红",
          };
        },
      });
    </script>
    

    根实例的 template、render 不是必须的,如上例子就是.
    它们的作用是接受一个根组件,然后将其编译后的内容填充到 el 内.
    通过 template、render 引入一个根组件,从而组成一个由上至下的组件树结构
    一般情况下,我们不在根实例中定义普通选项,根实例中常用的配置项有:

    {
        el: "#app",
        router,
        store,
        render:h=>h(App)
      }
    

    之所以说这些,是因为我下边的例子中,根实例有的没有用到 template、render
    下边我们举例说一下vue都有哪些模板技术

    方式 1: 模板-vue 单文件

    使用构建工具 cli 创建项目,综合来看单文件组件应该是最好的定义组件的方式,而且不会带来额外的模版语法的学习成本。
    如下,就一个完整的组件,使用的地方直接导入即可
    import MyHeader from './my-header.vue'

    <template>
      <h1>{{title}}</h1>
    </template>
    <script>
      // ./my-header.vue
      export default {
        name: "MyHeader",
        props: {
          title: "",
        },
      };
    </script>
    

    方式 2: 模板-template

    Vue 最简单直接的一种定义组件模版的方式,但是方式写起来很不友好,就像我们以前拼接 HTML 元素是一样的,很痛苦,所以我们并不常用
    字符串模板,template 选项对象的属性,模板将会替换挂载的元素,挂载元素的内容都将被忽略

    <div id="app">
      <my-header title="xx列表"></my-header>
    </div>
    <script>
      var MyHeader = {
        props: {
          title: "",
        },
        // 此处也可以使用es6的字符串模板能力
        template: "<h1>{{title}}</h1>",
      };
    
      var app = new Vue({
        el: "#app",
        components: { MyHeader },
      });
    </script>
    

    回忆过去

    需要注意是的是,大概 2018 年的时候,脚手架创建的项目
    vue 实例都是使 template 属性来指定根组件
    不过现在都被 render 函数写法代替了

    const app = new Vue({
      el: "#app",
      components: { App },
      template: "<App/>",
    });
    
    const app = new Vue({
      render: (h) => h(App),
    }).$mount("#app");
    

    展望未来

    X-Template,本质上讲,它仍是字符串模板 template 技术,是属于字符串模板的辅助性技术
    定义一个 <script> 标签,标记 text/x-template类型,通过 id 链接
    这个跟腾讯的artTemplate很像

    <div id="app">
      <my-header title="xx列表"></my-header>
    </div>
    <script type="text/x-template" id="my-header-xt">
      <h1>{{this.title}}</h1>
    </script>
    <script>
      Vue.component("MyHeader", {
        props: {
          title: "",
        },
        template: "#my-header-xt",
      });
    
      var app = new Vue({
        el: "#app",
      });
    </script>
    

    方式 3: 模板-内联模板

    与 「X-template」模版定义方式被称为模版定义的替代品,把内容定义在组件标签元素的内部,而不是作为 slot 内容分发,方式比较灵活,但是给让我们组件的模版与其他属性分离开。

    <div id="app">
      <my-template inline-template>
        <div>
          <!-- 只能有一个根元素 -->
          <div>{{uname}}</div>
          <!-- ❌❌ 无法使用父组件data -->
          <div>{{msg}}</div>
        </div>
      </my-template>
    </div>
    <script>
      Vue.component("MyTemplate", {
        data() {
          return {
            msg: "在子组件中声明的数据",
          };
        },
      });
    
      var app = new Vue({
        el: "#app",
        data() {
          return {
            uname: "小红",
          };
        },
      });
    </script>
    

    方式 4: 模板-render 函数

    单文件组件底层内部最终也是会被编译成 render 函数形式
    render 函数将会替换挂载的元素,挂载元素的内容都将被忽略
    模板-template的代替方案

    Vue.component("MyHeader", {
      props: {
        title: "",
      },
      render(createElement) {
        // 此处可以替换为jsx,会更加简介
        return createElement("h1", this.title);
      },
    });
    var app = new Vue({
      el: "#app",
    });
    

    以上就是 Vue 中可以定义组件模版的几种方式,有人可能说,我特么要知道这么多干嘛,只要一种不就行了,我想说兄 die 多知道几种可以帮助我们在不同的条件下做出更好的选择。

    比如:你就需要开发一个简单的页面,你非要弄个单文件组件,脚手架跑起来,何必呢,你说对不。

    解析 DOM 模板时的注意事项

    有些 HTML 元素,诸如 <ul><ol><table><select>,对于哪些元素可以出现在其内部是有严格限制的。而有些元素,诸如 <li><tr><option>,只能出现在其它某些特定的元素内部。

    这会导致我们使用这些有约束条件的元素时遇到一些问题。例如:

    <table>
      <blog-post-row></blog-post-row>
    </table>
    

    这个自定义组件 <blog-post-row> 会被作为无效的内容提升到外部,并导致最终渲染结果出错。幸好这个特殊的 is attribute 给了我们一个变通的办法:

    <table>
      <tr is="blog-post-row"></tr>
    </table>
    

    需要注意的是如果我们从以下来源使用模板的话,这条限制是不存在的:

    • 字符串模板 (例如:template: '...')
    • 单文件组件 (.vue)
    • 模板定义的替代品之 X-Template

    解读官方文档的描述,意思是说,普通这种写法(我把它称之为html模板)是不行的

    <div id="app">
      <select>
        <my-option></my-option>
      </select>
    </div>
    <script>
      Vue.component("MyOption", {
        template: "<option>选项一</option>",
      });
    
      var app = new Vue({
        el: "#app",
      });
    </script>
    

    使用字符串模板(模板-template)来使用组件,是可以的

    <div id="app"></div>
    <script>
      Vue.component("MyOption", {
        template: "<option>选项一</option>"
      });
      var app = new Vue({
        el: "#app",
        // 在模板-template使用也没问题
        template: `<select>
          <my-option></my-option>
        </select>`
      });
    </script>
    

    单文件组件 (.vue),是可以的

    <template>
      <div id="app">
        <select>
          <!-- 在单文件模板里这么用没问题 -->
          <my-option></my-option>
        </select>
      </div>
    </template>
    
    <script>
    import MyOption from './my-option.vue'
    export default {
      name: 'App',
      components: { MyOption },
    }
    </script>
    

    在x-template中,是可以的

    <div id="app"></div>
    <script type="text/x-template" id="my-app-xt">
      <select>
        <!--  在x-template使用没问题 -->
        <my-option></my-option>
      </select>
    </script>
    <script>
      Vue.component("MyOption", {
        template: `
          <option>选项一</option>
        </select>`,
      });
    
      var app = new Vue({
        el: "#app",
        template: "#my-app-xt",
      });
    </script>
    

    但是以上所有,只要is属性,就都可以解决该问题。

  • 相关阅读:
    虚拟机的三种联网模式(桥接模式、NAT 模式、仅主机模式)
    Vue 分页器 Pagination 实现点击分页器,平滑到对应的dom组件,而不是直接切换对应的组件
    img图片的处理技巧
    Vue中在DOM组件上动态绑定数据
    vue3.0中使用postcss-pxtorem
    vue中实现点击div有样式去除样式 无样式添加样式
    网易云音乐API,的调用方法 ,vue项目中(在本地使用)
    我的mixin.scss文件
    kendo-ui 几个有用的数据操作
    开发中常见的common.js--1
  • 原文地址:https://www.cnblogs.com/dshvv/p/15692576.html
Copyright © 2011-2022 走看看