最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 简简单单才是真,初试 Svelte

    正文概述 掘金(LeanCloud)   2021-04-23   675

    作者:LeanCloud weakish

    最近团队内部需要一个上传文件的 web 小工具,需要写一个简单的前端页面。 像这样的小工具,如果引入 React 和 Vue,似乎太重了,所以想尝试下 Svelte 这个无框架之框架(最终会编译成不带框架的 JS 代码)。

    闲话少叙,直接上手。 首先,生成模板项目:

    npx degit sveltejs/template fileup
    

    长期以来 Svelte 的一大痛点是不支持 TypeScript,不过去年开始也加入了 TypeScript 支持。 当然,像这样简单的小工具,直接用 JavaScript 写也没什么差别。 不过我还是打算用下 TypeScript。

    和其他一些模板生成工具不同,Svelte 官方没有提供单独的 TypeScript 模板项目仓库,也不会在生成模板的过程中让你选择是用 TypeScript 还是 JavaScript,而是在生成模板项目后,运行一个脚本把项目转成 TypeScript 项目:

    node scripts/setupTypeScript.js
    

    转换之后,执行常规的依赖安装步骤,就可以运行了:

    npm install
    npm run dev
    

    项目使用 npm 管理依赖,使用 rollup 打包,这些都不用操心,对于简单项目而言,只需修改 src/App.svelte 即可,模板、样式、交互逻辑都写在这一个文件中(这和 Vue 有点像):

    <script lang="ts">
    // TypeScript 代码
    </script>
    
    <style>
    /* CSS 代码 */
    </style>
    
    <!-- Svelte 模板代码 -->
    

    先来编写上传界面,google 一下,找到一个现成的组件 svelte-file-dropzone

    npm i svelte-file-dropzone
    

    将它加入依赖,在 App.sveltescript 部分引入,并编写相应的 TypeScript 代码和 Svelet 模板代码:

    <script lang="ts">
    import Dropzone from "svelte-file-dropzone";
    
    let files: File[]
    function handleFilesSelect(e) {
        files = e.detail.acceptedFiles
    }
    </script>
    
    <Dropzone on:drop={handleFilesSelect}>
      Click to select files, or drag and drop some files here.
    </Dropzone>
    

    获取选定的文件之后,再上传文件。 文件会上传到 LeanCloud,LeanCloud 是一家 BaaS 云服务商,也提供文件托管服务。 「svelte」的意思是「slender and elegant」,和「lean」也算是近义词,从这个角度说,这两个听起来还挺配的。

    同样,我们先把 LeanCloud 的 JavaScript SDK 加入依赖:

    npm i leancloud-storage
    

    然后初始化 SDK:

    import LC from "leancloud-storage";
    
    const appId = "your app id";
    const appKey = "your app key";
    const serverURL = "https://your-custom-domain.example.com";
    
    LC.init({
        appId,
        appKey,
        serverURL,
    });
    

    appIDappKey 可以从 「LeanCloud 控制台 > 设置 > 应用 Keys」查看,serverURL 是在 LeanCloud 绑定的域名。 当然,这需要首先在 LeanCloud 注册账号并创建应用。 应有关部门的要求,LeanCloud 国内版需要绑定已备案的域名,如果不想绑域名或者域名没有备案,可以用 LeanCloud 国际版。

    国际版初始化时无需传入 serverURL

    LC.init({
        appId,
        appKey
    });
    

    上传文件非常简单,只需两行代码:

    async function uploadFile(toUpload): Promise<String> {
        const uploaded = await new LC.File(toUpload.name, toUpload).save();
        return uploaded.get("url");
    }
    

    上面的代码中,用 new LC.File(文件名, 文件) 构建文件后,调用 save 方法保存到云端,之后就可以通过 url 属性得到可以访问该文件的 URL。

    到目前为止,我们已经完成了最核心的功能,选取文件和上传文件,只剩下最后一步,把获取的 URL 显示给用户了。

    {#if files}
      <h2>Files</h2>
      {#each files as file, i}
        {#await uploadFile(file)}
          <p>Uploading {file.name} ({file.size} bytes) ...</p>
        {:then url}
          <p>Uploaded:
            <code>{url ?? ""}</code>
          </p>
        {:catch error}
          <pre>{error}</pre>
        {/await}
      {/each}
    {/if}
    

    这里用到了 Svelte 的模板语法。 估计是为了节省写解析器的功夫,Svelte 的模板语法看起来有点别扭(#if/if:catch),但是忽略这些视觉上小小的不适,整体上还是清晰易读的。 先用 if 判断是否选取了文件,只有在选取了文件的情况下,才会显示文件列表。 接着用 each 遍历所有选中文件,进行上传操作,并在上传过程中显示文件的名称和大小,上传完成后则显示文件的 URL。 当然,几乎所有程序都少不了错误处理的部分。 因为这是一个内部工具,所以就直接在网页上显示错误信息了,没额外做更多处理。 注意这里用了 await 等待上传文件的异步函数返回结果,获取到结果后将它赋值给 url 变量,然后就可以直接在界面中使用 url 变量了。

    好了,大功告成,不到 50 行代码,就完成了这个简单的上传工具。 回头看看代码,非常直截了当。 但仔细想想,还是很神奇的,比如只是通过 files = e.detail.acceptedFiles 这一行赋值操作,界面就能感知到 files 的变化,相应地渲染不同的内容。 这是因为 Svelte 会把 = 编译为类似 React 等框架中的 setState 方法。 有些人可能觉得这有些太魔法了,但其实大多数编程语言中 = 就挺魔法的,比如会有 x = x + 1; 这样的语句,只是大家都习惯了而已。

    最后需要把它部署到一个地方。 因为是个纯静态页面,所以部署到什么地方都行。 既然文件托管已经用了 LeanCloud,那网页也部署到 LeanCloud 吧。

    运行以下命令编译、打包项目:

    npm run build
    

    然后运行以下命令即可部署至 LeanCloud:

    cd public
    lean switch --region CN --group web YOUR_APP_ID
    lean deploy --prod 1
    

    这里 CN 表示 LeanCloud 华北节点,web 是云引擎分组的名称,如果使用了其他节点或者 LeanCloud 国际版,或者分组名称不同,需要修改相应的值,具体可以查看「LeanCloud 控制台 > 云引擎 > 云引擎分组 > 部署 > 命令行工具」的说明。

    如果没有安装 LeanCloud 命令行工具,需要先安装并关联账号,关联账号的步骤同样可以上述控制台区域找到。 另外,要访问部署在云引擎上的页面,还需要绑定一个云引擎域名,或者申请一个 avosapps.us 下的子域名(仅限国际版)。

    下面是部署后的效果图:

    简简单单才是真,初试 Svelte

    可以看到,为了方便复制 URL,我加了复制到剪贴板的按钮。 使用 svelte-copy-to-clipboard 组件:

    npm i svelte-copy-to-clipboard
    

    只需添加 10 行代码:

    <script lang="ts">
    import CopyToClipboard from "svelte-copy-to-clipboard";
    // 略
    
    function handleSuccessfulCopy(i) {
        copyStatuses[i] = '✅'
    }
    function handleFailedCopy(i) {
        copyStatuses[i] = '❌'
    }
    </script>
    
    <!-- 略 -->
    {#if files}
      <h2>Files</h2>
        <!-- 略 -->
        {:then url}
          <p>Uploaded:
            <code>{url ?? ""}</code>
            <CopyToClipboard text={url} on:copy={() => handleSuccessfulCopy(i)} on:fail={() => handleFailedCopy(i)} let:copy>
              <button on:click={copy}>{copyStatuses[i]}</button>
            </CopyToClipboard>
          </p>
      <!-- 略 -->
    {/if}
    

    如果希望进一步改善用户体验,还可以在上传时显示进度。 这项改进就留给读者作为练习(提示)。

    不能免俗,用 LightHouse 跑个分:

    简简单单才是真,初试 Svelte

    之前写页面的时候我并没有考虑性能,但性能评分仍然达到了 100。 SEO 和可访问性方面有些小问题,改起来不麻烦,同样留给读者作为练习。 好吧,你也许已经发现了,我只是在为我自己的懒惰找借口。 不过,如果你真的完成了这些练习,欢迎来提 pr。

    写到这里差不多要结束了,总结一下。 就小工具和交互不多的站点而言,Svelte 写起来更加直截了当,和 React、Vue 相比,编写的代码更加简明扼要, 套路代码(boilerplate code)更少,编译出的代码更加轻量,因此对个人健康(节省键盘敲击次数,避免肌肉劳损)和世界环境(访问者加载和运行的代码更少,显著降低碳排量)都更友好。 Svelte 这样的无框架(frameless)框架和 LeanCloud 这样的无服务器(serverless)云服务,抽象掉了大量无关业务的细节,可以让开发者专注项目的核心功能,提升开发效率,改善开发体验。

    题图 Paul Gilmore


    起源地下载网 » 简简单单才是真,初试 Svelte

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元