• SveletJs学习——数据绑定


    1. input 单个数据绑定

    一般来说,Svelte中的数据流是自顶而下的,父组件可以给子组件设置props,组件也可以在元素上面设置属性,但反过来却不可以。但有时,这种单向数据流的方式需要打破来应用到我们的实际场景中。

    1.1 内容变化 type="text" bind:value={变量}

    <script>
    	let content = 'Ably'
    
    	function changeInputVal() {
    		console.log(content, '此时输入框中输入的值')
    	}
    
    </script>
    <main>
    	<h1>Hello, {content}</h1>
    	<input type="text" bind:value={content} on:keyup={changeInputVal}>
    </main>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    1.2 数据变化 type="range" bind:value={变量}

    <script>
    	let num1 = 0
    	let num2 = 0
    
    	function changeNum1() {
    		console.log(num1, '此时num1的值')
    	}
    	function changeNum2() {
    		console.log(num2, '此时num2的值')
    	}
    
    </script>
    <main>
    	<h1>num1: {num1}</h1>
    	<input type="range" bind:value={num1} on:change={changeNum1} max="10" min="0">
    	<h1>num2: {num2}</h1>
    	<input type="range" bind:value={num2} on:change={changeNum2} max="20" min="0">
    	num1 + num2 = {num1 + num2}
    </main>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    1.3 选中状态变化 type="checkbox" bind:checked={变量}

    <script>
    	let checkIt = false
    
    </script>
    <main>
    	当前是否为选中状态:{checkIt ? '是' : '否'}
    	<input type="checkbox" bind:checked={checkIt}>
    	{#if checkIt}
    	<h1>你选择了我,你是正确的</h1>
    	{:else}
    	<h2>你没有选择我,你也是正确的</h2>
    	{/if}
    </main>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    2. input 多个数据成组绑定 bind:group={变量}

    单选框会自动分为一组,多选框会自动形成一个数组

    <script>
    	let peopleHobby = [
    		'basketball',
    		'tennis',
    		'volleyball',
    		'pingpang'
    	];
    	let hobbies = []
    	let favoriteHob = []
    
    </script>
    <main>
    	<h1>当下年轻人喜欢的活动有哪些? {hobbies}</h1>
    	{#each peopleHobby as hob}
    		{hob}:<input bind:group={hobbies} type="checkbox" value={hob}><br>
    	{/each}
    	<h2>只可选择一种,最终会花落谁家呢? {favoriteHob}</h2>
    	{#each peopleHobby as hob}
    	{hob}:<input bind:group={favoriteHob} type="radio" value={hob}><br>
    	{/each}
    </main>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    3. textarea 内容绑定 bind:value={变量}

    <script>
    	let comment = '';
    </script>
    <main>
    	<textarea name="备注" id="comment" cols="30" rows="3" bind:value={comment} placeholder="留下您的需求,过后我们会有专业的工作人员与您进行联系"></textarea>
    	<h1>
    		需求为: {comment}
    	</h1>
    </main>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    4. select框绑定 bind:value={变量}

    4.1 单选

    <script>
    	let subjects = ['语文', '数学', '外语', '政治', '物理', '化学']
    	let favoriteSub
    </script>
    <main>
    	选择你最喜欢的学科:
    	<select name="" id="" bind:value={favoriteSub}>
    		{#each subjects as subject}
    		<option value={subject}>{subject}</option>
    		{/each}
    	</select>
    	<h1>最终喜欢的学科是:{favoriteSub}</h1>
    </main>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    4.2 多选

    shift + 鼠标选择多个内容

    <script>
    	let subjects = ['语文', '数学', '外语', '政治', '物理', '化学']
    	let favoriteSub = []
    </script>
    <main>
    	选择你最喜欢的学科:
    	<select multiple name="sub" id="" bind:value={favoriteSub}>
    		{#each subjects as subject}
    		<option value={subject}>{subject}</option>
    		{/each}
    	</select>
    	<h1>最终喜欢的学科是:{favoriteSub}</h1>
    </main>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    5. Contenteditable bind:innerHTML={变量}

    支持contenteditable="true"属性的标签,可以[contenteditable]设置样式,可以绑定innerHTML属性插入内容

    <script>
    	let htmlContent = '<h1>Hello, contenteditable</h1>'
    </script>
    <main>
    	<div contenteditable="true"  bind:innerHTML={htmlContent}></div>
    </main>
    <style>
    	[contenteditable] {
    		border: 1px solid #ccc;
    		padding: 4px;
    		border-radius: 4px;
    	}
    </style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    6. each块绑定

    • 动态绑定class:定义一个名为done的类,根据现在事项是佛偶完成展示对应样式 class:done={todoItem.done}
    <script>
    	let todoList = [
    		{
    			name: '变美',
    			weight: 999,
    			done: true
    		},
    		{
    			name: '变富',
    			weight: 9999,
    			done: false
    		},
    		{
    			name: '变快乐',
    			weight: 99999,
    			done: false
    		}
    	]
    	let todos = []
    	let newVal = ''
    
    	function addNewTodo() {
    		newVal = ''
    		todoList = todoList.concat({
    			name: '',
    			weight: 99999,
    			done: false
    		})
    	}
    
    	function completeTodo(todoItem) {
    		todoList[todoList.length - 1].name = newVal
    	}
    	function showUndo() {
    		todoList = todoList.filter((item) => {
    			return !item.done
    		})
    	}
    </script>
    <main>
    	{#each todoList as todoItem}
    		<div class:done={todoItem.done}>
    			<input type="checkbox" bind:checked={todoItem.done}> {todoItem.name}
    			{#if !todoItem.name}
    				<input type="text" bind:value={newVal} on:blur={completeTodo(todoItem)}>
    			{/if}
    		</div>
    	{/each}
    	<button on:click={addNewTodo}>新增一个</button>
    	<button on:click={showUndo}>展示未完成</button>
    </main>
    <style>
    .done {
    	opacity: 0.4;
    }
    </style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56

    7. 媒体标签的绑定 TODO: 待补充

    如果你看到的时候还是待补充,记得评论提醒我哦,我可能是忘记啦.

    8. 尺寸的绑定

    每个块级标签都可以对clientWidth、clientHeight、offsetWidth以及offsetHeight属性进行绑定。

    获取当前div的宽度和高度,由于div是块级元素,那么默认clientWidth就是当前铺满屏幕的宽度,高度会因下面增加的h1内容等进行变化
    
    <script>
    	let clientW
    	let clientH
    </script>
    <main>
    	<div class="block_content" bind:clientWidth={clientW} bind:clientHeight={clientH}>
    		这是块级内容
    		<h1>
    			size: width: {clientW}px height: {clientH}px
    		</h1>
    	</div>
    
    </main>
    <style>
    	.block_content {
    		background-color: aqua;
    	}
    </style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • clientWidth、clientHeight、offsetWidth 以及 offsetHeight这些绑定是只读的。
    • 使用display:inline的标签无法获得尺寸
    • 在标签上绑定这个值,涉及到额外的性能开销,因此不建议在页面中大量的使用。

    9. this绑定 TODO:待补充

    this可以绑定任何标签(或组件)并允许你获取对渲染标签的引用。

    10. 子组件向父组件传值

    • 在组件中通过export定义变量,才能在父组件中通过这个变量名接收到子组件中的值
    App.svelte
    
    <script>
    	import ChildValToApp from "./components/ChildValToApp.svelte";
    
    	let finalVal = ''
    	$: finalValView = finalVal
    </script>
    <main>
    	<div>点击后最终生成的内容:{finalValView}</div>
    	<ChildValToApp bind:calculateVal={finalVal}/>
    </main>
    <style>
    	.block_content {
    		background-color: aqua;
    	}
    </style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    ChildValToApp.svelte
    
    <script>
    
        // 在组件中通过export定义变量,才能在父组件中通过这个变量名接收到子组件中的值
        export let calculateVal = ''
    
        function handleClickContent(event) {
            calculateVal += event.target.innerHTML
            console.log(calculateVal, '最终拼接值')
        }
    
    </script>
    <main>
        <div class="gridContainer" on:click={handleClickContent}>
            <div class="gridItem">1</div>
            <div class="gridItem">2</div>
            <div class="gridItem">3</div>
            <div class="gridItem">4</div>
        </div>
    </main>
    <style>
        .gridContainer {
            display: flex;
        }
    .gridItem {
        padding: 20px;
        border: 1px solid #ccc;
        flex: 1;
        text-align: center;
    }
    </style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    代码分析:
    子组件中定义了一个又一个的栅格,点击栅格获取栅格中的字符串类型的数字,记录每一次点击的数字,然后将子组件中最终拼接成功的值在父组件中获取到。子组件中通过export let calculateVal = ''export定义变量,父组件中通过 <ChildValToApp bind:calculateVal={finalVal}/>bind子组件变量名转为新的变量,通过$实时监听渲染页面,最终达到的我们想要的效果。

    官方文档
    如果有用,点个赞呗~

    总结用法,希望可以帮助到你,
    我是Ably,你无须超越谁,只要超越昨天的自己就好~

  • 相关阅读:
    阿尔萨斯监控平台&普罗米修斯监控平台对服务器资源的监控
    【C语言】栈的实现
    【pytorch笔记】第六篇 卷积原理和卷积层
    南大通用数据库-Gbase-8a-学习-38-常规日志(general log)
    搞定企业视频直播:硬件设备、直播网络环境和设备连接说明
    zookeeper高级特性
    异或最小生成树
    kubernetes部署和运行维护中的错误汇总(不定时更新)
    一看就会的Chromedriver(谷歌浏览器驱动)安装教程
    vulnhub靶机-DC系列-DC-3
  • 原文地址:https://blog.csdn.net/weixin_44593720/article/details/125619245