Vue2

作者: fastwe | 来源:发表于2018-11-26 22:05 被阅读0次

    _______________________________________________________________________________________________

    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仓库地址

    相关文章

      网友评论

          本文标题:Vue2

          本文链接:https://www.haomeiwen.com/subject/yypbqqtx.html