美文网首页
11. vue-­router路由和vuex

11. vue-­router路由和vuex

作者: sweetBoy_9126 | 来源:发表于2018-10-14 23:21 被阅读55次

    11.1 vue-­router路由基本加载

    小案例:在根路径下只显示图片,在/hello下即显示图片又显示helloWorld组件里的内容
    简单四步走

    1. 安装
    npm install --save vue-router
    
    1. 引用(在你的main.js里)
    import router from 'vue-router'
    Vue.use(router)
    
    1. 配置路由文件,并在vue实例中注入(也是在main.js)
    var rt = new router({
      routes: [
        {
          path: '/hello',
          component: HelloWorld
        }
      ]
    })
    new Vue({
      el: '#app',
      router: rt,
      components: { App },
      template: '<App/>'
    })
    

    这里要注意的是如果你是在index.html之外的页面里使用vue-router,那么你路径设置为path='/'就是以你当前的html页面为根目录,比如在一个member.html里使用<router-view></router-view>,然后你在它的js里写path='/',比如你用的是本地端口,那么就是在localhost:8080/member.html/下使用组件,而不是localhost:8080/,也就是把你的member.html作为首页了,而正常情况下的/根目录其实就是你的首页,因为localhost:8080/index.html,因为index是可以省略的

    1. 确定视图加载的位置(在App.vue中)
      使用
    <router-view></router-view>
    

    如:

    <template>
      <div id="app">
        <img src="./assets/logo.png">
        <!--也就是说当路径等于/hello的时候下面的<router-view>就会替换成HelloWorld组件里的内容-->
        <router-view></router-view>
      </div>
    </template>
    

    这就是让它在图片下方显示

    11.2 vue-­router路由的跳转

    1. 通过给需要跳转的元素加<router-link to="/"></router-link>点击跳转到指定的路径
      list.vue
    <template>
        <ul>
            <li>
                <router-link to="/helloWorld">hello world</router-link>
            </li>
            <li>
                <router-link to="/helloMeizi">hello meizi</router-link>
            </li>
        </ul>
    </template>
    

    router目录下的index.js

    export default new router({
        routes: [
          {
            path: '/helloWorld',
            component: HelloWorld
          },
          {
              path: '/helloMeizi',
              component: HelloMeizi
          }
        ]
      })
    

    通过上面的代码我们点击hello world就会跳转到/helloWorld路径下,同样点击/helloMeizi也是一个道理

    1. 编程式的导航
      router.push(location, onComplete?, onAbort?)
      注意:在 Vue 实例内部,你可以通过$router 访问路由实例。因此你可以调用this.$router.push
      当你点击 <router-link> 时,这个方法会在内部调用,所以说,点击 <router-link :to="..."> 等同于调用 router.push(...)。
      该方法的参数可以是一个字符串路径,或者一个描述地址的对象。例如:
    // 字符串
    router.push('home')
    
    // 对象
    router.push({ path: 'home' })
    
    // 命名的路由
    router.push({ name: 'user', params: { userId: 123 }})
    
    // 带查询参数,变成 /register?plan=private
    router.push({ path: 'register', query: { plan: 'private' }})
    

    注意:如果提供了 path,params 会被忽略,上述例子中的 query 并不属于这种情况。取而代之的是下面例子的做法,你需要提供路由的 name 或手写完整的带有参数的 path:

    const userId = 123
    router.push({ name: 'user', params: { userId }}) // -> /user/123
    router.push({ path: `/user/${userId}` }) // -> /user/123
    // 这里的 params 不生效
    router.push({ path: '/user', params: { userId }}) // -> /user
    

    同样的规则也适用于 router-link 组件的 to 属性。

    11.3 vue­-router路由参数的传递

    1. 必须在路由内加入路由的name
    2. 必须在path后加/: +传递的参数
    export default new router({
        routes: [
          {
            name: 'helloWorld',
            path: '/helloWorld/:worldmsg',
            component: HelloWorld
          },
          {
            name: 'helloMeizi',
            path: '/helloMeizi/:meizimsg',
            component: HelloMeizi
          }
        ]
      })
    

    传递参数和接收参数看下边代码

    <!--方式1 推荐-->
    <ul>
        <li>
            <router-link :to="{name: 'helloWorld',params:{worldmsg:'你好世界'}}">hello world</router-link>
            读取参数在HelloWorld组件中通过:$route.params.XXX
            这种方式显示的路径为:/helloWorld/你好世界
      
        </li>
        <li>
            <router-link :to="{name: 'helloMeizi',params:{meizimsg:'你好妹子'}}">hello meizi</router-link>
        </li>
    </ul>
    
    <!--方式2 不推荐-->
    <router-link :to="{path: '/helloWorld',query:{worldmsg:你好世界}}">
     hello world
    </router-link>
    显示的路径为:/helloWorld?name=XX&count=xxx
    函数模式
    
    你可以创建一个函数返回 props。这样你便可以将参数转换成另一种类型,将静态值与基于路由的值结合等等。
    
    <template>
      {{q}} //比如当前是/search?q=5,那么此时就能拿到这个5
    </template>
    const router = new VueRouter({
      routes: [
        { path: '/search', component: SearchUser, props: (route) => ({
    q: route.query.q }) }
      ]
    })
    然后在组件中
    props:['q']
    

    11.4 嵌套路由

    let rt = new router({
        routes: [
            {
                path: '/',
                component: member,
            },
            {
                path: '/address',
                component: address,
                children: [
                    {
                        // /address/all路径下显示all组件
                        path: 'all',
                        component: all
                    },
                    {
                        // /address/form路径下显示form组件
                        path: 'form',
                        component: form
                    }
                ]
            },
        ]
    })
    

    上面代码当路径跳转到/address/all和/address/form的时候,分别显示嵌套的子路由组件all和form



    那如果想要在/address路径下显示嵌套的子路由组件该怎么做?

    1. 给子路由一个空路径
    {
      path: '/address',
      component: address,
      children: [
          {
              //在/address路径下显示嵌套路由组件all
              path: '',
              component: all
          },
      ]
    },
    
    1. 通过重定向实现路由跳转
    {
      path: '/address',
      component: address,
      children: [
          {
             //从路径''跳转到all,也就是从/address/ 跳转到 /address/all
              path: '',
              redirect: 'all'
          }
      ]
    },
    

    11.5.1 Axios之get请求详解

    axios的简介:

    axios 是一个基于Promise 用于浏览器和 nodejs 的 HTTP 客户端,它本身具有以下特征:

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

    1. 安装
    npm install axios
    
    1. 引入加载
    import axios from 'axios'
    
    1. 将axios全局挂载到VUE原型上
    Vue.prototype.$http = axios;//这里的$http随便什么名字都可以
    
    1. 发出请求 以cnode社区API为例子
    <template>
      <div class="hello">
        <button @click="getDate">点击获取数据</button>
        <ul>
          <li v-for="item in items">{{item.title}}</li>
        </ul>
      </div>
    </template>
    
    <script>
    import axios from 'axios'
    Vue.prototype.$http = axios
    import Vue from 'vue'
    export default {
      name: 'HelloWorld',
      data () {
        return {
          items: []
        }
      },
      methods: {
        getDate(){
          this.$http.get('https://cnodejs.org/api/v1/topics',
            {
              params: {
                page:1,
                limit: 10
              }
            }
          )
          .then(
            (response)=>{
              this.items = response.data.data
            },
            (err)=>{
              console.log(err)
            }
          )
        }
      }
    }
    </script>
    

    两种传递参数的形式

    axios.get('/user', {
      params: {
        ID: 12345
      }
    })
    axios.get('/user', {
      ID: 12345
    })
    ---------------------------------
    axios.get('https://cnodejs.org/api/v1/topics?page=1&limit=15')
    

    使用CNODE社区官方的API为例展开学习
    获取主题列表API:https://cnodejs.org/api/v1/topics
    参数:page页码
    limit 每页显示的数量

    11.5.2 Axios之post请求详解

    POST传递数据有两种格式:

    • form­data ?page=1&limit=48
    • x­www­form­urlencoded { page: 1,limit: 10 }

    在axios中,post请求接收的参数必须是form­data
    使用qs插件—­qs.stringify
    npm i qs

    getDate(){
      this.$http.post(url,qs.stringify({
        page: 1,
        limit: 10
      })) 
      .then(
        (response)=>{
          this.items = response.data.data
        },
        (err)=>{
          console.log(err)
        }
      )
    }
    

    11.6 Vuex之store

    用来管理状态,共享数据,在各个组件之间管理外部状态
    如何使用?
    第一步:在main.js中全局引入vuex,并通过use方法使用它

    import Vuex from 'vuex'
    Vue.use(Vuex)
    

    第二步: 创建状态仓库(注意必须是Store,state不能改成别的名字),在实例中使用它

    var store = new Vuex.Store({
      state: {
        //这里面是你要共享的数据,在所有组件中都可以访问的
        message: 88
      }
    })
    
    new Vue({
      el: '#app',
      router,
      store, //就相当于store: store
      components: { App },
      template: '<App/>'
    })
    

    第三步:通过this.$sore.state.XXX直接拿到需要的数据

    这里通过组件中的计算属性来获取
    {{getMessage}}  
    computed: {
            getMessage(){
                return this.$store.state.message
            }
     }
    

    11.7 Vuex的相关操作

    vuex状态管理的流程
    view———­>actions———–>mutations—–>state————­>view

    在组件中改变全局中的状态

    1.通过mutations,里面定义的方法必须传入state
    var store = new Vuex.Store({
      state: {
        message: 88
      },
      mutations: {
        getAdd(state){
          return state.message+=1
        },
        getmul(state){
          return state.message-=20
        }
      }
    }
    
    然后在组件中使用
    <button @click="sadd">子组件---通过mutations改变全局状态</button> 
    methods: {
        sadd(){
            //此处的getAdd是你在mucations中定义的方法名
            return this.$store.commit('getAdd')
        }
    }
    
    2.通过actions修改状态,actions里面要传入context上下文对象
    var store = new Vuex.Store({
      state: {
        message: 88
      },
      mutations: {
        getmul(state){
          return state.message-=20
        }
      },
      actions: {
        a(context){
          context.commit('getmul')
        }
      }
    }
    
    在组件中使用
    <button @click="c">子组件---通过actions改变全局状态</button>
    methods: {
        c(){
            return this.$store.dispatch('a')
        }
    }
    

    通过getters可以对你全局状态中的数据做限制,比如让它操作点击按钮累减的时候值不能小于零

    var store = new Vuex.Store({
      state: {
        message: 88
      },
      getters: {
        e(state){
          return state.message>0 ? state.message : 0
        }
      }
    })
    
    在组件中使用
    {{getMessage}}
    computed: {
        getMessage(){
            return this.$store.state.message
        }
    }
    

    注意:actions提交的是mutation,而不是直接变更状态
    actions可以包含异步操作,但是mutation只能包含同步操作

    actions: {
      a(context){
        setTimeout(()=>{
          context.commit('getmul')
        },2000)
      }
    }
    

    最后在你的src文件下新建一个state文件,里面一个index.js将你所有的状态相关的代码写在这里面,然后导出,在main.js里面引入一下

    相关文章

      网友评论

          本文标题:11. vue-­router路由和vuex

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