Vuejs 2.0 教程:与后端 API 进行交互
codedone

jelly,前后端分离后,要发布到生产环境是要怎么搞,直接将前端的代码,弄到laravel里面的模板中吗?

JellyBool 回复 @codedone

前端代码就是 webpack 打包的js 吧,可以直接 build ,放到public 目录下

codedone 回复 @JellyBool

好的,然后,用户进行http请求的话,是根据前端的路由去做转向?

JellyBool 回复 @codedone

如果前后端分离的话,就是前端路由接管就可以

codedone 回复 @JellyBool

好的,非常感谢jelly大大

leec

Vue前端项目 和 后端laravel api项目,分成两个不同文件夹放?
API可以弄成相对路径么?本地开发时候一个,联调测试时一个,只要前面的 base_api_url 不同。

JellyBool 回复 @leec

base_api_url ? 没理解错的话,你可以设置 axios 的 baseUrl 的,只要你的 api 路由都是一致的话,就可以。

Vue前端项目 和 后端laravel api项目,分成两个不同文件夹放

这个倒是没什么要求吧,看你怎么放都可以。如果是在一个 laravel 项目里,你可以使用laravel 自带的 webpack ,也可以自己打包,build 之后,放到 public 目录

-SHERLOCK勋 回复 @leec

可以放到webpack的env里面呀

sonics34

可以不用隐藏表单的方法获取到文章id吗

JellyBool 回复 @sonics34

恩,可以的啊,直接作为路由参数就可以的。

话说怎么在这里问这个问题

liudong0763
//正确写法:
toggleComplete(todo){
                this.axios.patch('http://laravel.dev/api/todo/'+todo.id+'/completed').then(response=>{
                    console.log(response.data)
                    todo.completed = ! todo.completed
                })
            }
//可是为什么这样写就不正确呢
toggleComplete(todo){
                this.axios.patch('http://laravel.dev/api/todo/'+todo.id+'/completed').then(response=>{
                    console.log(response.data)
                    todo = response.data
                })
            }
JellyBool 回复 @liudong0763

你具体看看你具体返回的是什么?

a119347 回复 @liudong0763

第一个是直接把todocompleted取反,第二个是获取response的值,要加Json.parse()

etoupcom 回复 @liudong0763

为什么新创建的数据点击completed无效呢?

JellyBool 回复 @etoupcom

你看看 chrome devtool 报什么错误

etoupcom 回复 @JellyBool

没有任何报错,添加新数据不刷新点击completed后没有反应,但是再点上面一条的completed两条会一起改变。刷新页面就没有这个问题。

JellyBool 回复 @etoupcom

有可能是你添加数据的时候没有设置 completed 这个属性吧,你就打开 chrome devtool 看看整个流程

Arun 回复 @etoupcom

你把completed传过去一起存数据库,然后就可以返回completed的值了

liudong0763
2laravel.dev/api/todo/8/completed:1 PATCH http://laravel.dev/api/todo/8/completed 
:8080/#/:1 XMLHttpRequest cannot load http://laravel.dev/api/todo/8/completed. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8080' is therefore not allowed access. The response had HTTP status code 429.
createError.js?f777:15 Uncaught (in promise) Error: Network Error(…)

老师,在我点complete按钮的时候,一般点前几次都没什么问题,但是点多几次就会在控制台报出这样的错误提示,不明白

JellyBool 回复 @liudong0763
Uncaught (in promise) Error: Network Error(…)

网问题?

sfabric2016

这个系列后续还会更新吗?

JellyBool 回复 @sfabric2016

恩,我应该今天就会更新

zovlqa 回复 @JellyBool

Vue.js 20 后面的课程有什么计划呢(课程表),可以列出来么?

JellyBool 回复 @zovlqa

后面应该是录两个跟 vuex 相关的视频吧

昝浩浩就是喜欢罗大霉

我听不懂怎么办........

JellyBool 回复 @昝浩浩就是喜欢罗大霉

还好吧,我已经尽力说清楚了,貌似用户的评价还不错

ye0205414225

老师讲的非常好!赞叹呐!

是否之后会有个前后端分离(结合框架)打包放上开发环境流程详细教程呢?

JellyBool 回复 @ye0205414225

这个也可以的,但是接下来我打算先录制一个实战的项目先

chunyi741

axios.get 可以正常获得数据,axios.post提示跨域请求

服务端路由

Route::post('api/todo/create', function (Request $request){
    $data = ['title' => $request->get('title'),'completed' => 0];
    $todo = App\Todo::create($data);
    return $todo;
})->middleware('cors');

TodoForm组件

methods: {
    addTodo(newTodo){
        this.axios.post(
        'http://localhost:8000/api/todo/create',{title: this.newTodo.title}).then(response => {
            console.log(response.data)
        })
        this.todos.push(newTodo);
        this.newTodo = {id:39,title:'',completed:false};
    },
}
JellyBool 回复 @chunyi741

你的 laravel 版本是多少?api 路由的定义是否是在 api.php 里面?试试这样:

->middleware('cors','api');
chunyi741 回复 @JellyBool

laravel版本是5.2

api 路由的定义是否是在 api.php 里面

你说的是api中间件吗,我并没有注册这个,我不知道应该怎么操作才能像你视频中说的在中间件中自动加上api/的路由前缀

JellyBool 回复 @chunyi741

额,你的是 5.2 的版本的话,貌似你要使用 api 这个middleware。

chunyi741 回复 @JellyBool

好的,下班了,回去仔细想一下,多谢Jelly

fujinshui

XMLHttpRequest cannot load http://192.168.0.168/tp5/public/index.php/admin/Todos/create. Request header field Content-Type is not allowed by Access-Control-Allow-Headers in preflight response.

JellyBool 回复 @fujinshui

这是跨域问题引起的吧。视频应该有说到

fujinshui 回复 @JellyBool

有用thinkphp吗 我get有值 post没值

fujinshui

addTodo(newTodo){

            this.axios.post('http://192.168.0.168/tp5/public/index.php/admin/Todos/create',{title:this.newTodo.title}).then(response=>{
                console.log(response.data)
                //this.todos.push(response.data);
            })
            this.newTodo={id:null,title:''};
        },后台接受值为空
GOD_Nt

老师,如果前后端分离的话,像微信授权登录这种(结合overtrue/wechat)如何使用啊?

JellyBool 回复 @GOD_Nt

具体我没有实现过,你可以看看这个讨论,感觉不错

https://pvg.v2ex.com/t/287376

GOD_Nt 回复 @JellyBool

谢谢Jelly,这个和我理解的差不多,但是总感觉应该有更好的解决办法

墨生人

如果我想增删改成功以后,出现一个小弹窗,vue有没有相关的插件,或者本身自带这个功能?

JellyBool 回复 @墨生人

删除完成之后触发一个 modal 就可以了吧,可以看看这个

https://vuejs.org/v2/examples/modal.html

墨生人 回复 @JellyBool

好的,十分感谢

etoupcom

为什么新创建的数据点击completed无效呢

HideStone

看教程但是没有后端api 如何按照流程走呢,自己模拟数据吗?

JellyBool 回复 @HideStone

你是说你完全不懂 后端?然后没有 api 数据?

HideStone 回复 @JellyBool

对,没有接触过后端,那么与后端一系列的数据操作只有自己去模拟数据来完成吗?

JellyBool 回复 @HideStone

这个有点难了,我帮你看看线上有没有类似的服务。

wenqingzzz

试验了好几次,我再进行get请求的时候没有什么问题,可是post请求的时候就会发生跨域的提示,不知道这个是怎么回事啊?我看了下请求method是OPTIONS的。
catch error提示 vue Error: Network Error

JellyBool 回复 @wenqingzzz

使用了 cros 这个 package 了么

wenqingzzz 回复 @JellyBool

使用了,我发现patch和delete都有报错

JellyBool 回复 @wenqingzzz

vue Error: Network Error 这是什么鬼?你提供一下 chrome 的报错信息?

wenqingzzz 回复 @JellyBool

Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8080' is therefore not allowed access.

JellyBool 回复 @wenqingzzz

这个就是跨域的吧,你使用了 cors 的路由怎么注册的?

wenqingzzz 回复 @JellyBool

我在问答中描述了一下问题,感觉可能是设置的问题

lg23

群主: axios拦截器有讲没?
我想实现以下功能
统一处理所有http请求和响应
配置 http response inteceptor,当后端接口返回401 Unauthorzed(未授权),让用户重新登录

问题是我现在手工在浏览器中添加:
http://www.tb.com/api/order/type=0?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOjUsImlzcyI6Imh0dHA6XC9cL3d3dy50Yi5jb21cL2FwaVwvbG9naW4iLCJpYXQiOjE0ODkyOTI4MDksImV4cCI6MTQ4OTI5NjQwOSwibmJmIjoxNDg5MjkyODA5LCJqdGkiOiI2OTNjYTY1MWU3MzVlZTQ4ODIxNWU2MzFkYzFjNTRjMSJ9.SV6yEcHkkALu07rSFdQx4ODm8zFrkNV7apxLYQg1MJc
请求返回结果是正常的。
但是我通过拦截器统一处理时,却总是提示:

GET http://www.tb.com/api/order/type=0 400 (Bad Request)
error : "token_invalid"

这里我估计是 token 没有添加上,但具体应该如何添加呢?

/**
 * 拦截器
 * 统一处理所有http请求和响应
 * 配置 http response inteceptor,当后端接口返回401 Unauthorzed(未授权),让用户重新登录
 */
import axios from 'axios'    // ajax 插件
import VueAxios from 'vue-axios' // vue请求ajax插件
import store from './vuex/store.js'//状态管理
import { USER_SIGNIN,USER_SIGNOUT,USER_REGISTER } from './vuex/types'// 引入状态定义 并解构
import router from './route-config.js'// 引入路由配置文件

// 全局 axios 默认值
// axios.defaults.baseURL = 'http://www.tb.com';

// 请求 拦截器
axios.interceptors.request.use(
    config => {
        console.log(Boolean(store.state.login.token))
        // 在请求之前做某事发送
        if (store.state.login.token) {// 判断是否存在token,如果存在,则每个http header都加上 token
            console.log(998112233)
                // config.headers.Authorization = `token ${store.state.login.token}`;
            config.headers.Bearer = `token ${store.state.login.token}`;
        
        }
        console.log(config)
        return config;
    }, err => {// 发生错误
        return promise.reject(err);
    });

// 响应 拦截器
axios.interceptors.response.use(
    response => { // 对响应数据做某事
        console.log(123)
        return response;
    }, error => {
        if (error.response) {// 对响应错误做出反应
                    console.log(789)
            switch (error.response.status) {
                case 401:
                    // 401 清除token信息  并跳转到login
                    store.commit(USER_SIGNOUT);
                    router.replace({
                        name: 'login',
                        query: {redirect: router.currentRoute.fullPath}
                    })
            }

            // 返回接口返回的错误信息
            return Promise.reject(error.response.data);
        }
            
    });

export default axios;

拦截器代码如上,还请指点!

JellyBool 回复 @lg23

这根拦截器没什么关系吧

你用的apache is?nginx?

lg23 回复 @JellyBool

nginx 服务器 php7.0

JellyBool 回复 @lg23

bear 那行没写对....

config.headers.Beaer is= ' Beaer $()....

lg23 回复 @JellyBool

好的, 我试试

JellyBool 回复 @lg23

这样试试:

config.headers.Bearer = `Bearer ${store.state.login.token}`;  
lg23 回复 @JellyBool

群主!
这里的 Beaer 是不是 Bearer
另外 上面的 is 是什么意思?
Beaer 和 Bearer 我都试过,还是报一样的错误

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

报错如下:
GET http://www.tb.com/api/order/0 400 (Bad Request)
Uncaught (in promise) Object {error: "token_invalid"}

JellyBool 回复 @lg23

保证这个 token 是可用的就行

${store.state.login.token}
lg23 回复 @JellyBool

搞定了,我的写法是这样的

config.headers.Authorization = `Bearer ${store.state.login.token}`;
lg23 回复 @JellyBool

我修改了添加token 的方法

if (store.state.login.token) {// 判断是否存在token,如果存在,则每个http header都加上 token
            
            reqHeaders.append('Authorization','Bearer '+store.state.login.token);
        }

目前没有报上面的错误了,但是返回数据时报错,提示
TypeError: Cannot read property 'data' of undefined

mounted() {// 生命周期钩子
        this.axios.get('http://www.tb.com/api/order/type=0')
        .then((response) => {
            console.log(JSON.parse(response.data))
            //console.log(JSON.parse(response.data.resultData));
            //this.lists = JSON.parse(response.data.resultData);
        })
    },

我后台返回的代码如下:
orderController.php
return $this->response->item($order, new OrderTransformer());

OrderTransformer.php
public function transform(Order $order)
    {
        // 调用 model 里的方法 将属性转换为数组
        return $order->attributesToArray();
    }
beaplat-61f

Laravel 5.1,路由使用 put 方法跨域有问题,改成 patch 就可以了

wuyutaott

jelly, api/todo/create 的认证是怎么实现的?

JellyBool 回复 @wuyutaott

你说的是什么认证?

lwQin

无法播放该视频,请换一个支持HTML5视频功能的浏览器
环境:Chrome58,win10

JellyBool 回复 @lwQin

我看看,基本上是视频问题

dcharlie123

视频无法播放

a359611223

感觉再学习下去就想转前端了 哈哈哈哈

rabZhang

老师问一个比较幼稚的问题,是不是靠这样就能做网站了呢,就是做全栈的话,还需要学什么

JellyBool 回复 @rabZhang

很多吧,部署站点会接触很多,nginx redis mysql 等

HsuChihYung

这个视频和第5个Vue和Laravel结合的视频会出现,“无法播放该视频,请换一个支持HTML5视频功能的浏览器”,用的是Chrome,有时会发生类似的情况,但有时也不会发生

JellyBool 微信公众号

不定期送书,送键盘,送订阅优惠