前期准备
安装node.js最新版本
开发工具
vscode 或者webstorm
创建项目
cd到要创建的目录下
vite创建
使用 NPM:
$ npm init vite@latest
使用 Yarn:
$ yarn create vite
使用 PNPM:
$ pnpx create-vite
项目创建好之后选择svelte模板,选择js或者ts模板
cd到创建好的项目目录下,安装依赖
npm install
安装好后,运行项目
npm run dev
没有报错后会运行在 http://localhost:3000/
ps:有报错的再次npm install
打开http://localhost:3000/ 看下默认项目效果
我们看到的是一个可点击的按钮效果,其实这是一个svelte组件做的,里面包含了html+css+js。
项目结构
因为这是vite打包工具创建的,里面的一些设置这里不再提及,感兴趣自己去看
我们从svelte用法切入。
main.ts和index.html
main.ts
import App from './App.svelte'//从svelte引入App类
const app = new App({ //实例化一个App类,名为app
target: document.getElementById('app')//将其挂载在到id='app'的元素上
})
export default app//抛出app
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Svelte + TS + Vite App</title>
</head>
<body>
<!-- App.svelte的内容将呈现在id='app'的元素内-->
<div id="app"></div>
<!--关联main.ts-->
<script type="module" src="/src/main.ts"></script>
</body>
</html>
组件
svelte组件,首字母大写,后缀名.svelte
<script> </script>
<main></main>
<style></style>
组件是由三部分组成,就是典型的html:js+css+html
我们写svelte就像写html一样容易
另外还有一个特性就是组件里的js,css只在组件内生效,不会影响到其它也面或者组件
组件的引用和使用
写好的组件不用做任何的抛出处理
需要引用组件的svelte文件,需要引入子组件。如默认模板中根组件,引入Count组件
<script lang="ts">
import logo from './assets/svelte.png'
import Counter from './lib/Counter.svelte'//在这里引入count组件
</script>
然后在下面使用 用组件名标签/表示
<main>
<img src={logo} alt="Svelte Logo" />
<h1>Hello Typescript!</h1>
/*在这边直接使用*/
<Counter />
</main>
热加载功能
我们在用svelte开发的时候,vite提供了热加载功能,也就是说你改变了代码,网页就会自动刷新,大大提高了开发效率
模板
在使用svelte开发网页的时候应当将数据和元素标签分开写
数据写在script标签中
元素单独写
如下一个简单的示例
<script>
let msg='it is a good day'
</script>
<style>
h1{
color:blue;
}
</style>
<h1>{msg}</h1>
它的效果其实就是
<style>
h1{
color:blue;
}
</style>
<h1>it is a good day</h1>
对了就是用{}来渲染数据
属性模板
我们知道每个元素标签是用很多属性的,比如最常用的class id等
我们看下svelte是怎么实现的
<script>
let msg='it is a good day'
let msgclass='one'
</script>
<style>
.one{
color:red;
width: 200px;
border: 1px blue solid;
border-radius: 10%;
}
</style>
<h1 class={msgclass}>{msg}</h1>
首先我们看到h1标签的class=一个带有{}数据,而msgclass是一个模板数据,它对应的是变量one,渲染之后就是class='one'
最后效果和我们单独写html是一样的
其它的标签属性也是同样可以按照这样的方式来绑定
HTML模板
如果我们想要把HTML元素渲染,如果按照{}的方法就会原样输出
这时候我们就要用到{@html }来渲染了
例子:
<script>
let msgh1 = `<h1>good day</h1>
<h2>nice</h2>`;
</script>
<div>{@html msgh1}</div>
最后显示效果
我们发现里面的内容是按html的文档来渲染了
事件模板
js有很多事件可以调用html元素,如click,mouse等等
我们看下模板是怎么写的
<script>
let a=0
function add(){
a++
}
</script>
<p>a的值为:{a}</p>
<button on:click={add}>+</button>
和原生js一样,我们先写个add方法。只不过绑定的方法要比原生来的简便
我们直接在要绑定事件的元素上面写上on:+时间名,={}里面写方法名就可以,让我们来看下最后效果
反应性能力
有了前面的基础,我们就可以来接触svelte里面很重要的一个知识点,反应性能力
首先看个示例组件
<script>
let a=0
$: doublea=a*2
function add(){
a++
}
</script>
<p>a的值为:{a}</p>
<p>a的2倍为:{doublea}</p>
<button on:click={add}>+</button>
先看下效果
没错,a的值+1的时候,doublea会重新计算下自己的值,因为在定义的时候是$: 开头的
只要$: 里的变量发生改变的时候,整个就会重新执行一次,这就是反应性能力
逻辑
我们都知道js里的逻辑运算,如 if(判断) for(循环)
svelte也带有这个功能,来让我们更好的渲染我们的页面
if...else
我们先看下例子
<script>
let a=0
function add(){
a++
}
</script>
{#if a<5}
<p style="color: red;">a的值为:{a}</p>
{/if}
<button on:click={add}>+</button>
if的语法是{#if xxx} {/if} 然后在里面写条件成立时,你要展示的内容
现在渲染的意思就是如果a<5,那么这段话就是红色的,如果a>=5了,那么这段话就不会显示了
当然大于5的时候我们也想让它显示,所以就要加上else了
我们简单调整下代码
<script>
let a=0
function add(){
a++
}
</script>
{#if a<5}
<p style="color: red;">a的值为:{a}</p>
{:else}
<p style="color: blue;">a的值为:{a}</p>
{/if}
<button on:click={add}>+</button>
{:else}代表if不成立时渲染的内容,没错a>=5是就变成蓝色了
但是当a>10的时候我们想让它变黑,怎么做呢,我们应该想到这种判断就要用else if了
在svelte里同样可以
<script>
let a=0
function add(){
a++
}
</script>
{#if a<5}
<p style="color: red;">a的值为:{a}</p>
{:else if a<=10}
<p style="color: blue;">a的值为:{a}</p>
{:else}
<p>a的值为:{a}</p>
{/if}
<button on:click={add}>+</button>
好了,现在就来看下最终的效果吧
each循环
js里循环有很多方式,在svelte里,提供的是each循环
看下代码
<script>
let peo=[
{name:'张三',age:22},
{name:'李四',age:22},
{name:'王五',age:22},
]
</script>
{#each peo as p}
<p>姓名:{p.name}</p>
<p>年龄:{p.age}</p>
<hr>
{/each}
循环包裹在{#each } {/each}里面,其实这种写法和js几乎一样
同样,它也支持解构,和index,代码调整如下
<script>
let peo=[
{name:'张三',age:22},
{name:'李四',age:22},
{name:'王五',age:22},
]
</script>
{#each peo as {name,age},index}
<h2>{index+1}</h2>
<p>姓名:{name}</p>
<p>年龄:{age}</p>
<hr>
{/each}
最后看下效果,
双向绑定
双向绑定是一个很重要的功能,在大多框架中都有,svelte同样提供了
书写规则如下
<script>
let name=''
</script>
<label for="name">name:</label>
<input type="text" id="name" bind:value={name}>
<br>
<p>姓名是:{name}</p>
那我们先看下效果
bind:value就是作用在表单元素的时候表示它的value,但是这个value是动态的
radio,checkbox,select表单里面会有很多值,让我们来看下,是如何实现的
<script>
let choose=['man','women']
let res=''
let address=['江苏','上海','广州']
let add=[]
let loves=['篮球','足球','排球','划船']
let lovechoose=''
</script>
{#each choose as p}
<input type="radio" bind:group={res} name='sex' value={p}>
<label for="sex">{p}</label>
{/each}
<br>
<p>性别是:{res}</p>
<hr>
{#each address as p}
<input type="checkbox" bind:group={add} name='add' value={p}>
<label for="add">{p}</label>
{/each}
<p>最后地址有:</p>
<p>
{#each add as p}
<span>{p}</span>
{/each}
</p>
<hr>
<label for="love">爱好</label>
<select name="love" id="" bind:value={lovechoose}>
{#each loves as p}
<option value={p}>{p}</option>
{/each}
</select>
<p>最后选择的爱好是:{lovechoose}</p>
效果如下
我们可以看出,raido和checkbox是将最后选择的值,给bind:group,radio是唯一,所以绑定的应该是个string,
而checkbox是个多项,所以应该绑定一个数组,然后我们可以把这个数组再渲染到页面上
select就和input里的text很想,将最后选择的值最为bind:value双向绑定
bind:checked
svelte给checkbox做了一个bind:checked,用来判断,是否被选中,看一个示例
<script>
let choose=false
</script>
<input type="checkbox" name="cho" bind:checked={choose}><label for="cho">choose it?</label>
{#if choose}
<p style="color: blue;">yes you choose it</p>
{:else}
<p style="color: red;">i am sorry ,you did not choose it</p>
{/if}
效果
选中的时候bind:checked的动态值为true,否则false