Component Setup
Write Vue Composition API logic directly in your Blade templates using @script.
Basic Usage
The @script directive lets you define Vue Composition API code (computed, watch, lifecycle hooks) directly in your Blade template.
<div>
<p>Name: <strong v-text="name">{{ $name }}</strong></p>
<p>Greeting: <strong v-text="greeting"></strong></p>
<p>Local count: <strong v-text="localCount"></strong></p>
<button @click="incrementLocal()">+1 Local</button>
<button @click="livue.call('increment')">+1 Server</button>
</div>
@script
const greeting = computed(() => 'Hello, ' + name.value + '!');
const localCount = ref(0);
function incrementLocal() {
localCount.value++;
}
watch(name, (newVal) => {
console.log('Name changed to:', newVal);
});
onMounted(() => {
console.log('Component mounted!');
});
return { greeting, localCount, incrementLocal };
@endscript
Available APIs
Inside @script, you have access to all Vue Composition APIs and your component's state:
Vue Composition API
ref()- Create reactive referencescomputed()- Computed propertieswatch()- Watch changeswatchEffect()- Reactive effectreactive()- Reactive objectsonMounted()- Mount lifecycleonUnmounted()- Unmount lifecyclenextTick()- DOM update timing
Component Access
name,count, etc. - PHP properties as refslivue- The LiVue helper objectlivue.call()- Call server methodslivue.set()- Update statelivue.errors- Validation errors
Server State as Refs
All your PHP public properties are available as Vue refs. Access them with .value:
@script
// 'name' and 'count' are PHP public properties
const greeting = computed(() => 'Hello, ' + name.value + '!');
const doubled = computed(() => count.value * 2);
// Watch server state changes
watch(count, (newVal, oldVal) => {
console.log(`Count changed: ${oldVal} → ${newVal}`);
});
return { greeting, doubled };
@endscript
IDE Support
For syntax highlighting and autocompletion, wrap your code in a <script> tag. LiVue removes it automatically:
@script
<script>
// Now your IDE recognizes this as JavaScript!
const greeting = computed(() => 'Hello, ' + name.value);
const localCount = ref(0);
return { greeting, localCount };
</script>
@endscript
Rules
-
1.
Place
@scriptoutside the root<div>, at the end of your template - 2. Return an object with the bindings you want to expose to the template
-
3.
Only one
@scriptblock per template - 4. Local state (refs created in @script) resets on server re-render
@script vs #[Vue]
Both execute client-side JavaScript, but serve different purposes:
| Aspect | @script | #[Vue] |
|---|---|---|
| Location | Blade template | PHP method |
| Execution | On component mount | When called via livue.call() |
| Best for | Computed, watchers, lifecycle | One-shot actions (reset, alert) |
| Returns | Object with template bindings | Nothing (side effects only) |
Full Example
PHP Component
class ScriptTest extends Component
{
public string $name = 'World';
public int $count = 0;
public function increment()
{
$this->count++;
}
}
Result
greetingupdates reactively whennamechangesdoubledupdates whencountchanges (server)localCountis pure client-side, no server calls- Watchers log changes to console