背景
最近需要给App
写几个h5
页面,没有复杂的交互,纯展示的内容多。如果引入Vue
的话,有点杀鸡焉用牛刀的感觉!之前了解过学习过Svelte
,正好是一次尝鲜的机会! 点击学习Svelte 入门教程!
初始化项目
Vite
官方提供了一个Svelte
和Svelte-ts
两个版本的模板——在线体验地址。
# npm 6.x
npm create vite@latest vite-svelte --template svelte
# npm 7+, extra double-dash is needed:
npm create vite@latest vite-svelte -- --template svelte
# yarn
yarn create vite vite-svelte --template svelte
# pnpm
pnpm create vite vite-svelte -- --template svelte
安装运行项目:
cd vite-svelte
yarn
yarn dev
open http://localhost:30000
引入路由
我用的是svelte-spa-router
,因为它的使用方式更接近vue-router
,用起来简单。
yarn add svelte-spa-router
// router/index.js
import List from '@/views/List.svelte'
import Detail from '@/views/Detail.svelte'
export default {
'/list': List,
'/detail/:id': Detail
}
// App.svelte
import Router, {link} from 'svelte-spa-router';
import routes from './router/index.js'
<Router {routes} />
use:link
import Router, {link} from 'svelte-spa-router';
<a href="javascript;" use:link={'/list'}>To List</a>
<a href="javascript;" use:link={'/detail/1?name=finget'}>To Detail</a>
编程式路由
svelte-spa-router
提供了三个方法push
,pop
,replace
,看名字也知道是什么意思了。
import {push, pop, replace} from 'svelte-spa-router'
push('/detail/42')
pop()
replace('/list')
获取路由参数
// views/Detail.svelte
<script>
import {querystring} from 'svelte-spa-router';
export let params = {}
</script>
<div>
<p>params id is {params.id}</p>
<p>query is {$querystring}</p>
</div>
动态组件
svelte-spa-router
也是支持异步动态组件的。
// router/index.js
import {wrap} from 'svelte-spa-router/wrap'
import List from '@/views/List.svelte'
export default {
'/list': List,
'/detail/:id': wrap({
asyncComponent: () => import('@/views/Detail.svelte')
})
}
引入tailwindcss
安装官网的方式安装:
yarn add -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
这时候重启项目,正常情况下会报错require() of ES modules is not supported
,不支持ES modules
解决方案在这里: github.com/vitejs/vite…
npx svelte-add@latest tailwindcss
接着再运行会提示没有安装svelte-preprocess
,重新安装一下就行了。
yarn add svelte-preprocess -D
到这里tailwindcss
就算成功引入了!
<a href="javascript;" class="font-medium text-xl underline text-red-400" use:link={'/list'}>To List</a>
<a href="javascript;" class="font-medium text-xl underline text-red-400" use:link={'/detail/1?name=finget'}>To Detail</a>
引入 axios
yarn add axios
// utils/request.js
// Api.js
import axios from "axios";
// Create a instance of axios to use the same base url.
const axiosAPI = axios.create({
baseURL: "https://xxxx.typicode.com", // it's not recommended to have this info here.
withCredentials: true,
timeout: 10000
});
// implement a method to execute all the request from here.
const apiRequest = (method, url, request) => {
const headers = {
authorization: ""
};
//using the axios instance to perform the request that received from each http method
return axiosAPI({
method,
url,
data: request,
headers
}).then(res => {
return Promise.resolve(res.data);
}).catch(err => {
return Promise.reject(err);
});
};
// function to execute the http get request
const get = (url, request) => apiRequest("get", url, request);
// function to execute the http delete request
const deleteRequest = (url, request) => apiRequest("delete", url, request);
// function to execute the http post request
const post = (url, request) => apiRequest("post", url, request);
// function to execute the http put request
const put = (url, request) => apiRequest("put", url, request);
// function to execute the http path request
const patch = (url, request) => apiRequest("patch", url, request);
// expose your method to other services or actions
export { get, deleteRequest, post, put, patch };
proxy
// vite.config.js
...
export default defineConfig({
return {
...
server: {
port: 3344,
proxy: {
'/api': {
target: 'http://api.coindesk.com',
changeOrigin: true,
secure: true,
pathRewrite: {
'^/api': ''
}
}
}
},
...
}
})
状态管理-实现一个简易的Toast组件
Svelte
自带状态管理store
,语法层面本文介绍太多,大家看下面的事例,运行一下项目,就能理解了,官网的教程写的特别好,更多的细节建议去Svelte 官网学习了解!
// components/Toast
// toasts.svelte
<script>
import { flip } from 'svelte/animate';
import { toasts } from './toastStore';
</script>
{#if $toasts.length}
<div class="fixed top-0 z-50">
<ul class="">
{#each $toasts as toast (toast.id)}
<li animate:flip class="totast text-white px-5 py-2 rounded-2xl mb-2">
{@html toast.msg}
</li>
{/each}
</ul>
</div>
{/if}
// toastStore.js
import { writable } from 'svelte/store';
export const toasts = writable([]);
/**
*
* @param msg 提示信息,可以是任意html内容
* @param type 信息类型
* @param removeAfter 清除时间,单位:秒
* @param handler 手动删除
* @returns id of Toast
*/
export function addToast(msg, type = 'info', handler = false, removeAfter = 2000) {
const id = new Date().valueOf() + msg;
toasts.update((all) => [
{
id,
msg,
type,
removeAfter
},
...all
]);
if(!handler) {
setTimeout(() => {
removeToast(id);
}, removeAfter);
}
return id;
}
export function removeToast(id) {
toasts.update((all) => all.filter((toast) => toast.id !== id));
}
如何使用:
<script>
import Toasts from '@/components/Toast/Toasts.svelte';
import {addToast} from '@/components/Toast/toastStore.js';
const handleToast = () => {
addToast('hello world')
}
</script>
<div class="p-4 bg-gray-600 w-1/2 rounded text-white mx-auto active:opacity-70" on:click={handleToast}>消息提示</div>
移动端调试神器 vconse
yarn add vite-plugin-vconsole -D
// vite.config.js
import { viteVConsole } from 'vite-plugin-vconsole';
export default defineConfig(({command, mode}) => {
// console.log(command, mode)
return {
plugins: [
svelte(),
viteVConsole({
entry: [path.resolve('src/main.js')], // entry for each page, different from the above
localEnabled: command === 'serve',
enabled: command === 'serve',
config: {
maxLogNumber: 1000,
theme: 'dark'
}
})
],
...
}
})
其他
用vscode开发项目,下载插件Svelte 3 Snippets
,Svelte Auto Import
,Svelte for VS Code
,定会事半功倍!
还有可能遇到的一个小问题,在style
标签处可能会提示一个红线错误,这时你查看错误信息找到对应的包的地址,我的是/Users/finget/.vscode/extensions/svelte.svelte-vscode-105.16.0
,进入这个目录,安装一下less
就好了。
感受
-
个人感觉
Svelte
的语法和Vue
和React
有很多相似之处,对于熟悉Vue
或React
的同学,上手难度不大。 -
编译速度上,
Vite
+Svelte
是真的快,几乎同等代码量(初始化+几个简单的页面)的情况下,比Vite
+Vue3
快的多。
Svelte
最大缺点就是社区不够强大,使用人数不多,容易踩坑,希望能越来越好!但是作为开发一些官网呀,博客,H5活动页的项目,用起来还是得心应手,值得大家尝试!
文中Demo代码地址: github.com/FinGet/vite…