# 視頻教程
http://noover.leanapp.cn/courses
# 安裝(Install)
npm install -g svelte-cli
# 創(chuàng)建一個會說你好世界的組件(HelloWorld Component)
- 新建一個項目文件夾,新建一個 HelloWrold.html 內(nèi)容如下。
<!-- HelloWrold 組件 -->
<h1>你好 {{name}}</h1>
- 使用命令編譯 html 文件
svelte compile --format iife HelloWorld.html > HelloWorld.js
- 創(chuàng)建 index.html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>Svelte Application</title>
</head>
<body>
<application></application>
<script src="./HelloWorld.js"></script>
<script>
var app = new HelloWorld({
target: document.querySelector( 'application' ),
data: {
name: '世界'
}
});
</script>
</body>
</html>
# 組件實例方法(Component API)
創(chuàng)建一個組件的實例的方法就是通過 new 調(diào)用并傳入配置項
- 要加載到的 DOM 節(jié)點上面
target: document.querySelector( 'main' )
- 組件的初始數(shù)據(jù)
data: {
author: {
name: '近藤麻理惠'
gender: 'female'
nationality: 'Japan'
},
title: '怦然心動人生整理魔法'
recommendedReason: '勤儉持家,人人有責(zé)劈榨。無論男女脏嚷,統(tǒng)統(tǒng)要干褒颈。'
}
# 在我們的 HelloWorld 例子中安皱,在你的Chrome 控制臺
輸入以下內(nèi)容
以下內(nèi)容都是實例的方法,每次開始測試之前可以刷新一下氛雪,清空之前的變量想虎。
# get
app.get('name')
// "世界"
# set
app.set({ name: '天地' })
# observe
observe
字面上的意思就是觀察卦尊,在代碼中的意思就是觀察 name
,當(dāng)值改變的時候就執(zhí)行回調(diào)函數(shù)磷醋。
可以看到加上觀察就立馬觸發(fā)了回調(diào)猫牡,打印了當(dāng)前 name 的值
const observer = app.observe( 'name', name => {
console.log( `當(dāng)前 name 的值是 ${name}` );
});
app.set({name:'虛空大帝'})
observer.cancel() // 取消觀察
app.set({name:'皓月大帝'})
傳入{ init: false }
那么第一次就不會觸發(fā)
app.observe( 'name', ( newValue, oldValue ) => {
console.log( `長度對比 ${newValue.length > oldValue.length ? 'new > old' : 'new < old'}` );
}, { init: false });
app.set({name:'宵元大帝~'})
默認(rèn)所有回調(diào)會在更新前完成,傳入{ defer: true }
會導(dǎo)致回調(diào)在組件更新完成之后調(diào)用邓线。
這樣的操作組要是跟 Dom 有關(guān)聯(lián)淌友,所以我們需要添加一點代碼來驗證它們。
- HelloWorld.html
<h1>你好 {{name}}</h1>
<canvas id="canvas-container" width="{{ canvas_width }}" height="{{ canvas_height }}"></canvas>
<style type="text/css">
#canvas-container{
background: #7F7BFF;
}
</style>
- 重新編譯一下
svelte compile --format iife HelloWorld.html > HelloWorld.js
- index.html
var app = new HelloWorld({
target: document.querySelector( 'application' ),
data: {
name: '世界',
canvas_width: '350',
canvas_height: '150'
}
});
function redraw(newValue, oldValue) {
const canvas = document.querySelector('#canvas-container')
console.log("Dom height " + canvas.height);
console.log("Dom width " + canvas.width);
console.log(newValue + " -> " + oldValue);
}
app.observe('canvas_width', redraw, { init: false})
app.observe('canvas_height', redraw, { defer : true, init: false })
- 在控制臺里面輸入
app.set({ canvas_height: 20 })
app.set({ canvas_width: 20 })
# on
on 在 js 語言中通常監(jiān)聽某一事件骇陈,這很符合慣例
const listener = app.on( 'eat', event => {
console.log( `${event.name} 超齡兒童震庭,你老婆叫你回家吃晚飯了` );
});
# fire
觸發(fā)某一事件
app.fire( 'eat', {
name: 'Alex'
});
- teardown
刪除 DOM 會觸發(fā)這個事件
app.on( 'teardown', () => {
alert( '滾蛋吧 組件君!' );
});
app.teardown()
# HelloWorld 組件源碼分析
- NeedTodo
# 組件模板語法(Template syntax)
# 變量
使用小胡子Mustaches
語法輸出變量
<p>{{a}} + {} = {{a + b}}</p>
<h1 style='color: {{color}};'>{{color}}</h1>
# 條件
{{#if user }}
<div>{{ user.name }} is beautful girl!</div>
{{/if}}
{{#if x > 10}}
<p>{{x}} 大于 10</p>
{{elseif 5 > x}}
<p>{{x}} 小于 5</p>
{{else}}
<p>{{x}} 在 5 與 10 之間</p>
{{/if}}
# 循環(huán)
<h1>水果大家庭</h1>
<ul>
{{#each fruits as fruit}}
<li>{{fruit}}</li>
{{/each}}
</ul>
fruits: ['蘋果','梨','香蕉','葡萄','橘子','菩提','火龍果','荔枝']
# 指令
<p>Count: {{count}}</p>
<button on:click='set({ count: count + 1 })'>+1</button>
# 組件樣式(Style)
<canvas id="canvas-container" width="{{ canvas_width }}" height="{{ canvas_height }}"></canvas>
<style type="text/css">
#canvas-container{
background: #7F7BFF;
}
</style>
# 組件行為(Script)
# 組件屬性
<p>Count: {{count}}</p>
<button on:click='set({ count: count + 1 })'>+1</button>
<script>
export default {
data () {
return {
count: 0
};
}
};
</script>
# 計算屬性
<p>
The time is
<strong>{{hours}}:{{minutes}}:{{seconds}}</strong>
</p>
<script>
export default {
data () {
return {
time: new Date()
};
},
computed: {
hours: time => time.getHours(),
minutes: time => time.getMinutes(),
seconds: time => time.getSeconds()
}
};
</script>
# 生命周期
<script>
export default {
onrender () {
this.interval = setInterval( () => {
this.set({ time: new Date() });
}, 1000 );
},
onteardown () {
clearInterval( this.interval );
},
data () {
return {
time: new Date()
};
},
computed: {
hours: time => time.getHours(),
minutes: time => time.getMinutes(),
seconds: time => time.getSeconds()
}
};
</script>
# 幫助函數(shù)
把你需要的函數(shù)放到 helpers 里面那就可以在模板中使用了你雌,但是必須是純函數(shù)器联。
<p>
The time is
<strong>{{hours}}:{{leftPad(minutes, 2, '0')}}:{{leftPad(seconds, 2, '0')}}</strong>
</p>
<script>
function leftPad(str, len, ch) {
str = str + '';
len = len - str.length;
if (len <= 0) return str;
if (!ch && ch !== 0) ch = ' ';
ch = ch + '';
return ch.repeat(len) + str;
};
export default {
helpers: {
leftPad
},
onrender () {
this.interval = setInterval( () => {
this.set({ time: new Date() });
}, 1000 );
},
onteardown () {
clearInterval( this.interval );
},
data () {
return {
time: new Date()
};
},
computed: {
hours: time => time.getHours(),
minutes: time => time.getMinutes(),
seconds: time => time.getSeconds()
}
};
</script>
# 組件方法
<button on:click='say("hello")'>say hello!</button>
<script>
export default {
methods: {
say ( message ) {
alert( message );
}
}
};
</script>
# 組件事件
記得在你的 data 上添加 done 變量
node 就是當(dāng)前的 dom 節(jié)點,callback 就是我要執(zhí)行的代碼婿崭,自行打印一下就很清楚了拨拓。
<button on:longpress='set({ done: true })'>click and hold</button>
{{#if done}}
<p>clicked and held</p>
{{/if}}
<script>
export default {
events: {
longpress ( node, callback ) {
function onmousedown ( event ) {
const timeout = setTimeout( () => callback( event ), 1000 );
function cancel () {
clearTimeout( timeout );
node.removeEventListener( 'mouseup', cancel, false );
}
node.addEventListener( 'mouseup', cancel, false );
}
node.addEventListener( 'mousedown', onmousedown, false );
return {
teardown () {
node.removeEventListener( 'mousedown', onmousedown, false );
}
};
}
}
};
</script>
# 子組件
此小節(jié)注意大小寫,組件用大寫氓栈,別弄錯了渣磷。
- 創(chuàng)建一個新的文件 Widget.html
<div class="widget-container">
<h1>hei! Widget</h1>
</div>
- 編譯一下
svelte compile -f iife -i Widget.html -o Widget.js
- 給 HelloWrold 添加一下代碼
import Widget from './Widget.html';
export default {
components: {
Widget
},
......
}
- 編譯一下 HelloWorld.html
svelte compile -f iife HelloWorld.html > HelloWorld.js
- 在給 index.html 修改一下代碼
Widget 由于被 HelloWorld 依賴所以需要先加載
<script src="./Widget.js"></script>
<script src="./HelloWorld.js"></script>