Vue之处理边界情况
处理边界情况
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> ` })