day80 路由、仓库、前后台交互、跨域问题、Vue操作cookie

一、路由文件:router.js  <router-link>详解

  前台路由: 页面组件与路径对应的关系【类比后台中路由与view函数的对应关系】

import Vue from 'vue'          # 因为router 依赖于Vue
import Router from 'vue-router'

import Home from './views/Home.vue'   # 组件取别名,
import User from './views/User'
Vue.use(Router);

export default new Router({
    mode: 'history',
    base: process.env.BASE_URL,
 routes: [
        {
            path: '/',    # http://localhost:8080/ 前缀由base补充了
            name: 'home',
            component: Home  # 组件页面
        },
        {
            path: '/about',
            name: 'about',
            // route level code-splitting
            // this generates a separate chunk (about.[hash].js) for this route
            // which is lazy-loaded when the route is visited.
            component: () => import(/* webpackChunkName: "about" */ './views/About.vue')
        }
    ]
})
View Code

 

   1.  App.js之router-link中的to跳转,to不写具体路径就会默认跳转到当前页面,点了哪个页面就在哪个页面,相当于给自身再发送一次请求

     <router-link to >主页</router-link>

   2.  路由的name使用:【需绑定to属性,大括号中为key,value形式】

               <router-link :to="{name: 'home'}" >主页</router-link>

  注:router-link与系统a标签的区别

    router-link: 会被vue渲染成a标签,但是点击这样的a标签不能发生页面的转跳,只会出现组件的替换

    a: 也可以完成同样的效果,但是会发生页面的转跳

 

    Link与a标签的区别,Link是组件的替换,而a 标签是页面的跳转【自我刷新效率是底的,Link是从缓存中获取数据】

 

  3. 路由重定向:

    routes: [
      {
    path: '/',
    name: 'home',
     component: Home
       },
    {
    path: '/home',
     redirect:'/', ==> 路由重定向
        }]

  4. 路由参数

   1). 获取url后面的参数【this.$route】:       http://localhost:8080/course/detail/1

             let index = this.$route.params.id

        if (index < 0 || index >= course_detail_list.length) index =0;
        this.crx = course_detail_list[index]

      router.js文件配置

      routes: [
        {path: '/course/detail/:id',
      name: 'course-datail',
    component: CourseDatail
           },
        ]

    Course.vue  

        <router-link :to="'/course/detail/'+ course.id " >{{course.title}}</router-link>

    注:url后冒号:放在params: {} 中

   2). 获取url? 面的参数

   路由:router.js     

    {
       path: '/course/detail',
       name: 'course-datail',
      component: CourseDatail
     },

  跳转页面:
    <!--<router-link :to="'/course/detail/' + course.id" >{{course.title}}</router-link>-->
    <router-link :to="'/course/detail?id=' + course.id" >{{course.title}}</router-link>

  渲染页面: 

    //管理数据[url后面冒号的参数]
    // console.log(this.$route);
    // let index = this.$route.params.id;
    // // console.log(index);
    // if (index < 0 || index >= course_detail_list.length) index =0;
    // this.crx = course_detail_list[index]


    console.log(this.$route);
    let index = this.$route.query.id;
    // console.log(index);
    if (index < 0 || index >= course_detail_list.length) index =0;
    this.crx = course_detail_list[index]

  注:?号后的参数放在query: {id: "1"}

 

    3). 逻辑转跳:router.js不写冒号参数接收,跳转页面绑定事件,添加path或name及参数

   

   router.js页面:

   {
   path: '/course/detail',
   name: 'course-datail',
   component: CourseDatail
  },


  跳转页面:
    <li v-for="course in courses" :key="course.title" @click="toDetail(course.id)">
  methods:{
   toDetail (id){
方式一,给path
// this.$router.push({path:'/course/detail?id=' + id})

方式二:push给name[渲染页course-datail是从params拿的]
// this.$router.push({
// name:'course-datail',
// params:{
// id:id
// }
//
// })

方式三:push给name [渲染页面course-datail是从query拿的]
this.$router.push({
name: 'course-datail',
query:{
id:id
}
})
}
}

   

  渲染页面:

 created (){
 console.log('详情页面被渲染了');
//router管理路径
// console.log(this.$router);

//管理数据[url后面冒号的参数]
// console.log(this.$route);
// let index = this.$route.params.id;
// // console.log(index);
// if (index < 0 || index >= course_detail_list.length) index =0;
// this.crx = course_detail_list[index]


console.log(this.$route);
let index = this.$route.query.id;
// console.log(index);
if (index < 0 || index >= course_detail_list.length) index =0;
this.crx = course_detail_list[index]
this.&router方法:
this.$router.go(-1)   ==>   A 页面  ==>  B 页面  ==>点击C页面的时候直接跳转到 A页面

this.$router.replace() ===> A 页面 ==> B 页面 ==>点击C页面, 点击<--返回的时候直接跳转到 A页面
this.$router.replace({
name: 'course-datail',
query:{
id:id
}
})

二、仓库:全局的单例

  1)数据:子子组件点击事件提交新值给store.js中 mutations的特定函数UpdateTitle
    methods:{
     btnchange (){
  this.$store.commit('UpdateTitle', this.val)
    }

    或者:自己监听
    watch:{
  val (){
this.$store.commit('updateTitle', this.val)
  }
    }
 
  2)仓库: UpdateTitle接收新值,更新数据
  //全局可以访问的变量  -- 获取值 
  state: {
      title:"123"
        },
  //全局可以访问的方法 --- 修改值
    mutations: {
       UpdateTitle (state, new_val){
       state.title = new_val
     }
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex);

export default new Vuex.Store({
    // 全局可以访问的变量 - 获取值
    // 组件内:this.$store.state.title
    state: {
        title: '主页'
    },
    // 全局可以访问的方法 - 修改值
    // 组件内:this.$store.commit('updateTitle', '新值')
    mutations: {
        updateTitle (state, newValue) {
            state.title = newValue
        }
    },
    actions: {}
})
View Code

 


  3) 父组件: 监听stor数据并渲染新值  
    computed:{
     title (){
   return this.$store.state.title
     }
       },
例子代码:
  MainSubSub
<template>
    <div>
        <input type="text" v-model="val">
        <button @click="btnchange">修改</button>
    </div>
</template>

<script>
    export default {
        name: "MainSubSub",
        data (){
            return{
                val:""
            }
        },
        methods:{
            btnchange (){
                this.$store.commit('UpdateTitle', this.val)
            }
        },
         watch:{
                val (){
                    this.$store.commit('updateTitle', this.val)
                }
            }
    }
</script>

<style scoped>

</style>
View Code
 

    store.js

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    title:"123"
  },
  mutations: {
    UpdateTitle (state, new_val){
     state.title = new_val
    }
  },
  actions: {

  }
})
View Code

     Main.vue

<template>
    <div class="main">
        {{ title}}
        <MainSub></MainSub>
    </div>
</template>

<script>
    import MainSub  from '../components/MainSub'
    export default {
        name: "Main",
        data (){
            return {
                // title:this.$store.state.title
            }
        },

        components:{
            MainSub,
        },
      computed:{
            title (){
                return this.$store.state.title
            }
        },

    }
</script>

<style scoped>
    .main a{
        font-size: 100px;
        color: #f00;
    }
</style>
View Code

 

三、前后台交互
 1.安装
   cd 项目目录
   cnpm install axios

  2.配置main.js
    ajax - vue的axios
   
   import Axios from 'axios'
   Vue.prototype.$axios = Axios 【this后面的名字通常加一个$符】

   Vue.prototype原型,给它赋值的变量,在任何地方通过this.都可以点出来
   首先Vue创建的对象就是一个个的实例,this就是全局的,任何地方都通过this可以获取到这个属性


  3. axios发送get请求
  this.$axios({
url: 'http://localhost:8000/test/data/',
method:"get",
}).then((response) => {
console.log(response.data)
})
  }
  4. axios发送post请求
  
  this.$axios({
url: 'http://localhost:8000/test/data/',
method:"post",
}).then((response) => {
console.log(response.data)
})
  }
简写:
  this.$axios.get('http://localhost:8000/test/data/').then((response) => {
  console.log(response.data)
  });
  
  this.$axios.post('http://localhost:8000/test/data/').then((response) => {
   console.log(response.data)
  })
5. axios携带带参数发送请求
this.$axios.get('http://localhost:8000/test/data/', {
params:{
username:'owen',
pwd:'123'
}
}).then((response) => {
console.log(response.data)
});


注:post不能像get一样发送数据,在后端我们服务端要求Content-Tyoe:‘application/x-www-form-urlencoded’
  而axios帮我们做了一个stringify的处理,默认会把json放到请求体中提交到后端的。


this.$axios.post('http://localhost:8000/test/data/',"username='admin'&pwd='000'").then((response) => {
console.log(response.data)
})

post请求中如果是放在{}中,后端收到数据后默认放在body中
this.$axios.post('http://localhost:8000/test/data/',{
username:"admin",
pwd:"123"
}).then((response) => {
console.log(response.data)
})

后端: print('body', request.body)  =>body b'{"username":"admin","pwd":"123"}'

四、跨域问题(同源策略):Access-Control-Allow-Origin =>CORS
  前提:前台向后台请求数据
  1)服务器不一致 --- ip
  2) 应用不一致 --- 端口
  3)协议不一致 -- http <--> https
  
 
 django解决跨域

    1)安装django-cors-headers模块


    2)在settings.py中配置
      # 注册app
      INSTALLED_APPS = [
      ...
      'corsheaders'
      ]
    3)添加中间件
      MIDDLEWARE = [
      ...
      'corsheaders.middleware.CorsMiddleware'
      ]
    4)允许跨域源, settings:
      CORS_ORIGIN_ALLOW_ALL = True
    

五、前台操作Cookie:vue-cookie

  注:前后台分离时,后台需要在响应的字典中添加token,   前台需要自己处理cookie

return JsonResponse({'msg': 'post ok',
'token':'asdfsdafsdfsadf'
})
安装
>: cd 项目目录
>: cnpm install vue-cookie --save

配置:main.js

import cookie from 'vue-cookie'
Vue.prototype.$cookie = cookie;

使用:在任何方法中

// token是后台返回的

// 设置cookie
// this.$cookie.set(key, value, time)
this.$cookie.set('token', token, 1);

// 取出cookie
// this.$cookie.get(key)
console.log(this.$cookie.get('token'));

// 删除cookie
// this.$cookie.delete(key)
this.$cookie.delete('token');

 

 
posted @ 2019-08-12 18:58  胖啊  阅读(217)  评论(0编辑  收藏  举报