随着组件的细化, 就会遇到多组件状态共享的情况, vuex 当然可以解决这类问题, 不过就像 Vuex 官方文档所说的, 如果应用不够大, 为避免代码繁琐冗余, 最好不要使用它, 今天我们介绍的是 vue.js 2.6 新增加的 Observable API , 通过使用这个 API 我们可以应对一些简单的跨组件数据状态共享的情况.
先看下官网描述, 如下图:
image.PNG
observable() 方法, 用于设置监控属性, 这样就可以监控 viewModule 中的属性值的变化, 从而就可以动态的改变某个元素中的值, 监控属性的类型不变量而是一个函数, 通过返回一个函数给 viewModule 对象中的属性, 从而来监控该属性.
说那么多, 我们在实际例子中尝试玩一下:
搭建个简单脚手架, 在项目 src 目录下建立 store.JS, 在组件里使用提供的 store 和 mutation 方法, 同理其它组件也可以这样使用, 从而实现多个组件共享数据状态.
首先, 创建一个 store.JS, 包含一个 store 和一个 mutations, 分别用来指向数据和处理方法.
- //store.JS
- import Vue from 'vue';
- export let store =Vue.observable({count:0,name:'李四'});
- export let mutations={
- setCount(count){
- store.count=count;
- },
- changeName(name){
- store.name=name;
- }
- }
然后在组件 Home.vue 中引用, 在组件里使用数据和方法:
- //Home.vue
- <template>
- <div class="container">
- <home-header></home-header>
- <button @click="setCount(count+1)">+1</button>
- <button @click="setCount(count-1)">-1</button>
- <div>store 中 count:{{count}}</div>
- <button @click="changeName(name1)"> 父页面修改 name</button>
- <div>store 中 name:{{name}}</div>
- <router-link to="/detail"><h5 > 跳转到详情页 </h5> </router-link>
- </div>
- </template>
- <script>
- import HomeHeader from '../components/HomeHeader'
- import {store,mutations} from '@/store'
- export default {
- data () {
- return {
- name1:'主页的 name'
- }
- },
- components: {
- HomeHeader
- },
- computed:{
- count(){
- return store.count
- },
- name(){
- return store.name
- }
- },
- methods:{
- setCount:mutations.setCount,
- changeName:mutations.changeName
- }
- }
- </script>
image.PNG
再定义一个子页面观察数据:
- //Detail.vue
- <template>
- <div class="detail">
- <detail-header></detail-header>
- <button @click="changeName(name2)"> 子页面修改 name</button>
- <p>store 中 name:{{name}}</p>
- </div>
- </template>
- <script>
- import DetailHeader from '../components/DetailHeader'
- import {store,mutations} from '@/store'
- export default {
- components: {
- DetailHeader
- } ,
- data(){
- return {
- name2:'子页的 name'
- }
- },
- computed:{
- name(){
- return store.name
- }
- },
- methods:{
- changeName:mutations.changeName
- }
- }
- </script>
image.PNG
我们简单点击下按钮, 改变下 store 中的数据, 效果如下:
image.PNG
最后补充一点, 就是如果当前项目 vue 版本低于 2.6, 要使用 Vue.observable(), 就必须要升级, 升级 vue 和 vue-template-compiler, 两者的版本需要同步, 如果不同步项目会报错.
// 升级 vue 版本
NPM update vue -S 或者 yarn add vue -S
NPM update vue-template-compiler -D 或者 yarn add vue-template-compiler -D
来源: http://www.jianshu.com/p/5306e120fa4a