Vue学习笔记入门篇——组件杂项

本文为转载,原文:Vue学习笔记入门篇——组件杂项

动态组件

通过使用保留的 <’component’> 元素,动态地绑定到它的 is 特性,我们让多个组件可以使用同一个挂载点,并动态切换:

<div id="app">
    <component :is="currentView"></component>
</div>
var home = {
    template:'<p>this is home</p>'
}
var posts = {
    template:'<p>this is posts</p>'
}
var archive = {
    template:'<p>this is archive</p>'
}
var app = new Vue({
    el:'#app',
    data:{
        currentView:'home'
    },
    components:{
        home:home,
        posts:posts,
        archive:archive
    }
})

运行结果:


在控制台中修改app.currentView的值,界面会动态发生改变。
如果把切换出去的组件保留在内存中,可以保留它的状态或避免重新渲染。为此可以添加一个 keep-alive 指令参数:

<keep-alive>
  <component :is="currentView">
    <!-- 非活动组件将被缓存! -->
  </component>
</keep-alive>

编写可复用组件

在编写组件时,记住是否要复用组件有好处。一次性组件跟其它组件紧密耦合没关系,但是可复用组件应当定义一个清晰的公开接口。
Vue 组件的 API 来自三部分 - props, events 和 slots :

Props 允许外部环境传递数据给组件
Events 允许从外部环境在组件内触发副作用
Slots 允许外部环境将额外的内容组合在组件中

子组件索引

尽管有 props 和 events,但是有时仍然需要在 JavaScript 中直接访问子组件。为此可以使用 ref 为子组件指定一个索引 ID。例如:

<div id="parent">
    <user-profile ref="profile"></user-profile>
</div>
var parent = new Vue({ el: '#parent' })
// 访问子组件
var child = parent.$refs.profile

当 ref 和 v-for 一起使用时,ref 是一个数组,包含相应的子组件。

$refs 只在组件渲染完成后才填充,并且它是非响应式的。它仅仅作为一个直接访问子组件的应急方案——应当避免在模版或计算属性中使用 $refs。

组件命名约定

当注册组件 (或者 props) 时,可以使用 kebab-case,camelCase,或 PascalCase。
在 HTML 模版中,请使用 kebab-case 形式。
当使用字符串模式时,可以不受 HTML 的 case-insensitive 限制。

components: {
    'kebab-cased-component': { /* ... */ },
    camelCasedComponent: { /* ... */ },
    PascalCasedComponent: { /* ... */ }
}

如果组件未经 slot 元素传递内容,你甚至可以在组件名后使用 / 使其自闭合.

<my-component/>

当然,这只在字符串模版中有效。因为自闭的自定义元素是无效的 HTML,浏览器原生的解析器也无法识别它。

递归组件

组件在它的模板内可以递归地调用自己,不过,只有当它有 name 选项时才可以:

name: 'unique-name-of-my-component'

当你利用Vue.component全局注册了一个组件, 全局的ID作为组件的 name 选项,被自动设置.

Vue.component('unique-name-of-my-component', {
// ...
})

如果你不谨慎, 递归组件可能导致死循环:

name: 'stack-overflow',
template: '<div><stack-overflow></stack-overflow></div>'

上面组件会导致一个错误“max stack size exceeded”,所以要确保递归调用有终止条件 (比如递归调用时使用 v-if 并让他最终返回 false )。

内联模板

如果子组件有 inline-template 特性,组件将把它的内容当作它的模板,而不是把它当作分发内容。这让模板更灵活。

<div id="app">
    <my-component inline-template>
        <div>
            <p>These are compiled as the component's own template.</p>
            <p>Not parent's transclusion content.</p>
        </div>
    </my-component>
</div>
   Vue.component('my-component',{
    })
    new Vue({
        el:'#app'
    })

运行结果:

但是 inline-template 让模板的作用域难以理解。最佳实践是使用 template 选项在组件内定义模板或者在 .vue 文件中使用 template 元素。

x-Templates

另一种定义模版的方式是在 JavaScript 标签里使用 text/x-template 类型,并且指定一个 id。例如:

<script type="text/x-template" id="hello-world-template">
    <p>Hello hello hello</p>
</script>
Vue.component('hello-world', {
    template: '#hello-world-template'
})

这在有很多模版或者小的应用中有用,否则应该避免使用,因为它将模版和组件的其他定义隔离了。

对低开销的静态组件使用 v-once

尽管在 Vue 中渲染 HTML 很快,不过当组件中包含大量静态内容时,可以考虑使用 v-once 将渲染结果缓存起来,就像这样:

Vue.component('terms-of-service', {
  template: '
    <div v-once>
      <h1>Terms of Service</h1>
      ... a lot of static content ...
    </div>
  '
})

其他

还有一些异步组件,和递归组件暂时先不介绍,等以后学习到webpack时在说这个问题。

本文为原创,转载请注明出处。
上一节:Vue学习笔记入门篇——组件的内容分发(slot)
返回目录

原文地址:https://www.cnblogs.com/ChainZhang/p/7148151.html