vue bus

vue Bus总线

有时候两个组件也需要通信(非父子关系)。当然Vue2.0提供了Vuex,但在简单的场景下,可以使用一个空的Vue实例作为中央事件总线。

参考:http://blog.csdn.net/u013034014/article/details/54574989?locationNum=2&fps=1

例子:https://segmentfault.com/q/1010000007491994

<divid="app">
<c1></c1>
<c2></c2>
</div>
var Bus = new Vue(); //为了方便将Bus(空vue)定义在一个组件中,在实际的运用中一般会新建一Bus.js
Vue.component('c1', { //这里已全局组件为例,同样,单文件组件和局部组件也同样适用
    template: '<div>{{msg}}</div>',
    data: () = >({
        msg: 'Hello World!'
    }),
    created() {
        Bus.$on('setMsg', content = >{
            this.msg = content;
        });
    }
});
Vue.component('c2', {
    template: '<button @click="sendEvent">Say Hi</button>',
    methods: {
        sendEvent() {
            Bus.$emit('setMsg', 'Hi Vue!');
        }
    }
});
varapp = newVue({
    el: '#app'
})

在实际运用中,一般将Bus抽离出来:Bus.js

import Vue from 'vue'
const Bus=newVue()
exportdefaultBus

组件调用时先引入

组件1

import Bus from './Bus'
exportdefault {
    data() {
        return {.........
        }
    },
    methods: {....Bus.$emit('log', 120)
    },
}

组件2

import Bus from './Bus'
exportdefault {
    data() {
        return {.........
        }
    },
    mounted() {
        Bus.$on('log', content = >{
            console.log(content)
        });
    }
}

但这种引入方式,经过webpack打包后可能会出现Bus局部作用域的情况,即引用的是两个不同的Bus,导致不能正常通信 

实际运用二(推荐):

当然也可以直接将Bus注入到Vue根对象中,

import Vue from 'vue'const Bus = newVue() varapp = newVue({
    el: '#app',
      data: {    Bus
    }  
})

在子组件中通过this.$root.Bus.$on(),this.$root.Bus.$emit()来调用

Vue2.0的三种常用传值方式、父传子、子传父、非父子组件传值

这里写图片描述

  1.  父组件向子组件传值

    父组件

    <template>
      <div>
        父组件:    <input type="text" v-model="name">
        <br>
        <br>
        <!-- 引入子组件 -->
        <child :inputName="name"></child>
      </div></template><script>
      import child from './child'
      export default {
        components: {
          child
        },
        data () {      return {
            name: ''
          }
        }
      }</script>

    子组件

    <template>
      <div>
        子组件:    <span>{{inputName}}</span>
      </div></template><script>
      export default {    // 接受父组件的值
        props: {
          inputName: String,
          required: true
        }
      }</script>

  2.  子组件向父组件传值

    子组件

    <template>
      <div>
        子组件:    <span>{{childValue}}</span>
        <!-- 定义一个子组件传值的方法 -->
        <input type="button" value="点击触发" @click="childClick">
      </div></template><script>
      export default {
        data () {      return {
            childValue: '我是子组件的数据'
          }
        },
        methods: {
          childClick () {        // childByValue是在父组件on监听的方法
            // 第二个参数this.childValue是需要传的值
            this.$emit('childByValue', this.childValue)
          }
        }
      }</script>

    父组件

    <template>
      <div>
        父组件:    <span>{{name}}</span>
        <br>
        <br>
        <!-- 引入子组件 定义一个on的方法监听子组件的状态-->
        <child v-on:childByValue="childByValue"></child>
      </div></template><script>
      import child from './child'
      export default {
        components: {
          child
        },
        data () {      return {
            name: ''
          }
        },
        methods: {
          childByValue: function (childValue) {
            // childValue就是子组件传过来的值
            this.name = childValue
          }
        }
      }</script>

     

  3.  非父子组件进行传值

    公共bus.js

    //bus.jsimport 
    Vue from 'vue'
    export default new Vue()

    组件A

    <template>
      <div>
        A组件:    <span>{{elementValue}}</span>
        <input type="button" value="点击触发" @click="elementByValue">
      </div></template><script>
      // 引入公共的bug,来做为中间传达的工具
      import Bus from './bus.js'
      export default {
        data () {      return {
            elementValue: 4
          }
        },
        methods: {
          elementByValue: function () {
            Bus.$emit('val', this.elementValue)
          }
        }
      }</script>

    组件B

    <template>
      <div>
        B组件:    <input type="button" value="点击触发" @click="getData">
        <span>{{name}}</span>
      </div></template><script>
      import Bus from './bus.js'
      export default {
        data () {      return {
            name: 0
          }
        },
        mounted: function () {
          var vm = this
          // 用$on事件来接收参数
          Bus.$on('val', (data) => {
            console.log(data)
            vm.name = data
          })
        },
        methods: {
          getData: function () {
            this.name++
          }
        }
      }</script>

     

superagent post数据获取2次请求 & php如何接受AJAX POST跨域的request payload形式的参数

superagent 使用post的时候会有2次请求

一次请求的类型是OPTIONS

另一种是POST

开始的时候我如何都接受不到post过来的数据

后来仔细核对了浏览器里的信息发现传输数据的方式不是以前的form data而是request payload

然后就上网找如何处理request payload类型的数据

最终像下面这样解决

header('Access-Control-Allow-Origin: *');
        header('Access-Control-Allow-Methods: GET,HEAD,PUT,PATCH,POST,DELETE');

        if($_SERVER['REQUEST_METHOD'] == 'OPTIONS'){
            header('HTTP/1.1 204 No Content');
            header('Server: Cowboy');
            header('Content-Length: 0');
            header('Connection: keep-alive');
            header('Vary: Access-Control-Request-Headers');
            header('Access-Control-Allow-Headers: content-type');
            header('Date: Fri, 19 Jan 2018 07:57:49 GMT');
            header('Via: 1.1 vegur');
        }else if($_SERVER['REQUEST_METHOD'] == 'POST'){
            $request_body = file_get_contents('php://input');
            $data = json_decode($request_body);

            echo json_encode($result);
        }

Promise 对象

http://wiki.jikexueyuan.com/project/es6/promise.html

基本用法

ES6 原生提供了 Promise 对象。所谓 Promise 对象,就是代表了某个未来才会知道结果的事件(通常是一个异步操作),并且这个事件提供统一的 API,可供进一步处理。

有了 Promise 对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。此外,Promise 对象提供的接口,使得控制异步操作更加容易。Promise 对象的概念的详细解释,请参考<a rel="nofollow" href="http://javascript.ruanyifeng.com/" "="" style="box-sizing: border-box; padding: 0px; margin: 0px; background-color: transparent; color: rgb(45, 133, 202); text-decoration-line: none;">《JavaScript标准参考教程》。

ES6 的 Promise 对象是一个构造函数,用来生成 Promise 实例。

var promise = new Promise(function(resolve, reject) {
  if (/* 异步操作成功 */){
    resolve(value);
  } else {
    reject(error);
  }
});

promise.then(function(value) {
  // success
}, function(value) {
  // failure
});

上面代码中,Promise 构造函数接受一个函数作为参数,该函数的两个参数分别是 resolve 方法和 reject 方法。如果异步操作成功,则用 resolve 方法将 Promise 对象的状态,从“未完成”变为“成功”(即从 pending 变为 resolved);如果异步操作失败,则用 reject 方法将 Promise 对象的状态,从“未完成”变为“失败”(即从 pending 变为 rejected)。

Promise 实例生成以后,可以用 then 方法分别指定 resolve 方法和 reject 方法的回调函数。

下面是一个使用 Promise 对象的简单例子。

function timeout(ms) {
  return new Promise((resolve) => {
    setTimeout(resolve, ms);
  });
}

timeout(100).then(() => {
  console.log('done');
});

……

vue 登录存localStorage

先补充下localStorage 知识点:

JS对象

读取形式:

localStorage.name

添加/修改

localStorage.name = "xuanyuan"

其中"xuanyuan"只能是字符串形式(目前为止只支持字符串)。所以存储时是JSON对象时需要执行下JSON.stringify,所以获取时需要执行下JSON.parse

删除

detele localStorage.name

API

获取键值对数量

localStorage.length

读取

localStorage.getItem('name'), localStorage.key(i)

添加/修改

localStorage.setItem('name','xuanyuan')

删除对应键值

localStorage.removeItem('name')

删除所有数据

localStorage.clear()

顺便说下,localStorage有效期是永久的。一般的浏览器能存储的是5MB左右。sessionStorage api与localStorage相同。

sessionStorage默认的有效期是浏览器的会话时间(也就是说标签页关闭后就消失了)。

localStorage作用域是协议、主机名、端口。(理论上,不人为的删除,一直存在设备中)

sessionStorage作用域是窗口、协议、主机名、端口。

知道了这些知识点后,你的问题就很好解决了。

localStorage是window上的。所以不需要写this.localStorage,你这里的this,是指vue实例。

方案一、

// 这里写的答案是指data.body.data是JSON。不是JSON则不需要JSON.parse和JSON.stringify

存储:localStorage.data = JSON.stringify(data.body.data);

获取:JSON.parse(localStorage.data);

方案二、

存储:localStorage.setItem('data',JSON.stringify(data.body.data));

获取:JSON.parse(localStorage.getItem('data'));

vue中 关于$emit的用法

1、父组件可以使用 props 把数据传给子组件。

2、子组件可以使用 $emit 触发父组件的自定义事件。

vm.$emit( event, arg ) //触发当前实例上的事件

vm.$on( event, fn );//监听event事件后运行 fn; 

例如:子组件:

<template>  
  <div class="train-city">  
    <span @click='select(`大连`)'>大连</span>  
  </div>  
</template>  
<script>  
export default {  
  name:'trainCity',  
  methods:{  
    select(val) {  
      let data = {  
        cityname: val  
      };  
      this.$emit('showCityName',data);//select事件触发后,自动触发showCityName事件  
    }  
  }  
}  
</script>

父组件:

<template>  
    <trainCity @showCityName="updateCity" :index="goOrtoCity"></trainCity> //监听子组件的showCityName事件。  
<template>  
<script>  
export default {  
  name:'index',  
  data () {  
   return {  
      toCity:"北京"  
    }  
  }  
  methods:{  
    updateCity(data){//触发子组件城市选择-选择城市的事件    
      this.toCity = data.cityname;//改变了父组件的值  
      console.log('toCity:'+this.toCity)        
    }  
  }  
}  
</script>

结果为:toCity: 大连