前端

使用sveltekit开发一个服务端渲染(SSR)项目

月盾
上篇简单介绍了sapper和sveltekit的发展,目前sveltekit还只是Beta版本,有很多不确定因素存在,有可能会有大的变更,所以还不推荐在生产环境中使用,不过在个人项目和小项目中可以大胆尝试。 今天我们就正式使用sveltekit开发一个web项目。 第一步:创建项目 mkdir my-app cd my-app npm init svelte@next npm install npm run dev 这样就可以创建一个简单的项目了,不过和我们真实需求还有些差距,既然是使用sveltekit,那么最重要的原因是其支持服务端渲染了。这就需要从服务端获取数据,接下来就实现这样的需求。 第二步:路由 和sapper一样,sveltekit也是基于文件系统的的路由器,这就需要我们来合理的组织目录结构。路由的核心目录是src/routes,当然,这个也是可配置的,按照自己的需求修改svelte.config.cjs,参考文档:https://kit.svelte.dev/docs#configuration。 我们以一个博客系统为例,在scr/routes下创建blog目录,光有目录还不行,如果想要访问 /blog 路由,还需要创建index.svelte文件,内容如下: <script context="module"> /** * @type {import('@sveltejs/kit').Load} */ export async function load({ page, fetch, session, context }) { return fetch(`blog.json`)// index.json.js = blog.json或blog/blog.json .then((r) => r.json()) .then((posts) => { console.log(posts); return { props: { posts } }; }); } </script> <script> export let posts; </script> <svelte:head> <title>Blog</title> </svelte:head> <h1>Recent posts</h1> <ul> {#each posts as post} <!

关于svelte框架——sapper和sveltekit的发展

月盾
虽然您可能现在还没有听说过svelte,但是其实svelte的发展速度超过了你的想象。 本文主要讲的是关于sapper和sveltekit这两款框架的发展。 svelte作者里奇·哈里斯(Rich Harris)在2020年10月的svelte峰会上表示:sapper永远不会发布1.0版本。 也就是说sapper不会发布正式版,一直处于非稳定版本。也可能放弃更新。 主要原因是sapper多年来代码库变得凌乱,但更主要的原因是最近网络发生了很大变化。 而作者放弃sapper后的另一种选择是开发SvelteKit。 Sapper和SvelteKit都是svelte的开发框架,类似于vue的nuxt框架。 sveltekit包含的功能有: 服务端渲染(SSR) 路由 typescript支持 less, scss支持 serverless vite打包 可以看到,sveltekit几乎包含了所有我们想要的功能,既能高效开发,又有高性能。 创建sveltekit的方法: mkdir my-app cd my-app npm init svelte@next npm install npm run dev 需要注意,您的nodejs版本需要更新到v12以上,否则可能出现以下错误: $ npm run dev -- --open > sveltekit-app@0.0.1 dev D:\workspace\sveltekit-app > svelte-kit dev "--open" D:\workspace\sveltekit-app\node_modules\@sveltejs\kit\svelte-kit.js:2 import './dist/cli.js'; SyntaxError: Unexpected string at Module._compile (internal/modules/cjs/loader.js:723:23) at Object.Module._extensions..js (internal/modules/cjs/loader.

svelte history路由刷新后404

月盾
npms.io上搜索到svelte的route包其实也不算少,使用比较广泛的svelte-spa-router路由包却不支持history模式。有些支持history模式的使用上也不是很方便,试用过五六个支持history的路由后最终@spaceavocado/svelte-router算是满足了要求。 使用简单 功能丰富 支持history和hash 我也是够难伺候的。 在试用了多个支持history的路由过程中,都遇到了一个问题:切换路由后刷新404。这也算是单页应用的通病了。不过像vue这种是在部署到服务器上刷新404,而svelte却在开发过程中也出现了,又想放弃了… 好在我也是试用过五六七八个路由的人了,中间不知道尝试过多少种方法来实现history路由。最后使用@spaceavocado/svelte-router包实现了history路由的时候我还是满心欢喜。 使用方法: //App.svelte <script> import RouterView from '@spaceavocado/svelte-router/component/view'; import { routes } from './router.js' </script> <RouterView /> //router.js import createRouter from '@spaceavocado/svelte-router'; import index from './index/index.svelte'; import a from './a/a.svelte'; import b from './b/b.svelte'; export const routes = createRouter({ mode: "HISTORY", routes: [ { path: '/', name: 'HOME', component: index, }, { path: '/a', name: 'a', component: a, }, { path: '/b', name: 'b', component: b, }, { path: '*', component: index, }, ], }); // index.
基于sapper开发svelte项目配置本地代理

基于sapper开发svelte项目配置本地代理

月盾
sapper可能被放弃更新,如果您要继续使用svelte,可以考虑使用sveltekit 最近使用svelte开发一个项目,说实在的,开发过程中遇到不少问题。 每次遇到问题的时候都有种想放弃的冲动,这生态也太差了,查个啥啥问题都查不到,找个啥啥插件也没有。 不过,到最后,遇到的问题又都解决了。 这不,今天又遇到了本地代理的设置问题。 在说遇到的问题之前先介绍一些项目架构。该项目是基于sapper框架开发,这是一个使用svelte开发的框架,具备以下特点: 服务端渲染 路由 代码分割 默认支持渐进式web应用(PWA) 预取路由 单独的头标签(meta,link等) 作为静态站点弹出 Cypress测试(免费,简单,端到端的测试) 可以看到,sapper基本是集合了目前前端开发所有需求,双向数据绑定,渐进式开发,SSR,静态化,高性能。 遇到的新问题:对于前端项目,调用接口时容易遇到跨域问题,一般是使用本地代理解决。自然也想这样来做,可是sapper没有vue项目那样的生态,用的打包工具也不是webpack,而是rollup。 那么就使用sapper自带的服务端来做代理好了。sapper的服务端用的是polka,而不是express,不过没关系,其实可以相互替换。 最关键的是增加了http-proxy-middleware中间件,却对中间件位置很敏感,不是想随便在哪添加一下就行。需要添加在第一个中间件位置,否则就会优先使用静态服务中间件,导致接口找不到。 完整代码: import sirv from 'sirv'; import polka from 'polka'; import compression from 'compression'; import * as sapper from '@sapper/server'; import { createProxyMiddleware } from 'http-proxy-middleware'; const { PORT, NODE_ENV } = process.env; const dev = NODE_ENV === 'development'; polka() // 需要放在最前面,否则接口404,secure参数解决调用https问题 .use('/api', createProxyMiddleware({ target: 'https://example.com', pathRewrite: { '^/api': '' }, secure: false, changeOrigin: true, })) .

svelte项目rollup配置px2rem

月盾
使用svelte开发项目时遇到需要将px转换成rem的需求,有试过postcss-px2rem,postcss-pxtorem,等postcss插件,都没成成功,最后找到了postcss-units插件成功实现。 完整rollup配置文件如下: converts px to rem 该配置是sapper项目配置 import path from 'path'; import resolve from '@rollup/plugin-node-resolve'; import replace from '@rollup/plugin-replace'; import commonjs from '@rollup/plugin-commonjs'; import url from '@rollup/plugin-url'; import svelte from 'rollup-plugin-svelte'; import babel from '@rollup/plugin-babel'; import { terser } from 'rollup-plugin-terser'; import config from 'sapper/config/rollup.js'; import pkg from './package.json'; import sveltePreprocess from 'svelte-preprocess'; // import { less } from 'svelte-preprocess'; const postcssUnits = require('postcss-units'); const mode = process.env.NODE_ENV; const dev = mode === 'development'; const legacy = !

svelte函数传参

月盾
svelte给dom对象绑定事件和vue框架类似。 定义函数: function handler(index){ alert("hello", index); } 绑定事件: <button on:click={handler}>点击</button> 但是带参函数的使用就略有不同了,函数handler的参数index需要传入的时候,不能直接这样使用<button on:click={handler(123)}>点击</button>,这样的写法会在页面打开时直接执行,而不是在点击按钮的时候执行。 这是初学svelte的时候比较郁闷的事,官方文档中也没有明显的文档说明如何传参。 正确的传参方式是这样的: <button on:click={() => handler(123)}>点击</button> 将on:click的内容改写为匿名函数,在函数中调用。

Svelte3路由

月盾
svelte目前没有提供官网路由组件,不过可以在社区中找到。本文介绍的是svelte-spa-router的使用方法。 npm i svelte-spa-router 参考以下目录结构创建文件(不是必须) router.js: import index from './index/index.svelte'; import a from './a/a.svelte'; import b from './b/b.svelte'; export const routes = { '/': index, '/a': a, '/b': b } 动态导入组件和代码分割: import { wrap } from 'svelte-spa-router/wrap' import index from './index/index.svelte'; export const routes = { '/': index, '/a': wrap({ asyncComponent: () => import('./a/a.svelte') }), // '/b': b // 动态加载 '/b': wrap({ asyncComponent: () => import('./b/b.svelte') }), } 动态导入组件的优点是组件不会一起打包,而是单独的组件文件,在打开对应的页面时才会请求,可以有效减少包文件大小。 App.

vue nuxt组建注册

月盾
Nuxt.js 2.13+可以扫描并自动导入您的组件,不再需要在该script部分中手动导入它们! nuxt.config配置: export default { components: true } 设置为true或使用对象时,它将包含nuxt / components依赖项,并且~/components在模板中使用它们时会自动导入您的组件。 组件目录: components/ ComponentFoo.vue ComponentBar.vue 使用 <template> <ComponentFoo /> <component-bar /> </template> 注意:如果使用nuxt 2.10…2.13,则还必须手动安装并添加@nuxt/components到buildModulesinside nuxt.config。

vue子组件修改父组件的数据

月盾
vue在子组件中直接修改父组件传递下来的数据会报错: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "json" 原因是vue子组件不能直接修改父组件的数据,可以使用this.$emit发送通知,让父组件来修改。 示例代码: 子组件: this.$emit("changeData", "要修改的数据"); 父组件: <mycomponent :json="JsonData" @changeData="changeData"></mycomponent> data(){ return { JsonData:{} } } methods:{ changeData(newData){ this.JsonData = newData; } } 子组件发送changeData事件, 父组件绑定changeData事件并接受数据,赋值给父组件的JsonData属性,子组件的值也会改变。从而实现子组件修改父组件的属性值。

原生js实现图片预览

月盾
不依赖jquery也可以实现图片预览功能: <!--图片放大后的div 开始 这块粘贴在你的html中最后body前 --> <div id="outerdiv" style="text-align: center;position: fixed;z-index: 9999;top: 0;left: 0;width: 100%;height: 100%;background-color: rgba(28,28,28,0.9);"> <img id="bigimg" style="max-height: 800px;max-width: 100%;border: 0;margin: auto;position: absolute;top: 0;bottom: 0;left: 0;right: 0;" src="" /> </div> <!--图片放大后的div 结束 这块粘贴在你的html中最后body前--> <!--js开始 是放大点击的触发事件 这块粘贴在你的html中最后body前--> <script type="text/javascript"> //图片放大 document.querySelector("#outerdiv").style.display = "none"; document.querySelectorAll("img").forEach(function (item) { item.style.cursor = "pointer"; }); document.querySelectorAll("img").forEach(function (item) { item.addEventListener("click", function () { imgShow("#outerdiv", "#bigimg", this); }) }) function imgShow(outerdiv, bigimg, _this) { var src = _this.