image555小屋

welcome my blog

Vue2常见的问题

By image555

发表于 2017-10-17

vue-i18n和Element国际化使用


en.json
{
    "page":"home",
    "name":"name",
    "status-1":"delete",
    "status0":"stop",
    "status1":"start",
}

zh-CN.json
{
    "page":"首页",
    "name":"姓名",
    "status-1":"已删除",
    "status0":"停用",
    "status1":"启用",
}

i18n文件夹index.js

import Vue from 'vue'
import VueI18n from 'vue-i18n'
import en from './en.json'
import zh from './zh-CN.json'

/*element ui国际化*/
import langEn from 'element-ui/lib/locale/lang/en'
import langZh from 'element-ui/lib/locale/lang/zh-CN'
import locale from 'element-ui/lib/locale'

Vue.use(VueI18n)


export function createI18n (type) {
  let i18nElement='';
  let i18nVue='';

  if(type!="china"){
    i18nElement=langEn;
    i18nVue='en';
  }else{
    i18nElement=langZh;
    i18nVue='zh';
  }

  locale.use(i18nElement)

  return new VueI18n({
    locale: i18nVue,
    messages: {
      'en': en,
      'zh': zh
    }
  })
}


入口main.js
/*vue国际化*/
import { createI18n } from './i18n'
let langType='';
if(window.location.href.indexOf('http://haiwai')==-1){    
    langType='foreign';   
}else{
    langType='china';
}
Vue.prototype.$lang=(langType=='china')?"zh":"en";
const i18n = createI18n(langType)

new Vue({
    i18n,
    router,
    store,
    render: h => h(App)
}).$mount('#app'); 


调用
list.vue
<template>
    <div>
        <el-button type="primary" @click="handleBuild" :bind="$t('name')">$t('home')</el-button>
        <el-table-column prop="status" :label="$t('name')" min-width="100">
            <template scope="scope">
                <p :class="scope.row.status == 1?'success':'danger'">scope.row.status | statusChange($i18n)</p>
            </template>
        </el-table-column>
    </div>   
</template>
<script type="text/javascript">
export default{
    data:function(){
        return {
            list:[]
        }
    },
    filters: {
        statusChange(val,type) {
            var status='';
            switch(parseFloat(val)){
                case -1:
                    status=type.t('status-1');                       
                break;
                case 0:
                    status=type.t('status0');
                break;
                case 1:
                    status=type.t('status1');
                break;
            }
            return status;
        },
    }      
}
</script>

vue2子组件之间通信

大多数应用程序要求组件与其父组件或子组件进行通信。推荐的方法是实施一个状态管理解决方案,例如 Vuex(官方的,支持的Flux类实现)甚至VueStash。
但是,对于相对简单的应用程序来说,这可能会带来一些开销,您只需要少量的跨组件通信。这是您可以使用全局事件总线的地方。


为了使您的应用程序中的任何地方可用,您可以将其附加到Vue全局对象。
const EventBus = new Vue()

Object.defineProperties(Vue.prototype, {
  $bus: {
    get: function () {
      return EventBus
    }
  }
})

触发全局事件
1.您现在可以触发组件中的事件:

export default {
  name: 'my-component',
  methods: {
    triggerMyEvent () {
      this.$bus.$emit('my-event', { ... pass some event data ... })
    }
}

2.或直接在您的HTML模板
<div>
  <button @click="$bus.$emit('my-event')">Click to trigger event</button>
</div>


监听事件
事件可以在任何组件中收听。

export default {
  name: 'my-component',
  created () {
    this.$bus.$on('my-event', ($event) => {
      console.log('My event has been triggered', $event)
    })
  }
}

包括事件总线组件本身
const EventBus = new Vue({
  created () {
    this.$on('my-event', this.handleMyEvent)
  },
  methods: {
    handleMyEvent ($event) {
      console.log('My event caught in global event bus', $event)
    }
  }
})

多级数据更改 视图不更新问题

html结构、数据格式如下


<div class="myHighchart" v-if="charBtn">
  <div class="tabs">
      <el-button>付款成功金额:元</el-button>
      <el-button>付款成功:笔</el-button>
  </div>
  <vue-highcharts :Highcharts="Highcharts" :options="chartOpt1" ref="lineCharts"
      style="width: 82%;margin: 0 auto"></vue-highcharts>
</div>

export default {
    data: function () {
        return {
            chartOpt1: {               
                xAxis: {
                    categories: []
                },
                yAxis: {
                    title: {
                        text: '金额'
                    },
                    labels: {
                        formatter: function () {
                            return this.value + '元';
                        }
                    }
                },
                series: [{
                    name: '',                       
                    data: []
                }]
            },
            charBtn:false,
            chart:{
                money:0,
                num:0,
            },             
        }
    },
}

解决办法一,直接修改data里的chartOpt1,显示隐藏开关charBtn和$nextTick的配合使用

//获取列表
getBlockList(){
    this.charBtn =false;
    this.load_data = true;
    let postData = {
        page: this.curPage,                                     
        game_id:this.queryData.game_id,
    };

    this.$get(`${this.$url}thirdaccess/access-order/index`, postData).then((res) => {
        let result = res.data;
        let lineCharts = this.$refs.lineCharts;

        if (result.code == 0) {
            this.totalPage = result.data.odata.count;
            this.items = result.data.odata.items;

            Object.keys(result.data.game_id).forEach( key => {                       
                this.queryData.game_listArr.push({id:String(key),val:result.data.game_id[key]})
            });

            this.chart.money = result.data.orderStatistics.total_amount;
            this.chart.num = result.data.orderStatistics.total_people;
  
            //多级json 视图更新1
            this.chartOpt1.xAxis.categories = result.data.orderStatistics.unit;
            this.chartOpt1.series = result.data.orderStatistics.list;
            this.$nextTick(function () {
                this.charBtn = true;
            })

            this.load_data = false;
        }
    });
}, 

解决办法二,声明一个变量asyncData,用Object.assign方法替换data里的chartOpt1

const asyncData = {
  xAxis: {
      categories: []
  },
  yAxis: {
      title: {
          text: '金额'
      },
      labels: {
          formatter: function () {
              return this.value + '元';
          }
      }
  },
  series: [{
      name: '',                       
      data: []
  }]
}

export default {
  data: function () {
    return {
      chartOpt1:{},
      charBtn:false,
      chart:{
          money:0,
          num:0,
      },
    }
  }
}
//获取列表
getBlockList(){
    this.charBtn =false;
    this.load_data = true;
    let postData = {
        page: this.curPage,                                     
        game_id:this.queryData.game_id,
    };

    this.$get(`${this.$url}thirdaccess/access-order/index`, postData).then((res) => {
        let result = res.data;
        let lineCharts = this.$refs.lineCharts;

        if (result.code == 0) {
            this.totalPage = result.data.odata.count;
            this.items = result.data.odata.items;

            Object.keys(result.data.game_id).forEach( key => {                       
                this.queryData.game_listArr.push({id:String(key),val:result.data.game_id[key]})
            });

            this.chart.money = result.data.orderStatistics.total_amount;
            this.chart.num = result.data.orderStatistics.total_people;

            //多级json 视图更新2
            asyncData.xAxis.categories = result.data.orderStatistics.unit;
            asyncData.series = result.data.orderStatistics.list;
            this.chartOpt1 = Object.assign({}, this.chartOpt1, asyncData)

            this.load_data = false;
        }
    });
},