只要你会vue,5分钟学不会 svelte 你来找我

news2024/11/14 23:39:28

🌻 前言

2023年了,国内前端领域基本被VueReact占领市场,近几年似乎前端技术栈的迭代更新缓慢了下来。

当然近几年也出现了像sveltesolid.js等一些新兴的前端框架,这些框架有很多创新的点,比如svelte相比于vue,react最大的不同,没有使用虚拟dom,将程序运行时的一系列处理移到了编译阶段,这样理论上就可以大大提高程序运行时的性能。

虽然现在国内svelte不温不火,除了它自身存在的一些问题,主要还是生态不够完善。但是它在国外是非常火的,说不定哪天这团火就烧到国內了🔥。

本文通过和vue语法逐一对比的方式,可以让熟悉vue的同学快速上手svelte~

1. 基础知识

安装svelte项目:

npx degit sveltejs/template my-svelte-project
cd my-svelte-project

npm install
npm run dev

vue页面都是以.vue结尾,而svelte页面是以.svelte结尾。(吐槽🤧:框架名起的拗口就算了,文件后缀还不能简化,这估计也是在国内流行不起来的一个原因)。

在svelte组件内可以直接写html内容,不像vue需要写在template模版中。
样式写在<style>标签中,自带 scope(样式隔离) 效果。

2. 插值表达式

vue的插值表达式是用双大括号包裹的,而svelte是用一个大括号{}包裹.

动态内容:

<script>
let name = 'world';
</script>

<h1>Hello {name}!</h1>

动态属性:

直接用{}包裹就行,如果需要拼接,可以用引号包裹,或者用模版字符串也是可以的。

ps:如果变量名和属性名一致,甚至可以简写,例如src={src}可以简写为{src}。如下:

<script>
    let src = 'https://p3-passport.byteimg.com/img/user-avatar/f51713bb5df34d682e00c40d5078b95e~180x180.awebp';
    let name = '前端阿彬的头像';
</script>

<img src={src} alt="">

<img {src} alt="图片描述:{name}">

<img {src} alt={`${src} : ${name}`}>

3. svelte里的 v-html

vue里使用v-html语法糖向指定节点中渲染包含html结构的内容,即设置元素的innerHTML

在svelte里语法是使用特殊标记{@html ...}

<script>
   let string = `<strong style="color: red">学如逆水行舟,不进则退!</strong>`;
</script>

<p>{@html string}</p>

4. svelte里的 v-model 双向绑定

在vue里,v-bind一般用来动态绑定值,v-model用来双向绑定数据。

而到了svelte里,双向绑定是用bind:标记。svelte没有类似于vue的v-bind动态绑定这一说,统统用{}插值表达式就能实现。

<script>
	let name = 'world';
</script>

<input bind:value={name}>

<h1>Hello {name}!</h1>

svelte的双向绑定有个很方便的用法,就是绑定多个值,语法为bind:group。例如在实现复选框组时,可以用bind:group绑定数据,绑定的值会形成一个数组,如下:

let list = [
    '小红',
    '小美',
    '阿彬'
];
let peoples = [阿彬'];

{#each list as people}
    <label>
            <input type=checkbox bind:group={peoples} value={flavour}>
            {people}
    </label>
{/each}

上面代码很简单就能实现一个复选框组合,值绑定给了peoples,是个数组,多个值时格式为['阿彬','小美']

5. svelte里的 v-on 事件绑定

vue绑定事件用v-on,即语法糖@
在svelte里绑定事件语法为on:事件名,如下:

function handleClick(){}

<button on:click={handleClick}>

同样,svelte也有事件修饰符,语法为on:click|once={handleClick},可以同时使用多个修饰符,例如on:click|once|capture={handleClick}

svelte的事件修饰符有:

  • preventDefault :调用event.preventDefault(),阻止默认事件;
  • stopPropagation :调用 event.stopPropagation(), 阻止冒泡;
  • passive :优化了对 touch/wheel 事件的滚动表现(Svelte 会在合适的地方自动添加滚动条);
  • capture:在捕获阶段而不是冒泡阶段触发事件处理程序;
  • once :事件只能执行一次。
  • self:仅当 event.target 是其本身时才执行。

6. svelte里的 computed + watch

svelte的$: 代码块类似于vue的 computed计算属性 和 watch状态监听 的结合体

它既能用来声明计算属性,同时可以监听数据变化执行代码块,类似于vue3的watchEffect,它不需要指定要监听的数据,只要在代码块中就会监听。

计算属性举例:

let name = '阿彬'
$: level = name + '是个前端程序员'

<p>{ level }</p>

监听数据变化:需要用{}包裹代码块

let val
$: {
	console.log(`你输入的内容是: ${val}`);
	alert(`你输入的内容是: ${val}`);
}

<input bind:value={val}>

以上代码,只要在输入框输入内容,就会弹窗提示

使用$: 监听数据变化时,可以在{}代码块前使用if语句,是不是很巧妙,能减少很多情况下的代码量。

$: if (count >= 10) {
    alert(`count is dangerously high!`);
    count = 9;
}

7. svelte里的 v-if

svelt里的v-if条件语句语法有点像uniapp的条件编译。由首尾两个标记包裹需要根据条件控制显隐的dom代码块,语法如下:

字符#始终表示块开始标记。字符/始终表示块结束标记。:中的字符表示{:else}连续标记。

svelte的逻辑语句都是用开始标记#和结束标记/包裹。 逻辑语句包括if else条件编译、each 遍历渲染await块,也就是本文7、8、9点。

{#if 条件}    
   代码块    
{/if} 

举例:

{#if user.loggedIn}
    <button on:click={toggle}>
            Log out
    </button>
{/if}

{#if !user.loggedIn}
    <button on:click={toggle}>
            Log in
    </button>
{/if}

if条件语句中的else、else if写法:

{#if x > 10}
	<p>{x} is greater than 10</p>
{:else if 5 > x}
	<p>{x} is less than 5</p>
{:else}
	<p>{x} is between 5 and 10</p>
{/if}

8. svelte里的 v-for

vue的v-for语法为v-for=(item,index) in list) :key="index"
svelte遍历渲染使用的是 each 块:

下面例子中,类比vue,cat就是遍历的item:

<script>
	let cats = [
		{ id: '1', name: 'Keyboard Cat' },
		{ id: '2', name: 'Maru' },
		{ id: '3', name: 'Henri The Existential Cat' }
	];
</script>

<ul>
    {#each cats as cat (cat.id)}
            <li><a target="_blank" href="https://www.youtube.com/watch?v={cat.id}">
                    {cat.name}
            </a></li>
    {/each}
</ul>

怎么像vue一样,增加索引当第二个参数呢,写法如下,用,逗号分隔就行:

{#each cats as cat,i}
        <li><a target="_blank" href="https://www.youtube.com/watch?v={cat.id}">
                {cat.name}
        </a></li>
{/each}

v-for里的key唯一标识符,到了svelte里,只要在each块后括号说明key是什么就行,如下,id作为key

{#each cats as cat,i (cat.id)}
    <li><a target="_blank" href="https://www.youtube.com/watch?v={cat.id}">
            {cat.name}
    </a></li>
{/each}

9. 巧妙的 await 块

如果在开发一个用户个人主页时,在数据加载时需要显示骨架屏,加载成功正常显示页面,加载失败显示错误提示。

像这种依赖于异步请求决定页面的不同显示逻辑的场景,就可以使用 svelte 的 await 标记代码块。使用方法如下:

<script>
    let promise = getRandomNumber();
    async function getRandomNumber() {
            const res = await fetch(`tutorial/random-number`);
            const text = await res.text();

            if (res.ok) {
                    return text;
            } else {
                    throw new Error(text);
            }
    }
</script>

{#await promise}
	<p>...waiting</p>
{:then number}
	<p>The number is {number}</p>
{:catch error}
	<p style="color: red">{error.message}</p>
{/await}

可以看到,可以很容易显示一个三种不同状态下的页面显示,甚至不需要声明什么变量来承接请求得到的数据,是不是很巧妙 🤙🤙🤙

如果你不需要判断请求错误的情况,则可以忽略 catch 块。如果在请求完成之前不想程序执行任何操作,也可以忽略第一个块。如下:

{#await promise then value}
	<p>the value is {value}</p>
{/await}

10. 引入组件

svelte引入使用组件类似vue3,引入就可以直接使用,不需要注册。同时要注意组件名要大写,和html标签区分开。

<script>
  import Child from './Nested.svelte';
</script>

<Child/>

11. 组件传参

vue中父组件向子组件传参,常规方式是在子组件用 props 声明可以接收的自定义属性。

而svelte则不同,它是在子组件中用 export 声明需要接收的props参数。
export导出时赋值就是设置默认值。

注意: 与vue不同,svelte子组件接收的props数据是可以在子组件里直接修改的!

//父组件
import Child from './Child.svelte';
<Child content="父组件内容"/>

//子组件
<script>
  export let content;
</script>

<p>The answer is {answer}</p>

传递多个参数: 如果你的组件含有一个对象属性,可以利用...扩展运算符一次性绑定,如下:

const pkg = {
    name: 'svelte',
    version: 3,
    speed: 'blazing',
    website: 'https://svelte.dev'
};
        
<Info {...pkg}/>
//相当于
<Info name={pkg.name} version={pkg.version} speed={pkg.speed} website={pkg.website}/>

12. 子组件自定义事件

子组件自定义事件,即实现子组件调用父组件方法。

在子组件内需要使用createEventDispatcher 在首次实例化组件时,定义一个dispatch进行连接,进而把组件实例化。具体使用如下:

//父组件
<script>
    import Inner from './Inner.svelte';

    function handleMessage(event) {
            alert(event.detail.text);
    }
</script>
<Inner on:message={handleMessage}/>

//子组件
<script>
    import { createEventDispatcher } from 'svelte';

    const dispatch = createEventDispatcher();

    function sayHello() {
        dispatch('message', {
                text: 'Hello!'
        });
    }
</script>

<button on:click={sayHello}>
	Click to say hello
</button>

如果想为组件注册dom事件,只需要在子组件内部需要触发这个事件的地方加上on:事件名就行,例如:

<button on:click>
	Click me
</button>

这样就可以在使用这个子组件时绑定on:click事件了。

13.ref 获取dom元素引用

this可以绑定到任何标签 (或组件) 并允许你获取对渲染标签的引用。 例如,我们对<canvas> 标签进行绑定:

<canvas
    bind:this={canvas}
    width={32}
    height={32}
></canvas>

注意,svelte也是有生命周期的,在onMount生命周期前,组件还没有挂载完毕,canvas的值这时候是undefined,所以如果要操作dom引用,需要在 onMount 生命周期后。

14. 生命周期

svelte的生命周期只有四个,分别是:

  • onMount:页面渲染完成后;
  • onDestroy:组件销毁前;
  • onDestroy:DOM渲染完成前执行;
  • onDestroy:在异步数据加载完成后执行;

PS:tick函数不同于其他生命周期函数,因为你可以随时调用它。它类似于vue的nextTick,每当组件pending状态变化便会立即体现到DOM中 (除非没有pending状态变化)。

15.数组/对象赋值

由于 Svelte 的响应式是由赋值语句触发的,因此使用数组的诸如 pushsplice 之类的方法就不会触发自动更新视图。

解决该问题的一种方法是多执行一个赋值的语句:

function addNumber() {
    numbers.push(numbers.length + 1);
    numbers = numbers;
}

但还有一个更惯用的解决方案:

function addNumber() {
   numbers = [...numbers, numbers.length + 1];
}

你可以使用类似的模式来替换 popshiftunshiftsplice 方法。

另外,需要注意只有被更新的变量名称出现在赋值语句的左侧,才能在变量变化时更新其视图。例如下面这种情况视图是不会修改的:

<script>
    const obj = {
        foo: {
           name: '阿彬'
        }
    }
    const foo = obj.foo;
    
    const handleClick = () => {
      foo.name = '小美'  //因为obj没出现在赋值表达式左侧,所以下面的p标签内容不会变化
    }
</script>

<p>{ JSON.stringify(obj) }</p>
//在输入内容时,上面的p标签显示不会变化
<input bind:value={ foo.name }>
//点击时,上面的p标签显示也不会变化
<button on:click={handleClick}>测试</button>

🎁 说在最后

svelte的使用还是很简单的,如果你会vue,相信你花5分钟读完这篇文章,就可以上手开发svelte了 🥳🥳🥳

我是喜欢归纳总结前端相关知识的前端阿彬,尽力持续输出原创优质文章,欢迎点赞关注😘

表情包2.webp

往期文章
# 🧙‍♀️css魔法:伪元素content ➕ css函数
# 玩转css逐帧动画,纯css让哥哥动起来💃
# 🕸2023 前端 SEO 无死角解读
# 我给自己搭建的前端导航网站,你们都别用🤪
# 2023 最新最细 vite+vue3+ts 多页面项目架构,建议收藏备用!
# 浅谈 强制缓存/协商缓存 怎么用?
# 2023 前端性能优化清单

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/712491.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SSTI-lab

Level-1 no waf {{2*2}}测试发现存在ssti漏洞 {{.__class__}}{{.__class__.__bases__[0]}}{{.__class__.__bases__[0].__subclasses__}}import requestsurl"http://node1.anna.nssctf.cn:28430/level/1"#payload{{.__class__.__bases__[0].__subclasses__()[1]}} …

基于智慧消防系统的建设与应用

安科瑞 华楠 【摘要】随着“智慧城市”建设热潮的兴起&#xff0c;对推动人类社会发展与进步发挥重要作用&#xff0c;而“智慧消防”作为“智慧城市”的重要组成部分&#xff0c;其建设工作也越来越受到社会各界人士的高度关注&#xff0c;这对推动“智慧城市”构建发挥作用。…

途乐证券|Prada总部上海荣宅失事?230亿龙头突现重大利空,黑马也被带崩

Prada和蔡徐坤同时刷屏&#xff01; 今天一早&#xff0c;Prada冲上微博热搜&#xff0c;原因是有网友称&#xff0c;“Prada总部上海荣宅起火”&#xff0c;相关视频在网上热传。据上海静安消防发布火情通报&#xff0c;2023年7月2日18时14分&#xff0c;静安区陕西北路靠近南…

登录校验-会话技术/JWT令牌

登录校验 会话技术 会话&#xff1a; 用户打开浏览器&#xff0c;访问web资源的时候&#xff0c;会话建立。直到一方断开连接&#xff0c;会话结束&#xff0c;一次会话中包含多次响应 会话跟踪&#xff1a;一种维护浏览器状态的方法&#xff0c;服务器需要识别多次请求是否来…

【MySQL】count()查询性能梳理

【MySQL】count()查询性能梳理 1、背景 使用的数据库是MySQL8&#xff0c;使用的存储引擎是Innodb。 通常情况下&#xff0c;分页接口一般会查询两次数据库&#xff0c;第一次是获取具体数据&#xff0c;第二次是获取总的记录行数&#xff0c;然后把结果整合之后&#xff0c…

【VB6|第19期】vb6通过COM组件操作Excel

日期&#xff1a;2023年7月3日 作者&#xff1a;Commas 签名&#xff1a;(ง •_•)ง 积跬步以致千里,积小流以成江海…… 注释&#xff1a;如果您觉得有所帮助&#xff0c;帮忙点个赞&#xff0c;也可以关注我&#xff0c;我们一起成长&#xff1b;如果有不对的地方&#xff…

软件测试工程师必备的27个基础技能

混迹于软件测试这么长时间了&#xff0c;一直想写一篇关于软件测试的经验分享的文章&#xff0c;但苦于工作原因迟迟未下笔。最近终于有了些闲余时间&#xff0c;遂决定把自己的心路历程及所感所想记录下来&#xff0c;与各位同行共勉。 以我多年的工作经验来看&#xff0c;软…

处理glibc堆栈缓冲区溢出漏洞(CVE-2018-11236)

GNU C Library&#xff08;又名glibc&#xff0c;libc6&#xff09;是一种按照LGPL许可协议发布的开源免费的C语言编译程序。 GNU C库&#xff08;aka glibc或libc6&#xff09;中的stdlib/canonicalize.c处理非常长的路径名参数到realpath函数时&#xff0c;可能会遇到32位体系…

判断平台现货白银价格趋势方法有哪些?

新手投资者面对平台现货白银走势总是束手无策&#xff0c;那是因为新手投资者对市场的运行规律&#xff0c;以及对一些常用的技术分析工具并不熟悉&#xff0c;最后无法判断市场走向&#xff0c;所以交易获利也无从谈起。下面&#xff0c;我们一起来讨论一些可以判别趋势的工具…

imazing是什么软件? iMazing 2.17.3备份神器,iPhone相册管理超方便!!!

相信很多小伙伴们听说过imazing&#xff0c;那么imazing这是一款什么软件呢&#xff0c;imazing是一款iOS设备管理软件&#xff0c;这款软件支持对基于iOS系统的设备进行数据传输与备份。 imazing是什么软件 答&#xff1a;imazing是一款iOS设备管理软件。 imazing是一款iOS设…

Steam搬运饰品诈骗套路,及补救措施

这几个月&#xff0c;圈内频频有人曝出Steam库存饰品被盗。今天我就来聊聊饰品安全问题&#xff0c;相信也是大家最关注的问题。 其实&#xff0c;市面上绝大多数库存被盗问题都是因为Steam安全信息泄露导致的。 最常见的钓鱼信息就是从Steam自身而来&#xff0c;例如Steam好友…

【测试数据】关于多路播放在mesh中卡顿问题

测试环境 ![(https://img-blog.csdnimg.cn/ab2c3fb7f4b945c3af2a8ecf36bd3d99.jpeg#pic_center) 各种场景数据 WEB端播放 web6路 VID_3路慢点 web第三路慢点 客户端播放 客户端6路 客户端vsWeb wifi vS mesh wifi Vs Mesh链路 wifi下还是很流畅&#xff0c;九路

用C语言实现“括号匹配“问题

&#x1f388;个人主页:&#x1f388; :✨✨✨初阶牛✨✨✨ &#x1f43b;推荐专栏1: &#x1f354;&#x1f35f;&#x1f32f;C语言初阶 &#x1f43b;推荐专栏2: &#x1f354;&#x1f35f;&#x1f32f;C语言进阶 &#x1f511;个人信条: &#x1f335;知行合一 &#x1f…

Springboot整合Activiti详解

文章目录 版本依赖配置文件需要注意的问题画流程图activiti服务类进行编写流程部署流程定义启动流程流程实例 测试流程启动流程完成任务受理任务 版本依赖 开发工具 IDEASpringBoot 2.4.5&#xff08;这里我试过SpringBoot 3.1.1版本&#xff0c;Activiti没有启动&#xff0c;…

现代卓越首席咨询顾问张智喨受邀为第十二届中国PMO大会演讲嘉宾

现代卓越首席咨询顾问张智喨老师受邀为由PMO评论主办的2023第十二届中国PMO大会演讲嘉宾&#xff0c;演讲议题&#xff1a;BANI时代下如何打造价值导向型PMO。大会将于8月12-13日在北京举办&#xff0c;敬请关注&#xff01; 议题简要&#xff1a; 在BANI时代下&#xff0c;企…

机器学习14:稀疏性-Sparsity

现实世界中&#xff0c;问题的特征的数量往往是很大的&#xff0c;而其中起决定性作用的往往是很小的一部分&#xff0c;稀疏规则化算子的引入会学习去掉这些没有信息的特征&#xff0c;也就是把这些特征对应的权重置为 0。 1.稀疏性正则化&#xff1a;L₁ 正则化 稀疏向量通常…

Docker容器初识篇

学习-https://vuepress.mirror.docker-practice.com/basic_concept/container/ https://www.bookstack.cn/cate 什么是Docker Docker 和传统虚拟化方式的不同之处。传统虚拟机技术是虚拟出一套硬件后&#xff0c;在其上运行一个完整操作系统&#xff0c;在该系统上再运行所需应…

时间序列分解 | Matlab集合经验模态分解EEMD的信号分解

文章目录 效果一览文章概述部分源码参考资料效果一览 文章概述 时间序列分解 | Matlab集合经验模态分解EEMD的信号分解 部分源码 %--------------------

JavaWeb学习路线(10)—— 关于SpringBoot的原理

一、配置文件优先级 在Springboot框架三s种配置文件的格式 application.propertiesapplication.ymlapplication.yaml Springboot是支持多配置文件的&#xff0c;所以当我们使用两种配置文件配置相同参数时&#xff0c;Springboot会执行哪一个配置文件呢&#xff1f;这就是Sp…

FFmpeg5.0源码阅读—— avcodec_open2

摘要&#xff1a;本文主要描述了FFmpeg中用于打开编解码器接口avcodec_open2大致流程的具体调用流程&#xff0c;详细描述了该接口被调用时所作的具体工作。   关键字&#xff1a;ffmpeg、avcodec_open2大致流程   注意&#xff1a;读者需要了解FFmpeg的基本使用流程&#…