Vue2

_______________________________________________________________________________________________

4、兄弟组件通信

兄弟组件的通信,借助于一个Vue的实例(eventBus 事件总线)作为一个中介,组件通过监听该实例去完成事件的绑定和触发(仅)

varbus= new Vue();          //新建一个Vue实例,并接收这个实例,当作事件总线

Vue.component("发送方组件",{

  methods:{

    handleClick: function(){

     bus.$emit('event自定义事件名','arg1','arg2'...)

   }         //触发当前实例上的事件,第二个参数是触发时附加的参数,会传给监听器回调

  },

  template: `<button @click="handleClick">触发事件,进行通信</button>`

})

Vue.component("接收方组件",{

  created:function(){              //放在'组件实例创建完成后'的函数中,可以自动接收

   bus.$on('event自定义事件名',function(arg1,arg2...){ }

  }            //绑定监听当前实例上的自定义事件,事件由.emit触发

                //第二个参数是触发事件成功的回调函数,会接收所有传入'事件触发函数'的额外参数

  template: `<div>接收通信</div>`

})

_______________________________________________________________________________________________

路由

使用 vueRouter 插件可以实现SPA

单文件: 在webpack环境下使用路由模块:  或者在项目初始化时提前设置自动安装

        var Vue=require('vue')

        var VueRouter=require('vue-router')

        Vue.use(VueRouter)

VueRouter

① 引入 vue-router.js 文件

② 指定容器

<div id="example">

  <router-view></router-view>        //指定组件插入的容器

</div>

③ 创建各个子组件

var Test01Component=Vue.component("test01",{    //组件定义在最上面,才能加载路由

  template:`<div>

  <h1>这是子组件test01</h1>

  </div>`

});

④ 配置路由地址(分为三段)

constmyRoutes= [        //① 配置路由地址: 创建一个对象数组,每个对象指定path/component

  { path:'/myPath1',component:Test01Component },

  { path:'/myPath2',component:Test01Component},

  { path: "/",component: Test01Component }        //没有path,只有一个/时跳转的地址

];

constmyRouter= new VueRouter({        //② 创建一个VueRouter的实例,并接收

  routes:myRoutes       //指定 routes 属性为配置的路由地址,与①可合为一个

});

new Vue({

  router:myRouter       //③ 在vue的实例中指定router属性为路由 VueRouter 的实例

          <=> new VueRouter({routes:myRoutes});    //但不建议这样写,跳转不便

})

跳转:

html的方式  <router-link to="/myPath1">跳转到myPath1</router-link>  //渲染出来是一个 a 标签

js的方式:

jump:function(){ myRouterVueRouter的实例.push("/myPath1"); }

<button @click="jump">跳转到myPath1</button>

传参:

① 明确发送方、接收方

② 配置接收方的路由地址path

  {path: "/myPath1/:arg",component:Test01Component }

③ 接收方取得传递过来的参数

  created:function(){

    this.resArgdata数据=this.$route.params.arg;

  }

④ 发送方发送参数

<router-link to='/myPath1/20'>    <router-link v-bind:to="'/myPath1/'+value"></router-link>

<a href='#/myPath1/20'></a>       <a v-bind:href="'#/myPath1/'+value"></a>

jump:function(){ myRouter.push('/myPath1/20'); }

jump:function(){ myRouter.push("/myPath1"+this.value); }    //通过'该组件的数据'传参

jump:function(key){ myRouter.push("/myPath1/"+key);}        //通过'方法传来的参数'传参

触发事件绑定的方法:  <any @click="jump(key)"><any>

嵌套路由:

var MyMail = Vue.component("mail",{

  template: `<div>

  <h1>这是邮箱主页面</h1>

  <router-link to="/inbox">收件箱</router-link>

  <router-link to="/outbox">发件箱</router-link>

  <router-view></router-view>                       //① 为子路由指定容器

  </div>`

  });

② 在配置路由地址时,为子路由指定path/component

constmyRoutes=[

  { path:'/myPath1',component:Test01Component },

 {path:"/myMail", component:MyMail, children:[

    { path:"/inbox",component:inBox },

    { path:"/outbox",component:outBox}] },

  { path: "/",component: Test01Component }

];

注意: 子路由的跳转链接不是必须加在父路由中。可以加在项目的任一页面,都可跳向子路由,同时也会显示其父路由的内容

_______________________________________________________________________________________________

三、网络请求(使用vue-resource或者axios插件)

① 引入vue-resource.js文件

Vue.component('test',{

  data: function(){

    return { List:[] }

  },

  methods:{

    loadData: function(){    //this.$http.get()第一个参数是请求的url,第二个参数是传递的参数

     this.$http.get('data/stu.json请求url',{"id":123})        //② 发起网络请求 get/post

       .then(function(response){                 //响应成功的回调函数,参数是返回的数据

          this.List = response.data;                //③ 对响应到的数据进行操作

     })

    }

  },

  template:`<div>

  <ul><li v-for="tmp in List">{{tmp.name}}</li></ul>        //将返回的数据显示在视图上

  <button @click="loadData">加载数据</button>               //绑定请求事件

  </div>`

})

axios(爱可西柚子)******************************************************************************

特色: ① 浏览器端发起XMLHttpRequests请求  ② node端发起http请求  ③ 支持Promise API

      ④ 监听请求和返回  ⑤ 转化请求和返回  ⑥ 取消请求  ⑦ 自动转化json数据  ⑧ 客户端支持抵御

安装使用:

npm:  npm install axios --save-dev

cdn:  <script src="https://unpkg.com/axios/dist/axios.min.js"></script>

src/main.js: 引入axios

import axios from 'axios'

Vue.prototype.$axios = axios

src/App.vue: 拦截器,在请求或者返回被then或catch处理之前对它们进行拦截

created(){

  var loading = null;

  this.$axios.interceptors.request.use(config => {    //发出请求之前进行拦截

    if(store.state.token){  //判断是否存在token,如果存在的话,则每个http header都加上token

      config.headers.Authorization = `token ${store.state.token}`;

    }

    loading = this.$loading({ text:'请求中...' });

    return config;

  }, err => {

    this.$message({ message:'请求接口失败...', type:'warning', duration: 1333 });

    return Promise.reject(err);

  })

  this.$axios.interceptors.response.use(res => {      //对返回的数据进行拦截

    loading.close();

    return res;

  }, err => {

    loading.close();

    if(err.response){

      switch (err.response.status) {

        case 401:

store.commit(types.LOGOUT);//返回401(未授权),清除token信息并跳转到登录页面

          router.replace({ path: 'login',

                           query: {redirect: router.currentRoute.fullPath}

          })

      }

    }

return Promise.reject(err);//返回接口返回的错误信息

  })

}

跨域请求:

config/index.js:

proxyTable:{

  '/api':{                           // '/api'文件中的匹配项

    target: 'http://erpserver.mgupiao.com',        //请求接口的地址

    secure: false,                                 //如果是https接口,需要配置此参数

    changeOrigin: true,                            //如果需要跨域,需要配置此参数

    pathRewrite:{ '^/api':'' }        // 因为在ajax的url中加了前缀 '/api'用于匹配,而原本的接口是没有这个前缀的,所以需要通过pathRewrite来重写地址,将前缀'/api'转为'/'

 },

  '/station': {

    target: 'http://erpserver.mgupiao.com',

    changeOrigin: true,

    pathRewrite: { '^/station': 'station' }

  }

},

axios的功能特性:

在浏览器中发送XMLHttpRequests请求

支持Promise API

拦截请求和响应

转换请求和响应数据

自动转换JSON数据

客户端支持保护安全免受XSRF攻击

请求方式:

var axios = this.$axios

axios(config)

axios.request(config)

axios.get(url[,config])

axios.delete(url[,config])

axios.head(url[,config])

axios.post(url[,data[,config]])

axios.put(url[,data[,config]])

axios.patch(url[,data[,config]])

get请求:

axios.get('/user',{param:{id:1}})        //可以取param参数

     .then(res=>{console.log(res)})

     .catch(err=>{console.log(err)})

post请求:

axios.post('/user',{id:2})               //会转换为json格式

     .then(res=>{console.log(res)})

     .catch(err=>{console.log(err)})

发送并发请求:

axios.all([axios.get('/profile'), axios.post('/user')])

     .then(axios.spread((res1,res2)=>{

       console.log(res1); console.log(res2);

     }

))

*.vue单文件************************************************************************************

每一个*.vue文件都是组件使用大驼峰命名法

每个组件分为3个部分: <template></template>、<script></script>、<style></style>

template中只能有一个根标签

*.vue中的data是一个方法,该方法需要返回一个对象,在对象中初始化数据

<template>

  <divclass="hello">        //只能有一个根标签(如div/section)

    <head-top></head-top>    //③ 使用组件

    ...

  </div>

</template>

<script>

  import headTop from './Header'        //① 引入组件

  export default{

    name: 'SelectBall',      //导出组件名

    data () {

      return {}

    },

    components: {            //② 注册组件(使用components属性)

      headTop                //headTop: ES6的简写,相当于ES5: headTop:headTop

    }

  }

</script>

<style lang="less" type="text/less" scoped>    //若不写type="text/less",WebStorm可能会报错

              //scoped: 使style中的样式(如less)只作用于当前组件(若不写,则样式会作用于全局)

  @import 'other.less';        //导入的也遵守此规则

  .tilte{

    font-size: 1.2rem;

  }

</style>

src/router/index.js:  每一个*.vue文件都需要在此文件中引入才能使用(配置路由)

import Vue from 'vue'

import Router from 'vue-router'

import HelloWorld from '@/components/HelloWorld'    //引入组件

                                        //@: 在build/webpack.base.conf.js中的alias配置的别名

Vue.use(Router)                         //使用路由

constrouter= new Router({

  mode:'history',        //配置此参数后,路径不会带#(可使用pushState/replaceState来管理记录)

                         //否则需要在跳转地址前加 /#

  routes: [{path: '/helloWorld',            //配置路由地址

             name: 'helloWorld',             //name和path使用小驼峰命名法

             component: HelloWorld,

             children:[{ path:"/inbox",component:InBox },

                         { path:"/outbox",component:OutBox}]},

           {path: '/xiaoliang',

             name: 'xiaoliang',

             component: Xiaoliang,

             meta: {

               title: '标题',

               requireAuth: true,    //自定义字段,表示进入这个路由需要登录

             }, }]

})

利用vue-router提供的钩子函数beforeEach对路由进行判断,进行登录验证、修改title等操作

router.beforeEach((to, from, next) => {

  if(to.meta.requireAuth){        //判断该路由是否需要登录权限

    if(store.state.token){        //通过vuex state获取当前的token是否存在

      next();

    }else{

      next({ path: '/login',

             query: {redirect: to.fullPath} //将跳转的路由path作为参数,登录成功后跳回该路由

      })

    }

  }else{ next(); }

  if(to.meta.title){

    document.title = to.meta.title;    //设置网页标题

  }

  next();

})

export default router

跳转: 使用路由跳转,可跳到子组件或兄弟组件

注意:

① 若不在域名的根目录下时,需要在routes中的每个路由下添加 /目录名

② 应使用<router-link to="/home">Home</router-link>跳转,若用a跳转则会刷新页面

③ 若使用mode: 'history',应将服务期所有404页面重定向回index.html,使用前端路由跳转

   如nginx: error_page  404        /index.html;

④ 因为所有的404都会重定向到index.html,所以可以在Vue应用里覆盖所有的路由,给出一个404页面

   { path: '*', component: NotFoundComponent }

⑤ 在IE中,页面大小<1024b会被认为不友好,会将该页面替换成自己的错误提示页面,所以应避免index.html小于1024b

⑥ 登录应做双重判定,首先应由前端路由控制(router.beforeEach),为确保token失效后确保无法访问需要登录的页面,应使用http拦截器+后台接口返回的http状态码来判断(axios拦截器)

vue技巧*****************************************************************************************

路由动画效果:

src/App.Vue:

<div id="app">

  <transition :name="transitionName">

    <router-view class="child-view"></router-view>

  </transition>

</div>

export default {

  name: 'App',

  data(){

    return {

      transitionName: 'slide-left'

    }

  },

  watch: {

'$route'(to, from){//监听路由的路径,可以通过不同的路径去选择不同的切换效果

      const toDepth = to.path.split('/').length;

      const fromDepth = from.path.split('/').length;

      this.transitionName = toDepth < fromDepth ? 'slide-right' : 'slide-left';

    }

  }

}

#app,.child-view{        //防止切换路由时出现滚动条

  position: absolute;

  top: 0;

  left: 0;

  right: 0;

  bottom: 0;

}

#app{

  overflow-x: hidden;

}

.child-view{

  transition: all .8s cubic-bezier(.55, 0, .1, 1);

}

.slide-left-enter, .slide-right-leave-active{

  opacity: 0;

  -webkit-transform: translate(100%, 0);

  transform: translate(100%, 0);

}

.slide-left-leave-active, .slide-right-enter{

  opacity: 0;

  -webkit-transform: translate(-100%, 0);

  transform: translate(-100%, 0);

}

配置资源路径:

方法①

config/index.js:

assetsPublicPath:'/',             //可发布到网络上,资源使用的是根路径

assetsPublicPath: '/dist/',       //在dist中创建一个WebStorm项目即可查看(根路径)

assetsPublicPath:'',              //输出相对路径,不用服务器也能打开(引用直接写的文件名)

assetsPublicPath:'./',            //输出相对路径,不用服务器也能打开(引用写的./文件名)

方法②

build/webpack.prod.conf.js:

output: { publicPath:'./', },      //添加此语句,调试打包时,都输出相对路径(引用使用./文件名)

基于vue的ui库***********************************************************************************

PC端:

① element      饿了么前端出品的基于Vue 2.0的桌面端组件库

   https://github.com/ElemeFE/element                 //github仓库地址

② iview        基于Vuejs的开源UI组件库

   https://github.com/iview/iview                     //github仓库地址

③ muse-ui      三端样式一致的响应式UI库

   https://github.com/museui/muse-ui                  //github仓库地址

移动端:

① Vux          基于Vue和微信官方WeUI的组件库

   https://github.com/airyland/vux                    //github仓库地址

② mint-ui      饿了么前端推出的基于Vue.js的移动端组件库

   https://github.com/ElemeFE/mint-ui                 //github仓库地址

   http://elemefe.github.io/mint-ui/#/                //demo地址

③ vue-material 基于Vue Material和Vue 2精美的app应用(英文文档)

   https://github.com/marcosmoura/vue-material        //github仓库地址

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,542评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,596评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,021评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,682评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,792评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,985评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,107评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,845评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,299评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,612评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,747评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,441评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,072评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,828评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,069评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,545评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,658评论 2 350

推荐阅读更多精彩内容