处理边界情况
All the features on this page document the handling of edge cases,meaning unusual situations that sometimes require bending Vue’s rules a little. Note however, that they all have disadvantages or situations where they could be dangerous.
特殊情况下的处理方式,有利有弊
1. 访问元素&组件
1.1 访问根实例(Accessing the Root Instance )
通过 this.$root
根实例
// The root Vue instance
new Vue({
data: {
foo: 1
},
created:function(){
// 【获取根组件的数据】
console.log(this.$root.foo);
// 【写入根组件的数据】
this.$root.foo = 2
// 【访问根组件的计算属性】
this.$root.bar;
},
computed: {
bar: function () {
alert('我是计算属性bar,只要有人访问我或者改变我的值,我就执行')
}
},
methods: {
baz: function () {
alert('baz')
}
}
})
这种适合小型代码量时使用,中大型项目还是推荐用 Vuex
来管理应用的状态:如下
用根实例获取状态 VS 用Vuex
管理状态
完整代码
1.2 访问父组件实例
Similar to
$root
, the$parent
property can be used to access the parent instance from a child.
This can be tempting to reach for as a lazy alternative to passing data with a prop.
父组件通过prop向子组件传值,子组件也可通过$parent访问父组件的值
1.3 访问子组件或子元素
通过$refs
访问子组件,注意: $refs
只会在组件渲染完成之后生效。
<div id="app">
<base-input ref="usernameInput"></base-input>
</div>
<script>
Vue.component("base-input", {
template: "<input type='input' ref='input'>",
methods: {
popUp() {
alert(11)
},
focus: function () {
this.$refs.input.focus()
}
}
});
new Vue({
el: "#app",
data: {},
mounted: function () {
this.$refs.usernameInput.popUp();
this.$refs.usernameInput.focus();
}
});
</script>
1.4 依赖注入
In fact, you can think of dependency injection as sort of “long-range props”
使用props是父组件向子组件共享数据
而使用依赖注入是父组件向所有的子孙组件共享数据(可跨层级的分享数据)
使用方法:
// 父组件中抛出要分享的数据
provide: function () {
return {
getMap: this.getMap
}
}
// 在子组件中注入一下就可以用了,so easy!
inject: ['getMap']
2. 程序化的事件监听(Programmatic Event Listeners )
- Listen for an event with
$on(eventName, eventHandler)
- Listen for an event only once with
$once(eventName, eventHandler)
- Stop listening for an event with
$off(eventName, eventHandler)
当你需要在一个组件实例上手动侦听事件时,它们是派得上用场的
<div id="app">
<input ref="dateInput" v-model="date" type="text" />
</div>
<script>
new Vue({
el: "#app",
data: {
date: null
},
mounted: function() {
var picker = new Pikaday({
field: this.$refs.dateInput,
format: "YYYY-MM-DD"
});
this.$once("hook:beforeDestroy", function() {
picker.destroy();
});
}
});
</script>
3. 循环引用
3.1 递归组件
Components can recursively invoke themselves in their own template. However, they can only do so with the
name
option
组件可以在自身模板中调用自己,注意:不要陷入无限循环
<div id="app">
<base-input></base-input>
</div>
<script>
Vue.component("base-input", {
name: 'stack-overflow',
template: '<div><stack-overflow></stack-overflow></div>' // 无限循环:报错:Maximum call stack size exceeded
});
new Vue({
el: "#app",
data: {}
});
</script>
3.2 组件之间的循环引用
常见场景:渲染多层级结构时会用到
4. 定义模板的另外两种方式
4.1 Inline Template
这种方式会放模板的作用域容易混淆,不推荐,还是推荐用组件中的 template
选项或者.vue
文件中的元素
<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>
4.2 X-Template
这个有点像mustuche
模板的用法
<script type="text/x-template" id="hello-world-template">
<p>Hello hello hello</p>
</script>
Vue.component('hello-world', {
template: '#hello-world-template'
})
5. 控制更新(Controlling Updates)
5.1 强制更新
If you find yourself needing to force an update in Vue, in 99.99% of cases, you’ve made a mistake somewhere.
使用 $forceUpdate
强制更新,注意:需要强制更新的情况极少,99%可能性是你哪边出错了
5.2 通过 v-once
创建低开销的静态组件
要渲染的静态内容很多,明显影响了渲染性能时可以用,一般不要用。
Vue.component('terms-of-service', {
template: `
<div v-once>
<h1>Terms of Service</h1>
... a lot of static content ...
</div>
`
})
更多Vue文档解读:《Vue Doc 笔记》