注册 登录

清河洛

svelte中组件的script块和props

qingheluo2023-08-28清河洛897
<script>块一个组件中<script>块包含创建组件实例时运行的JavaScript在顶层声明(或导入)的变量在该组件中默认是处于“可见”的,可以直接使用<script> let num = 0; function but(){ num++; } </script> <button on:click="{ but }">当前num值:{ num }</button>组件的PropsProps表示子组件从父组件接受到的数据,要完成组件间的数据传递,需要...

<script>块

一个组件中<script>块包含创建组件实例时运行的JavaScript

在顶层声明(或导入)的变量在该组件中默认是处于“可见”的,可以直接使用

<script>
    let num = 0;
    function but(){
        num++;
    }
</script>

<button on:click="{ but }">当前num值:{ num }</button>

组件的Props

Props表示子组件从父组件接受到的数据,要完成组件间的数据传递,需要父组件通过属性传递Props,并且子组件中要声明允许接收的Props

父组件传递Props

<script>
    import MyComponent from './MyComponent.svelte';
</script>

<MyComponent name="qian" age="35" mydata="{prop_data}" odata="{...other_data}" />

父组件通过属性传递了name、age简单数据和一个mydata复杂数据(一般为对象)给子组件

odata中通过展开语句{...other_data}将对象展开,这样相当于单独传递每个元素

如果有较多的属性需要传递,可以传入一个obj对象并展开

子组件声明允许接收的Props

在svelte4中,通过export关键字将变量声明为prop,表示该组件允许接受该变量名称的属性

export let name;       // 不指定默认值,当不传入myname属性时默认值为undefined
export let age = 33;   // 指定默认值,当不传入myage属性时默认值为33

// 也可以统一指定prop
let name;
let age = 33;
export { name , age [as myage] }

当使用了别名"as new_arg"时,传入的属性必须为myage

在svelte5中,使用let { ...val } = $props() 在子组件中声明允许接收的props

let { name, age:myage = 33 } = $props()
    允许接收name、age属性,其中
    name没有默认值,如果不传递值为undefined
    age使用myage别名,父组件需要使用myage属性进行传递,且默认值为33

let data = $props()
    不限制接收的属性,且将接受到的值统一放置于对象data中
    通过data.key来获取指定属性的数据

let { name, ...other } = $props()
    指定了要接收的name属性,其余接收到的数据全部放置于数组other中

props的响应性,父组件中修改传递的props值可以在子组件中响应,但是子组件中修改传递的props值不会在父组件中响应

// 父组件
<script>
    import Child from './Component.svelte';
    let count = $state(0);
</script>

<button onclick={() => (count += 1)}>parent: {count}</button>
<Child {count} />

// 子组件
<script>
    let { count } = $props();
</script>

<button onclick={() => (count += 1)}>child: {count}</button>

点击父组件中的按钮count的值改动会同步在子组件中响应
点击子组件中的按钮count的值改动不会同步到父组件的响应

要向实现子组件修改一个props后在父组件也能响应,可以传递一个对象,该对象中有一个用于修改该对象属性值的方法,由于对象属于引用传值,通过调用该方法来修改对象的属性达到类似于的功能

// 父组件
<script>
    import Child from './Component.svelte';
    let data = {
        count:1,
        add:()=>data.count++
    }
</script>
<Child {data} />
<button onclick="{data.add}">parent: {data.count}</button>

// 子组件
<script>
    let { data } = $props();
</script>
<button onclick="{data.add}">child: {data.count}</button>

props双向绑定

上面我们看到了props的响应性是仅可由父组件传递给子组件,无法由子组件传递给父组件

虽然后面我们也实现了类似的效果,但却是利用了对象的引用传递,说到底属于“偏门”,并非是数据实际的由子组件传递向父组件

$bindable(val)用于在子组件中创建双向绑定的数据,其中val表示父组件不传递该属性时的默认值

// 父组件
<script>
    import Child from './Component.svelte';
    let count = $state(0);
</script>
<button onclick={() => (count += 1)}>parent: {count}</button>
<Child bind:count={count} />
    // 使用 bind: 语句声明该属性为双向绑定,父组件应该需要关注并接受该变量的值

// 子组件
<script>
    let { count = $bindable(66) } = $props();
        // 创建一个初始值为 66 的可双向绑定的值
</script>

<button onclick={() => (count += 1)}>child: {count}</button>


网址导航