阅读 758

iView+Vue+Echarts+ES6+Mock

实习项目中的技术栈是iView+Vue+Echarts,用了webpack打包等。现在记录学习和复习总结,结束后整理成文档。

Vue

在了解iView之前,要先了解Vue的基础知识。

Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。

Vue 常用指令

v-bind

将这个元素节点的 title 特性和 Vue 实例的 message 属性保持一致

<div id="app-2">
  <span v-bind:title="message">
    鼠标悬停几秒钟查看此处动态绑定的提示信息!
  </span>
</div>
复制代码
var app2 = new Vue({
  el: '#app-2',
  data: {
    message: '页面加载于 ' + new Date().toLocaleString()
  }
})
复制代码

缩写:

<!-- 完整语法 -->
<a v-bind:href="url">...</a>

<!-- 缩写 -->
<a :href="url">...</a>
复制代码

v-if

控制切换一个元素是否显示

<div id="app-3">
  <p v-if="seen">现在你看到我了</p>
</div>
复制代码
var app3 = new Vue({
  el: '#app-3',
  data: {
    seen: true
  }
})
复制代码

v-for

绑定数组的数据来渲染一个项目列表

<div id="app-4">
  <ol>
    <li v-for="todo in todos">
      {{ todo.text }}
    </li>
  </ol>
</div>
复制代码
var app4 = new Vue({
  el: '#app-4',
  data: {
    todos: [
      { text: '学习 JavaScript' },
      { text: '学习 Vue' },
      { text: '整个牛项目' }
    ]
  }
})
复制代码

v-on

添加一个事件监听器,通过它调用在 Vue 实例中定义的方法

<div id="app-5">
  <p>{{ message }}</p>
  <button v-on:click="reverseMessage">反转消息</button>
</div>
复制代码
var app5 = new Vue({
  el: '#app-5',
  data: {
    message: 'Hello Vue.js!'
  },
  methods: {
    reverseMessage: function () {
      this.message = this.message.split('').reverse().join('')
    }
  }
})
复制代码

缩写:

<!-- 完整语法 -->
<a v-on:click="doSomething">...</a>

<!-- 缩写 -->
<a @click="doSomething">...</a>
复制代码

v-model

轻松实现表单输入和应用状态之间的双向绑定

<div id="app-6">
  <p>{{ message }}</p>
  <input v-model="message">
</div>
复制代码
var app6 = new Vue({
  el: '#app-6',
  data: {
    message: 'Hello Vue!'
  }
})
复制代码

组件化应用构建

一个组件本质上是一个拥有预定义选项的一个 Vue 实例。

<div id="app-7">
  <ol>
    <!--
      现在我们为每个 todo-item 提供 todo 对象
      todo 对象是变量,即其内容可以是动态的。
      我们也需要为每个组件提供一个“key”,稍后再
      作详细解释。
    -->
    <todo-item
      v-for="item in groceryList"
      v-bind:todo="item"
      v-bind:key="item.id"
    ></todo-item>
  </ol>
</div>
复制代码
Vue.component('todo-item', {
  props: ['todo'],
  template: '<li>{{ todo.text }}</li>'
})

var app7 = new Vue({
  el: '#app-7',
  data: {
    groceryList: [
      { id: 0, text: '蔬菜' },
      { id: 1, text: '奶酪' },
      { id: 2, text: '随便其它什么人吃的东西' }
    ]
  }
})
复制代码

我们已经设法将应用分割成了两个更小的单元。子单元通过 prop 接口与父单元进行了良好的解耦。我们现在可以进一步改进 <todo-item> 组件,提供更为复杂的模板和逻辑,而不会影响到父单元。

Vue 特殊特性

ref

预期: string

ref 被用来给元素或子组件注册引用信息。引用信息将会注册在父组件的 $refs 对象上。如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向组件实例

<!-- `vm.$refs.p` will be the DOM node -->
<p ref="p">hello</p>

<!-- `vm.$refs.child` will be the child component instance -->
<child-component ref="child"></child-component>
复制代码
// 获取DOM <p>元素
this.$refs.p
复制代码

vm.$refs

类型: Object

一个对象, 持有注册过 ref 特性的所有DOM元素和组件实例。

Vue 计算属性

模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的。在模板中放入太多的逻辑会让模板过重且难以维护。对于任何复杂逻辑,你都应当使用计算属性computed

基础例子

<div id="example">
  <p>Original message: "{{ message }}"</p>
  <p>Computed reversed message: "{{ reversedMessage }}"</p>
</div>
复制代码
var vm = new Vue({
  el: '#example',
  data: {
    message: 'Hello'
  },
  computed: {
    // 计算属性的 getter
    reversedMessage: function () {
      // `this` 指向 vm 实例
      return this.message.split('').reverse().join('')
    }
  }
})
复制代码

这里我们声明了一个计算属性 reversedMessage。我们提供的函数将用作属性 vm.reversedMessagegetter 函数:

console.log(vm.reversedMessage) // => 'olleH'
vm.message = 'Goodbye'
console.log(vm.reversedMessage) // => 'eybdooG'
复制代码

计算属性缓存 vs 方法

你可能已经注意到我们可以通过在表达式中调用方法来达到同样的效果:

<p>Reversed message: "{{ reversedMessage() }}"</p>
复制代码
// 在组件中
methods: {
  reversedMessage: function () {
    return this.message.split('').reverse().join('')
  }
}
复制代码

我们可以将同一函数定义为一个方法而不是一个计算属性。两种方式的最终结果确实是完全相同的。然而,不同的是计算属性是基于它们的响应式依赖进行缓存的。只在相关响应式依赖发生改变时它们才会重新求值。这就意味着只要 message 还没有发生改变,多次访问 reversedMessage 计算属性会立即返回之前的计算结果,而不必再次执行函数。 相比之下,每当触发重新渲染时,调用方法将总会再次执行函数。

计算属性 vs 侦听属性

Vue 提供了一种更通用的方式来观察和响应 Vue 实例上的数据变动:侦听属性。然而,通常更好的做法是使用计算属性而不是命令式的 watch 回调。当需要在数据变化时执行异步或开销较大的操作时,使用侦听器方式是最有用的。

下面这个例子

<div id="demo">{{ fullName }}</div>
复制代码
var vm = new Vue({
  el: '#demo',
  data: {
    firstName: 'Foo',
    lastName: 'Bar',
    fullName: 'Foo Bar'
  },
  watch: {
    firstName: function (val) {
      this.fullName = val + ' ' + this.lastName
    },
    lastName: function (val) {
      this.fullName = this.firstName + ' ' + val
    }
  }
})
复制代码

上面代码是命令式且重复的。将它与计算属性的版本进行比较:

var vm = new Vue({
  el: '#demo',
  data: {
    firstName: 'Foo',
    lastName: 'Bar'
  },
  computed: {
    fullName: function () {
      return this.firstName + ' ' + this.lastName
    }
  }
})
复制代码

Vue 组件

组件是可复用的Vue实例,我们可以在一个通过 new Vue 创建的 Vue 根实例中,把这个组件作为自定义元素来使用。

Vue组件三要素

  1. 每个组件都带有一个名字。下例中button-counter就是组件的名字。
<div id="components-demo">
  <button-counter></button-counter>  
</div>
复制代码
  1. 注册组件:组件的格式为Vue.component('component-name',{});。此处为全局注册。

组件与 new Vue 接收相同的选项,例如 datacomputedwatchmethods 以及生命周期钩子等。

在组件这里data必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝,以此来实现组件的可复用性。

// 定义一个名为 button-counter 的新组件
Vue.component('button-counter', {
  data: function () { // 组件的data必须为函数
    return {
      count: 0
    }
  },
  template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>' // 组件的html显示
})
复制代码
  1. 使用 new Vue 创建 Vue 根实例,必须在组件注册之后。
new Vue({ el: '#components-demo' }) // 此处挂载点为组件的父元素
复制代码

PS:注意2、3步骤不可调换。

通过 Prop 向子组件传递数据

Prop 是你可以在组件上注册的一些自定义特性。当一个值传递给一个 prop 特性的时候,它就变成了那个组件实例的一个属性。

一个组件默认可以拥有任意数量的 prop,任何值都可以传递给任何 prop。

你会发现我们可以使用 v-bind 来动态传递 prop。

<div id="father">
  <blog-post v-for="post in posts"
             v-bind:key="post.id"
             v-bind:post="post" // v-bind 动态传递prop
  ></blog-post>
</div>
复制代码
Vue.component('blog-post', {
    props: ['post'], // 注册prop
    template: `
    <div class="blog-post">
      <h3>{{ post.title}}</h3>
      <div v-html="post.content"></div>
    </div>
    `
  })

new Vue({
    el: '#father',
    data: {
      posts: [ // 各prop的属性,自动在blog-post中可用
        {id: 1, title: 'title1', content: 'content1'},
        {id: 2, title: 'title2', content: 'content2'}
      ]
    }
  })
复制代码

上面的v-bind:post="post" 是将对象的所有属性都作为 prop 传入,等价于

v-bind:id="post.id"
v-bind:title="post.title"
v-bind:content="post.content"
复制代码

任何类型的值都可以传给一个 prop ,例如数字、布尔值、数组、对象等。

Prop类型

可以是:

props: ['title', 'likes', 'isPublished', 'commentIds', 'author']
复制代码

但是,通常你希望每个 prop 都有指定的值类型。这时,你可以以对象形式列出 prop,这些属性的名称和值分别是 prop 各自的名称和类型:

props: {
  title: String,  // prop名称为title,类型为String
  likes: Number,
  isPublished: Boolean,
  commentIds: Array,
  author: Object,
  callback: Function,
  contactsPromise: Promise // or any other constructor
}
复制代码

prop 的单项数据流

所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外改变父级组件的状态,从而导致你的应用的数据流向难以理解。

额外的,每次父级组件发生更新时,子组件中所有的 prop 都将会刷新为最新的值。这意味着你不应该在一个子组件内部改变 prop。如果你这样做了,Vue 会在浏览器的控制台中发出警告。

监听子组件事件

父级组件可以像处理 native DOM 事件一样通过 v-on 监听子组件实例的任意事件,子组件可以通过调用内建的 $emit 方法 并传入事件名称来触发一个事件。

我们在每篇博文正文之前添加一个按钮来放大字号:

<div id="blog-posts-events-demo">
  <div v-bind:style="{ fontSize: postFontSize + 'em' }">
    <blog-post
            v-for="post in posts"
            v-bind:key="post.id"
            v-bind:post="post"
            <!--父级组件可以像处理 native DOM 事件一样通过 v-on 监听子组件实例的任意事件-->
            
            v-on:enlarge-text="postFontSize += 0.1"
    ></blog-post>
  </div>
</div>
复制代码
  Vue.component('blog-post', {
    props: ['post'],
    template: `
    <div class="blog-post">
      <h3>{{ post.title }}</h3>
       <!--子组件可以通过调用内建的 $emit 方法 并传入事件名称来触发一个事件-->
      <button v-on:click="$emit('enlarge-text')">
        Enlarge text
      </button>
      <div v-html="post.content"></div>
    </div>
  `
  })

  new Vue({
    el: '#blog-posts-events-demo',
    data: {
      posts: [
        {id: 1, title: 'title1', content: 'content1'},
        {id: 2, title: 'title2', content: 'content2'}
      ],
      postFontSize: 1 // 初始化
    }
  })
复制代码

使用事件抛出一个值

有的时候用一个事件来抛出一个特定的值是非常有用的。例如我们可能想让 组件决定它的文本要放大多少。这时可以使用 $emit 的第二个参数来提供这个值:

<button v-on:click="$emit('enlarge-text', 0.1)">
  Enlarge text
</button>
复制代码

然后当在父级组件监听这个事件的时候,我们可以通过 $event 访问到被抛出的这个值:

<blog-post
  ...
  v-on:enlarge-text="postFontSize += $event"
></blog-post>
复制代码

在组件上使用 v-model

自定义事件也可以用于创建支持 v-model 的自定义输入组件。

<div id="father">
  <custom-input v-model="searchText"></custom-input>
</div>
复制代码

为了让它正常工作,这个组件内的 <input> 必须:

将其 value 特性绑定到一个名叫 valueprop 上 在其 input 事件被触发时,将新的值通过自定义的 input 事件抛出

  Vue.component('custom-input', {
    props: ['value'],
    template: `
    <input
      v-bind:value="value"
      v-on:input="$emit('input', $event.target.value)"
    >
  `
  })

  new Vue({
    el: '#father'
  })
复制代码

组件注册

全局注册

之前说的组件三要素就是全局注册的方式。组件在注册之后可以用在任何新创建的Vue根实例(new Vue)的模板中。

比如

<div id="app">
  <component-a></component-a>
  <component-b></component-b>
  <component-c></component-c>
</div>
复制代码
Vue.component('component-a', { /* ... */ })
Vue.component('component-b', { /* ... */ })
Vue.component('component-c', { /* ... */ })

new Vue({ el: '#app' })
复制代码

局部注册

全局注册往往是不够理想的,经常会造成用户下载的js的无谓的增加。

可以通过一个普通的JS对象来定义组件:

var ComponentA = { /* ... */ }
var ComponentB = { /* ... */ }
var ComponentC = { /* ... */ }

// 然后在 components 选项中定义你想要使用的组件:
new Vue({
  el: '#app',
  components: {
    'component-a': ComponentA,
    'component-b': ComponentB
  }
})
复制代码
<div id="father">
  <component-a></component-a>
  <component-b></component-b>
</div>
复制代码

对于components对象中的每个属性来说,其属性名就是自定义元素的名字,属性值就是这个组件的选项对象。

局部注册的组件在其子组件中不可用

如果希望 ComponentAComponentB 中可用,需要有如下改写:

var ComponentA = { /* ... */ }

var ComponentB = {
  components: {
    'component-a': ComponentA
  },
  // ...
}
复制代码
如果通过 Babel 和 webpack 使用ES2015 模块,那么代码看起来更像:
import ComponentA from './ComponentA.vue'

export default {
    components: {
        ComponentA
    },
    // ...
}
复制代码

注意在 ES2015+ 中,在对象中放一个类似 ComponentA 的变量名其实是 ComponentA: ComponentA 的缩写,即这个变量名同时是:

  • 用在模板中的自定义元素的名称
  • 包含了这个组件选项的变量名
在模块系统中局部注册

如果使用了 webpack 等模块系统,推荐创建一个 components 目录,并将每个组件放置在其各自的文件中。

然后在局部注册之前导入每个想使用的文件。例如,在一个假设的 ComponentB.jsComponentB.vue 文件中:

  import ComponentA from './ComponentA'
  import ComponentC from './ComponentC'
  
  export default {
      components: {
          ComponentA,
          ComponentC
      },
      // ...
  }
复制代码

现在 ComponentAComponentC 都可以在 ComponentB 的模板中使用了。

基础组件的自动化全局注册

基础组件指相对通用的例如输入框或者按钮之类的元素,会在各个组件中被频繁的用到。

如果你使用了 webpack (或在内部使用了 webpack 的 Vue CLI 3+),那么就可以使用 require.context 只全局注册这些非常通用的基础组件。这里有一份可以让你在应用入口文件 (比如 src/main.js) 中全局导入基础组件的示例代码:

import Vue from 'vue'
import upperFirst from 'lodash/upperFirst'
import camelCase from 'lodash/camelCase'

const requireComponent = require.context(
  // 其组件目录的相对路径
  './components',
  // 是否查询其子目录
  false,
  // 匹配基础组件文件名的正则表达式
  /Base[A-Z]\w+\.(vue|js)$/
)

requireComponent.keys().forEach(fileName => {
  // 获取组件配置
  const componentConfig = requireComponent(fileName)

  // 获取组件的 PascalCase 命名
  const componentName = upperFirst(
    camelCase(
      // 获取和目录深度无关的文件名
      fileName
        .split('/')
        .pop()
        .replace(/\.\w+$/, '')
    )
  )

  // 全局注册组件
  Vue.component(
    componentName,
    // 如果这个组件选项是通过 `export default` 导出的,
    // 那么就会优先使用 `.default`,
    // 否则回退到使用模块的根。
    componentConfig.default || componentConfig
  )
})
复制代码

内在

深入响应式原理

iView

组件

select下拉框

<Select v-model="allouseModel" style="width:100px">
        <Option v-for="item in allouseList" :value="item.value" :key="item.value">{{ item.label }}</Option>
</Select>
复制代码
allouseList : [
          {
            value: 'allo',
            label : '分配率'
          },
          {
            value: 'use',
            label : '利用率'
          }
],
allouseModel : 'allo',
复制代码

label 仅在 remote 模式下,初始化时使用。因为仅通过 value 无法得知选项的 label,需手动设置。

checkbox多选框

组合使用
<template>
    <CheckboxGroup v-model="social">
        <Checkbox label="twitter">
            <Icon type="social-twitter"></Icon>
            <span>Twitter</span>
        </Checkbox>
        <Checkbox label="facebook">
            <Icon type="social-facebook"></Icon>
            <span>Facebook</span>
        </Checkbox>
        <Checkbox label="github">
            <Icon type="social-github"></Icon>
            <span>Github</span>
        </Checkbox>
        <Checkbox label="snapchat">
            <Icon type="social-snapchat"></Icon>
            <span>Snapchat</span>
        </Checkbox>
    </CheckboxGroup>
    <CheckboxGroup v-model="fruit">
        <Checkbox label="香蕉"></Checkbox>
        <Checkbox label="苹果"></Checkbox>
        <Checkbox label="西瓜"></Checkbox>
    </CheckboxGroup>
</template>
<script>
    export default {
        data () {
            return {
                social: ['facebook', 'github'],
                fruit: ['苹果']
            }
        }
    }
</script>
复制代码

Menu导航菜单

<template>
    <Menu mode="horizontal" :theme="theme1" active-name="1">
        <MenuItem name="1">
            <Icon type="ios-paper"></Icon>
            内容管理
        </MenuItem>
        <MenuItem name="2">
            <Icon type="ios-people"></Icon>
            用户管理
        </MenuItem>
        <Submenu name="3">
            <template slot="title">
                <Icon type="stats-bars"></Icon>
                统计分析
            </template>
            <MenuGroup title="使用">
                <MenuItem name="3-1">新增和启动</MenuItem>
                <MenuItem name="3-2">活跃分析</MenuItem>
                <MenuItem name="3-3">时段分析</MenuItem>
            </MenuGroup>
            <MenuGroup title="留存">
                <MenuItem name="3-4">用户留存</MenuItem>
                <MenuItem name="3-5">流失用户</MenuItem>
            </MenuGroup>
        </Submenu>
        <MenuItem name="4">
            <Icon type="settings"></Icon>
            综合设置
        </MenuItem>
    </Menu>
    <br>
    <p>Change theme</p>
    <RadioGroup v-model="theme1">
        <Radio label="light"></Radio>
        <Radio label="dark"></Radio>
        <Radio label="primary"></Radio>
    </RadioGroup>
</template>
<script>
    export default {
        data () {
            return {
                theme1: 'light'
            }
        }
    }
</script>
复制代码

Echarts

charts

柱状图 bar

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>ECharts</title>
    <!-- 引入 echarts.js -->
    <script src="echarts.min.js"></script>
</head>
<body>
    <!-- 为ECharts准备一个具备大小(宽高)的Dom -->
    <div id="main" style="width: 600px;height:400px;"></div>
    <script type="text/javascript">
        // 基于准备好的dom,初始化echarts实例
        var myChart = echarts.init(document.getElementById('main'));

        // 指定图表的配置项和数据
        var option = {
            title: {
                text: 'ECharts 入门示例'
            },
            tooltip: {},
            legend: {
                data:['销量']
            },
            xAxis: {
                data: ["衬衫","羊毛衫","雪纺衫","裤子","高跟鞋","袜子"]
            },
            yAxis: {},
            series: [{
                name: '销量',
                type: 'bar',
                data: [5, 20, 36, 10, 10, 20]
            }]
        };

        // 使用刚指定的配置项和数据显示图表。
        myChart.setOption(option);
    </script>
</body>
</html>
复制代码

饼图 pie

饼图只有一维的数值,不需要给类目。不在直角坐标系上,也不需要xAxis,yAxis

myChart.setOption({
    series : [
        {
            name: '访问来源',
            type: 'pie',
            radius: '55%',
            data:[
                {value:235, name:'视频广告'},
                {value:274, name:'联盟广告'},
                {value:310, name:'邮件营销'},
                {value:335, name:'直接访问'},
                {value:400, name:'搜索引擎'}
            ]
        }
    ]
})
复制代码

个性化样式

ECharts 中有一些通用的样式,诸如阴影、透明度、颜色、边框颜色、边框宽度等,这些样式一般都会在系列的 itemStyle 里设置。例如设置扇形的颜色:

itemStyle: {
    // 设置扇形的颜色
    color: '#c23531',
    shadowBlur: 200,
    shadowColor: 'rgba(0, 0, 0, 0.5)'
}

复制代码

调色盘

调色盘,可以在 option 中设置。它给定了一组颜色,图形、系列会自动从其中选择颜色。 可以设置全局的调色盘,也可以设置系列自己专属的调色盘。

option = {
    // 全局调色盘。
    color: ['#c23531','#2f4554', '#61a0a8', '#d48265', '#91c7ae','#749f83',  '#ca8622', '#bda29a','#6e7074', '#546570', '#c4ccd3'],

    series: [{
        type: 'bar',
        // 此系列自己的调色盘。
        color: ['#dd6b66','#759aa0','#e69d87','#8dc1a9','#ea7e53','#eedd78','#73a373','#73b9bc','#7289ab', '#91ca8c','#f49f42'],
        ...
    }, {
        type: 'pie',
        // 此系列自己的调色盘。
        color: ['#37A2DA', '#32C5E9', '#67E0E3', '#9FE6B8', '#FFDB5C','#ff9f7f', '#fb7293', '#E062AE', '#E690D1', '#e7bcf3', '#9d96f5', '#8378EA', '#96BFFF'],
        ...
    }]
}
复制代码

dataset 管理数据

ECharts 4 提供了 数据集(dataset)组件来单独声明数据,它带来了这些效果:

  • 能够贴近这样的数据可视化常见思维方式:基于数据(dataset 组件来提供数据),指定数据到视觉的映射(由 encode 属性来指定映射),形成图表。
  • 数据和其他配置可以被分离开来,使用者相对便于进行单独管理,也省去了一些数据处理的步骤。
  • 数据可以被多个系列或者组件复用,对于大数据,不必为每个系列创建一份。
  • 支持更多的数据的常用格式,例如二维数组、对象数组等,一定程度上避免使用者为了数据格式而进行转换。
option = {
    legend: {},
    tooltip: {},
    dataset: {
        // 提供一份数据。
        source: [
            ['product', '2015', '2016', '2017'],
            ['Matcha Latte', 43.3, 85.8, 93.7],
            ['Milk Tea', 83.1, 73.4, 55.1],
            ['Cheese Cocoa', 86.4, 65.2, 82.5],
            ['Walnut Brownie', 72.4, 53.9, 39.1]
        ]
    },
    // 声明一个 X 轴,类目轴(category)。默认情况下,类目轴对应到 dataset 第一列。
    xAxis: {type: 'category'},
    // 声明一个 Y 轴,数值轴。
    yAxis: {},
    // 声明多个 bar 系列,默认情况下,每个系列会自动对应到 dataset 的每一列。
    series: [
        {type: 'bar'},
        {type: 'bar'},
        {type: 'bar'}
    ]
}
复制代码

API

tooltip

显示提示框,有下面两种使用方式。

  1. 指定在相对容器的位置处显示提示框,如果指定的位置无法显示则无效
dispatchAction({
    type: 'showTip',
    // 屏幕上的 x 坐标
    x: number,
    // 屏幕上的 y 坐标
    y: number,
    // 本次显示 tooltip 的位置。只在本次 action 中生效。
    // 缺省则使用 option 中定义的 tooltip 位置。
    position: Array.<number>|string|Function
})
复制代码
  1. 指定数据图形,根据 tooltip 的配置项显示提示框。
dispatchAction({
    type: 'showTip',
    // 系列的 index,在 tooltip 的 trigger 为 axis 的时候可选。
    seriesIndex?: number,
    // 数据的 index,如果不指定也可以通过 name 属性根据名称指定数据
    dataIndex?: number,
    // 可选,数据名称,在有 dataIndex 的时候忽略
    name?: string,
    // 本次显示 tooltip 的位置。只在本次 action 中生效。
    // 缺省则使用 option 中定义的 tooltip 位置。
    position: Array.<number>|string|Function,
})
复制代码

timeline

配置项

series

系列列表,每个系列通过 type 决定自己的图标类型。

line 折线/面积图

pie 饼图

bar 柱状/条形图

encode

可以定义 data 的哪个维度被编码成什么。

option = {
    dataset: {
        source: [
            // 每一列称为一个『维度』。
            // 这里分别是维度 0、1、2、3、4。
            [12, 44, 55, 66, 2],
            [23, 6, 16, 23, 1],
            ...
        ]
    },
    series: {
        type: 'xxx',
        encode: {
            x: [3, 1, 5],      // 表示维度 3、1、5 映射到 x 轴。
            y: 2,              // 表示维度 2 映射到 y 轴。
            tooltip: [3, 2, 4] // 表示维度 3、2、4 会在 tooltip 中显示。
        }
    }
}
复制代码

当使用 dimensions 给维度定义名称后,encode 中可直接引用名称,例如:

series: {
    type: 'xxx',
    dimensions: ['date', 'open', 'close', 'highest', 'lowest'],
    encode: {
        x: 'date',
        y: ['open', 'close', 'highest', 'lowest']
    }
}
复制代码

下面是encode 支持的一些属性:

// 在任何坐标系和系列中,都支持:
encode: {
    // 使用 “名为 product 的维度” 和 “名为 score 的维度” 的值在 tooltip 中显示
    tooltip: ['product', 'score']
    // 使用 “维度 1” 和 “维度 3” 的维度名连起来作为系列名。(有时候名字比较长,这可以避免在 series.name 重复输入这些名字)
    seriesName: [1, 3],
    // 表示使用 “维度2” 中的值作为 id。这在使用 setOption 动态更新数据时有用处,可以使新老数据用 id 对应起来,从而能够产生合适的数据更新动画。
    itemId: 2,
    // 指定数据项的名称使用 “维度3” 在饼图等图表中有用,可以使这个名字显示在图例(legend)中。
    itemName: 3
}

// 对于一些没有坐标系的图表,例如饼图、漏斗图等,可以是:
encode: {
    value: 3
}
复制代码

series[i]-xxx.label

图形上的文本标签,可用于说明图形的一些数据信息,比如值,名称等

series[i]-line.label.formatter

【string, Function】。

标签内容格式器,支持字符串模板和回调函数两种形式,字符串模板与回调函数返回的字符串均支持用 \n 换行。

字符串模板 模板变量有:

  • {a}:系列名。
  • {b}:数据名。
  • {c}:数据值。
  • {@xxx}:数据中名为'xxx'的维度的值,如{@product}表示名为'product'` 的维度的值。
  • {@[n]}:数据中维度n的值,如{@[3]}` 表示维度 3 的值,从 0 开始计数。

series[i]-pie.label.formatter

相较于 line 折线图,饼图多了一个模板变量:

  • {d}:百分比。

例如:

formatter: '{b}: {@四月} ({d}%)'
复制代码

Echarts中的事件和行为

鼠标事件的处理

ECharts 支持常规的鼠标事件类型,包括 'click'、'dblclick'、'mousedown'、'mousemove'、'mouseup'、'mouseover'、'mouseout'、'globalout'、'contextmenu' 事件。

// 基于准备好的dom,初始化ECharts实例
var myChart = echarts.init(document.getElementById('main'));

// 指定图表的配置项和数据
var option = {
    xAxis: {
        data: ["衬衫","羊毛衫","雪纺衫","裤子","高跟鞋","袜子"]
    },
    yAxis: {},
    series: [{
        name: '销量',
        type: 'bar',
        data: [5, 20, 36, 10, 10, 20]
    }]
};
// 使用刚指定的配置项和数据显示图表。
myChart.setOption(option);
// 处理点击事件并且跳转到相应的百度搜索页面
myChart.on('click', function (params) {
    window.open('https://www.baidu.com/s?wd=' + encodeURIComponent(params.name));
});
复制代码

所有的鼠标事件包含参数 params,这是一个包含点击图形的数据信息的对象,如下格式:

{
    // 当前点击的图形元素所属的组件名称,
    // 其值如 'series'、'markLine'、'markPoint'、'timeLine' 等。
    componentType: string,
    // 系列类型。值可能为:'line'、'bar'、'pie' 等。当 componentType 为 'series' 时有意义。
    seriesType: string,
    // 系列在传入的 option.series 中的 index。当 componentType 为 'series' 时有意义。
    seriesIndex: number,
    // 系列名称。当 componentType 为 'series' 时有意义。
    seriesName: string,
    // 数据名,类目名
    name: string,
    // 数据在传入的 data 数组中的 index
    dataIndex: number,
    // 传入的原始数据项
    data: Object,
    // sankey、graph 等图表同时含有 nodeData 和 edgeData 两种 data,
    // dataType 的值会是 'node' 或者 'edge',表示当前点击在 node 还是 edge 上。
    // 其他大部分图表中只有一种 data,dataType 无意义。
    dataType: string,
    // 传入的数据值
    value: number|Array
    // 数据图形的颜色。当 componentType 为 'series' 时有意义。
    color: string
}
复制代码

如何区分鼠标点击到了哪里:

myChart.on('click', function (params) {
    if (params.componentType === 'markPoint') {
        // 点击到了 markPoint 上
        if (params.seriesIndex === 5) {
            // 点击到了 index 为 5 的 series 的 markPoint 上。
        }
    }
    else if (params.componentType === 'series') {
        if (params.seriesType === 'graph') {
            if (params.dataType === 'edge') {
                // 点击到了 graph 的 edge(边)上。
            }
            else {
                // 点击到了 graph 的 node(节点)上。
            }
        }
    }
});

复制代码

ES6

Axios

Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。

特性

  • 从浏览器中创建 XMLHttpRequests
  • 从 node.js 创建 http 请求
  • 支持 Promise API
  • 拦截请求和响应
  • 转换请求数据和响应数据
  • 取消请求
  • 自动转换 JSON 数据
  • 客户端支持防御 XSRF

axios API

可以通过向 axios 传递相关配置来创建请求

// 获取远端图片
axios({
  method:'get',
  url:'http://bit.ly/2mTM3nY',
  responseType:'stream'
})
  .then(function(response) {
  response.data.pipe(fs.createWriteStream('ada_lovelace.jpg'))
});
复制代码

请求配置

这些是创建请求时可以用的配置选项。只有 url 是必需的。如果没有指定 method,请求将默认使用 get 方法。

  // `url` 是用于请求的服务器 URL
  url: '/user',

  // `method` 是创建请求时使用的方法
  method: 'get', // default
  
  // `headers` 是即将被发送的自定义请求头
  headers: {'X-Requested-With': 'XMLHttpRequest'},

 // `params` 是即将与请求一起发送的 URL 参数
   // 必须是一个无格式对象(plain object)或 URLSearchParams 对象
  params: {
    ID: 12345
  },
  
  // `data` 是作为请求主体被发送的数据
  // 只适用于这些请求方法 'PUT', 'POST', 和 'PATCH'
  // 在没有设置 `transformRequest` 时,必须是以下类型之一:
  // - string, plain object, ArrayBuffer, ArrayBufferView, URLSearchParams
  // - 浏览器专属:FormData, File, Blob
  // - Node 专属: Stream
  data: {
    firstName: 'Fred'
  }
复制代码

模块化

export 与 export default

export 本质上就是规定模块[js文件]的对外接口[属性或方法],一个文件可以输出多个

export function output() {  }

import {output} from './example'

复制代码

export default 则是在 export 的基础上,为规定模块提供一个默认的对外接口。一个js文件只能输出一个。

export default function output() {  } 

import output from './example'

复制代码

vue 中使用export data return

export default{
    data(){
        return {
            showLogin:true,
            // def_act: '/A_VUE',
            msg: 'hello vue',
            user:'',
            homeContent: false,
        }
    },
    methods:{
       
    }
}
复制代码

不使用 return 包裹的数据会在项目的全局可见,会造成变量污染

使用 return 包裹后数据中变量只在当前组件中生效,不会影响其他组件。

Mock.js

Mock.js是一种前端工具,能够生成随机数据,拦截Ajax请求,使前后端独立开发,只要定义好接口就可以并行工作,互不影响。

Mock.mock()

Mock.mock()可根据数据模板生成模拟数据

Mock.mock( rurl, template )

记录数据模板。当拦截到匹配 rurl 的 Ajax 请求时,将根据数据模板 template 生成模拟数据,并作为响应数据返回。

rurl 可选。

表示需要拦截的 URL,可以是 URL 字符串或 URL 正则。例如 /\/domain\/list\.json/、'/domian/list.json'