使用 JavaScript 显示 Laravel 的变量
Using JavaScript to display Laravel's Variable
在我的代码中,我使用 typeahead.js。我使用 Laravel 5,我需要用我的 {{ $jobs }}
变量替换 var states
。我需要将所有职位作为一个数组列出。
在我的控制器中我有
$jobs = Job::all(['job_title']);
我知道 javascript 中的循环方法,但我不知道如何 "link" 我的 blade 变量在 javascript 中。有人知道怎么做吗?
我试过了,在my.js
var jobs = {{ $jobs }}
但这行不通。
对于数组等更复杂的变量类型,最好的办法是将其转换为 JSON,在模板中回显并在 JavaScript 中对其进行解码。像这样:
var jobs = JSON.parse("{{ json_encode($jobs) }}");
请注意 PHP 必须 运行 修改此代码才能使其正常工作。在这种情况下,您必须将它放在您的 Blade 模板中。如果您的 JavaScript 代码位于一个或多个单独的文件中(这很好!),您只需将一个内联脚本标记添加到您传递变量的模板中。 (只需确保 运行s 在 其余 JavaScript 代码之前。通常 document.ready
就是答案)
<script>
var jobs = JSON.parse("{{ json_encode($jobs) }}");
</script>
如果您不喜欢这样做,我建议您在单独的 ajax 请求中获取数据。
补充以上内容:
var jobs = JSON.parse("{{ json_encode($jobs) }}");
将 return 转义 html 实体,因此您将无法遍历 javascript 中的 json 对象,要解决此问题,请使用以下方法:
var jobs = JSON.parse("{!! json_encode($jobs) !!}");
或
var jobs = JSON.parse(<?php echo json_encode($jobs); ?>);
这对我有用
jobs = {!! json_encode($jobs) !!};
通知
仅当您可以保证 $jobs
不包含任何用户输入值时才使用此方法。使用 {!! ... !!}
输出值而不对它们进行转义,这可能会导致跨站点脚本 (XSS) 攻击。
我刚刚解决了这个问题,方法是在布局文件的 <head>
中放置对 window
对象的引用,然后使用可以注入任何组件的 mixin 选择该引用。
TLDR SOLUTION
.env
GEODATA_URL="https://geo.some-domain.com"
config/geodata.php
<?php
return [
'url' => env('GEODATA_URL')
];
resources/views/layouts/root.blade.php
<head>
<script>
window.geodataUrl = "{{ config('geodata.url') }}";
</script>
</head>
resources/js/components/mixins/geodataUrl.js
const geodataUrl = {
data() {
return {
geodataUrl: window.geodataUrl,
};
},
};
export default geodataUrl;
用法
<template>
<div>
<a :href="geodataUrl">YOLO</a>
</div>
</template>
<script>
import geodataUrl from '../mixins/geodataUrl';
export default {
name: 'v-foo',
mixins: [geodataUrl],
data() {
return {};
},
computed: {},
methods: {},
};
</script>
END TLDR SOLUTION
如果需要,您可以使用全局混入,方法是将其添加到您的 app.js
入口点:
Vue.mixin({
data() {
return {
geodataUrl: window.geodataUrl,
};
},
});
但是,我不建议对任何敏感数据使用此模式,因为它位于 window
对象上。
我喜欢这个解决方案,因为它没有使用任何额外的库,而且代码链非常清晰。它通过了 grep 测试,因为您可以在代码中搜索 "window.geodataUrl"
并查看您需要了解的所有内容,以了解代码的工作方式和原因。
如果代码可能存在很长时间并且其他开发人员可能会遇到它,那么这种考虑很重要。
然而,JavaScript::put([])
在我看来是一个值得拥有的不错的实用程序,但过去我不喜欢如果出现问题,调试起来会非常困难,因为你看不到数据来自代码库中的何处。
假设您有一些 Vue 代码正在消耗来自 JavaScript::put([ 'chartData' => $user->chartStuff ])
的 window.chartData
。根据代码库中对 chartData
的引用数量,您可能需要很长时间才能发现哪个 PHP 文件负责使 window.chartData
工作,尤其是如果您没有不写那个代码,下一个人不知道 JavaScript::put()
正在被使用。
在那种情况下,我建议在代码中添加注释,例如:
/* data comes from poop.php via JavaScript::put */
然后此人可以搜索 "JavaScript::put"
的代码并快速找到它。请记住 "the person" 可能在您忘记实施细节后的 6 个月内成为您自己。
像这样使用 Vue 组件 prop 声明总是一个好主意:
props: {
chartData: {
type: Array,
required: true,
},
},
我的观点是,如果您使用 JavaScript::put()
,那么如果组件无法接收数据,Vue 将无法轻松检测到。 Vue 必须假设数据在它引用它的那一刻就在 window 对象上。您最好的选择可能是创建一个 GET 端点并在您的 created/mounted 生命周期方法中进行提取调用。
我认为在涉及 getting/setting 数据时,Laravel 和 Vue 之间有一个明确的契约很重要。
为了尽可能多地为您提供选择,这里有一个使用 ES6 语法糖进行提取调用的示例:
routes/web.php
Route::get('/charts/{user}/coolchart', 'UserController@getChart')->name('user.chart');
app/Http/Controllers/UserController.php
public function getChart(Request $request, User $user)
{
// do stuff
$data = $user->chart;
return response()->json([
'chartData' => $data,
]);
}
Vue 中的任何地方,尤其是创建的生命周期方法:
created() {
this.handleGetChart();
},
methods: {
async handleGetChart() {
try {
this.state = LOADING;
const { data } = await axios.get(`/charts/${this.user.id}/coolchart`);
if (typeof data !== 'object') {
throw new Error(`Unexpected server response. Expected object, got: ${data}`);
}
this.chartData = data.chartData;
this.state = DATA_LOADED;
} catch (err) {
this.state = DATA_FAILED;
throw new Error(`Problem getting chart data: ${err}`);
}
},
},
该示例假设您的 Vue 组件是一个 Mealy 有限状态机,组件在任何给定时间只能处于一种状态,但它可以在状态之间自由切换。
我建议使用计算道具这样的状态:
computed: {
isLoading() { return (this.state === LOADING); },
isDataLoaded() { return (this.state === DATA_LOADED); },
isDataFailed() { return (this.state === DATA_FAILED); },
},
带有如下标记:
<div v-show="isLoading">Loading...</div>
<v-baller-chart v-if="isDataLoaded" :data="chartData"></v-baller-chart>
<button v-show="isDataFailed" type="button" @click="handleGetChart">TRY AGAIN</button>
这种方法对我有用:
var job = {!! json_encode($jobs ) !!}
并在 java 脚本中使用
在 laravel 6 这对我有用
使用 laravel blade 指令
var jobs = {!! json_encode($jobs) !!};
还使用了@json
指令
var jobs = @json($jobs);
使用 php 风格
var jobs = <?php echo json_encode($jobs); ?>
在较新的 laravel 版本中,在 json 中 "
(双引号)被编码为 htmlentity
为 "e;
和不需要的 JSON.parse()
用这个调用,
var jobs = JSON.parse("{{ json_encode($jobs) }}");
你最终会遇到 javascript 错误。或者,您可以使用
var jobs = {!! json_encode($jobs, JSON_PRETTY_PRINT) !!};
我们知道,{!! !!}
是用来打印 HTML 的,它会很有用。这也将减少在浏览器中解析 JSON 的开销。
在laravel 7我就是这样
var jobs = '{{ $jobs }}';
在Laravel 8。您可以使用 blade 模板来...
const jobs = @json($jobs ?? NULL);
一个简单的方法是使用 Blade 的新 @json()
指令。
✓ 在 Laravel 7.x
上测试
<script>
let myVariable = @json($myVariable)
console.log(myVariable)
</script>
var job_id = '{{ $jobs->first()->id}}';
在我的代码中,我使用 typeahead.js。我使用 Laravel 5,我需要用我的 {{ $jobs }}
变量替换 var states
。我需要将所有职位作为一个数组列出。
在我的控制器中我有
$jobs = Job::all(['job_title']);
我知道 javascript 中的循环方法,但我不知道如何 "link" 我的 blade 变量在 javascript 中。有人知道怎么做吗?
我试过了,在my.js
var jobs = {{ $jobs }}
但这行不通。
对于数组等更复杂的变量类型,最好的办法是将其转换为 JSON,在模板中回显并在 JavaScript 中对其进行解码。像这样:
var jobs = JSON.parse("{{ json_encode($jobs) }}");
请注意 PHP 必须 运行 修改此代码才能使其正常工作。在这种情况下,您必须将它放在您的 Blade 模板中。如果您的 JavaScript 代码位于一个或多个单独的文件中(这很好!),您只需将一个内联脚本标记添加到您传递变量的模板中。 (只需确保 运行s 在 其余 JavaScript 代码之前。通常 document.ready
就是答案)
<script>
var jobs = JSON.parse("{{ json_encode($jobs) }}");
</script>
如果您不喜欢这样做,我建议您在单独的 ajax 请求中获取数据。
补充以上内容:
var jobs = JSON.parse("{{ json_encode($jobs) }}");
将 return 转义 html 实体,因此您将无法遍历 javascript 中的 json 对象,要解决此问题,请使用以下方法:
var jobs = JSON.parse("{!! json_encode($jobs) !!}");
或
var jobs = JSON.parse(<?php echo json_encode($jobs); ?>);
这对我有用
jobs = {!! json_encode($jobs) !!};
通知
仅当您可以保证 $jobs
不包含任何用户输入值时才使用此方法。使用 {!! ... !!}
输出值而不对它们进行转义,这可能会导致跨站点脚本 (XSS) 攻击。
我刚刚解决了这个问题,方法是在布局文件的 <head>
中放置对 window
对象的引用,然后使用可以注入任何组件的 mixin 选择该引用。
TLDR SOLUTION
.env
GEODATA_URL="https://geo.some-domain.com"
config/geodata.php
<?php
return [
'url' => env('GEODATA_URL')
];
resources/views/layouts/root.blade.php
<head>
<script>
window.geodataUrl = "{{ config('geodata.url') }}";
</script>
</head>
resources/js/components/mixins/geodataUrl.js
const geodataUrl = {
data() {
return {
geodataUrl: window.geodataUrl,
};
},
};
export default geodataUrl;
用法
<template>
<div>
<a :href="geodataUrl">YOLO</a>
</div>
</template>
<script>
import geodataUrl from '../mixins/geodataUrl';
export default {
name: 'v-foo',
mixins: [geodataUrl],
data() {
return {};
},
computed: {},
methods: {},
};
</script>
END TLDR SOLUTION
如果需要,您可以使用全局混入,方法是将其添加到您的 app.js
入口点:
Vue.mixin({
data() {
return {
geodataUrl: window.geodataUrl,
};
},
});
但是,我不建议对任何敏感数据使用此模式,因为它位于 window
对象上。
我喜欢这个解决方案,因为它没有使用任何额外的库,而且代码链非常清晰。它通过了 grep 测试,因为您可以在代码中搜索 "window.geodataUrl"
并查看您需要了解的所有内容,以了解代码的工作方式和原因。
如果代码可能存在很长时间并且其他开发人员可能会遇到它,那么这种考虑很重要。
然而,JavaScript::put([])
在我看来是一个值得拥有的不错的实用程序,但过去我不喜欢如果出现问题,调试起来会非常困难,因为你看不到数据来自代码库中的何处。
假设您有一些 Vue 代码正在消耗来自 JavaScript::put([ 'chartData' => $user->chartStuff ])
的 window.chartData
。根据代码库中对 chartData
的引用数量,您可能需要很长时间才能发现哪个 PHP 文件负责使 window.chartData
工作,尤其是如果您没有不写那个代码,下一个人不知道 JavaScript::put()
正在被使用。
在那种情况下,我建议在代码中添加注释,例如:
/* data comes from poop.php via JavaScript::put */
然后此人可以搜索 "JavaScript::put"
的代码并快速找到它。请记住 "the person" 可能在您忘记实施细节后的 6 个月内成为您自己。
像这样使用 Vue 组件 prop 声明总是一个好主意:
props: {
chartData: {
type: Array,
required: true,
},
},
我的观点是,如果您使用 JavaScript::put()
,那么如果组件无法接收数据,Vue 将无法轻松检测到。 Vue 必须假设数据在它引用它的那一刻就在 window 对象上。您最好的选择可能是创建一个 GET 端点并在您的 created/mounted 生命周期方法中进行提取调用。
我认为在涉及 getting/setting 数据时,Laravel 和 Vue 之间有一个明确的契约很重要。
为了尽可能多地为您提供选择,这里有一个使用 ES6 语法糖进行提取调用的示例:
routes/web.php
Route::get('/charts/{user}/coolchart', 'UserController@getChart')->name('user.chart');
app/Http/Controllers/UserController.php
public function getChart(Request $request, User $user)
{
// do stuff
$data = $user->chart;
return response()->json([
'chartData' => $data,
]);
}
Vue 中的任何地方,尤其是创建的生命周期方法:
created() {
this.handleGetChart();
},
methods: {
async handleGetChart() {
try {
this.state = LOADING;
const { data } = await axios.get(`/charts/${this.user.id}/coolchart`);
if (typeof data !== 'object') {
throw new Error(`Unexpected server response. Expected object, got: ${data}`);
}
this.chartData = data.chartData;
this.state = DATA_LOADED;
} catch (err) {
this.state = DATA_FAILED;
throw new Error(`Problem getting chart data: ${err}`);
}
},
},
该示例假设您的 Vue 组件是一个 Mealy 有限状态机,组件在任何给定时间只能处于一种状态,但它可以在状态之间自由切换。
我建议使用计算道具这样的状态:
computed: {
isLoading() { return (this.state === LOADING); },
isDataLoaded() { return (this.state === DATA_LOADED); },
isDataFailed() { return (this.state === DATA_FAILED); },
},
带有如下标记:
<div v-show="isLoading">Loading...</div>
<v-baller-chart v-if="isDataLoaded" :data="chartData"></v-baller-chart>
<button v-show="isDataFailed" type="button" @click="handleGetChart">TRY AGAIN</button>
这种方法对我有用:
var job = {!! json_encode($jobs ) !!}
并在 java 脚本中使用
在 laravel 6 这对我有用
使用 laravel blade 指令
var jobs = {!! json_encode($jobs) !!};
还使用了@json
指令
var jobs = @json($jobs);
使用 php 风格
var jobs = <?php echo json_encode($jobs); ?>
在较新的 laravel 版本中,在 json 中 "
(双引号)被编码为 htmlentity
为 "e;
和不需要的 JSON.parse()
用这个调用,
var jobs = JSON.parse("{{ json_encode($jobs) }}");
你最终会遇到 javascript 错误。或者,您可以使用
var jobs = {!! json_encode($jobs, JSON_PRETTY_PRINT) !!};
我们知道,{!! !!}
是用来打印 HTML 的,它会很有用。这也将减少在浏览器中解析 JSON 的开销。
在laravel 7我就是这样
var jobs = '{{ $jobs }}';
在Laravel 8。您可以使用 blade 模板来...
const jobs = @json($jobs ?? NULL);
一个简单的方法是使用 Blade 的新 @json()
指令。
✓ 在 Laravel 7.x
上测试<script>
let myVariable = @json($myVariable)
console.log(myVariable)
</script>
var job_id = '{{ $jobs->first()->id}}';