详解vue高级特性(3)

不过一个子组件的根节点会同时受其父组件的 scoped CSS 和子组件的 scoped CSS 的影响。这样设计是为了让父组件可以从布局的角度出发,调整其子组件根元素的样式。

如果你希望父组件的 scoped 样式中的一个选择器能够作用得“更深”,例如影响子组件,可以使用深度选择器: >>> 操作符。

<style scoped> .a >>> .b { /* ... */ } </style>

上述代码将会编译成:

.a[data-v-f3f3eg9] .b { /* ... */ }

但是,有些像 Sass 之类的预处理器无法正确解析 >>>。这种情况下你可以使用 /deep/ 或 ::v-deep 操作符,这两者都是 >>> 的别名,实现同样的功能。

我们都知道,通过 v-html 创建的 DOM 内容不受 scoped 样式影响,可以通过深度作用选择器>>>来为他们设置样式。

七、路由的props属性

一般在组件内使用路由参数,大多数人会这样做:

export default { methods: { getParamsId() { return this.$route.params.id } } }

当你随便用用,临时凑手,这没什么问题,毕竟解决了需求。

可我们要随时谨记:组件是用来复用的!组件应该有高度的封闭性!

在组件中使用 $route 会使它与路由系统形成高度耦合,从而使组件只能在使用了路由功能的项目内,或某些特定的 URL 上使用,限制了其灵活性。

试想一下,如果你的组件被人拿去复用了,但是那个人并没有使用路由系统,而是通过别的方式传递id参数,那么他该怎么办?

正确的做法是通过 props 解耦!

首先,为组件定义一个叫做id的prop:

export default { props: ['id'], methods: { getParamsId() { return this.id } } }

如果组件没有对应路由,那么这个id也可以通过父组件向子组件传值的方式使用。

如果使用了路由,可以通过路由的prop属性,传递id的值:

const router = new VueRouter({ routes: [{ path: '/user/:id', component: User, props: true }] })

将路由的 props 属性设置为 true 后,组件内可通过 props 接收到 params 参数

另外,你还可以通过函数模式来返回 props

const router = new VueRouter({ routes: [{ path: '/user/:id', component: User, props: (route) => ({ id: route.query.id }) }] })

其实,上面的技巧,在VueRouter的官档都有说明。

八、异步组件

在大型应用中,我们可能需要将应用分割成小一些的代码块,并且只在需要的时候才从服务器加载一个模块。

为了简化,Vue 允许你以一个工厂函数的方式定义你的组件,这个工厂函数会异步解析你的组件定义。Vue 只有在这个组件需要被渲染的时候才会触发该工厂函数,且会把结果缓存起来供未来重渲染。例如:

Vue.component('async-example', function (resolve, reject) { setTimeout(function () { // 向 `resolve` 回调传递组件定义 resolve({ template: '<div>I am async!</div>' }) }, 1000) })

如你所见,这个工厂函数会收到一个 resolve 回调,这个回调函数会在你从服务器得到组件定义的时候被调用。

你也可以调用 reject(reason) 来表示加载失败。这里的 setTimeout 是为了演示用的,如何获取组件取决于你自己。

一个推荐的做法是将异步组件和 webpack 的 code-splitting 功能一起配合使用:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/773bf3bc7394b41cdab603808ee3ce29.html