昨天我们解说了 , Jquery 跟 Vue 两种处理 Dom 的模式
在文末 , 提到了 Web Component 中没有 Vue 可用 ,
不过我们可以建立 _render 函式 , 来达到资料的单向绑定
今天我们来建立 _render 函式 , 并利用 day-11 提到的 Proxy 来触发 _render 函式
达成资料的单向绑定
将昨天的 button 范例转换成 Web Component
将昨天的
my-button.vue
中的 style . script . template 三个区块放到相对应的位置
// my-button.js
class MyButton01 extends HTMLElement {
// style 的内容放这
styles = `
<style>
button.btn {
padding: 10px 20px;
border-radius: 8px;
font-size: 16px;
color: white;
}
button:disabled {
cursor: not-allowed;
}
</style>
`
connectedCallback() {
this.attachShadow({mode: 'open'}).innerHTML = this.styles + `<div></div>`;
this._render()
}
_render() {
const rootDiv = this.shadowRoot.querySelector('div')
// template 的内容放这
rootDiv.innerHTML = `
<div>
<h2>目前有 <span class="left">{{left}}</span> 点数</h2>
<h2>预计花费 <span class="cost">{{cost}}</span> 点数</h2>
<button class="btn" :style="{backgroundColor:bgColor}" :disabled="disabled" @click="buy">
购买
</button>
<h2></h2>
<button @click="login">登入</button>
<button @click="logout">登出</button>
<h2></h2>
<button @click="addCost(100)">加买法帐( 100 点 )</button>
<button @click="minusCost(100)" :disabled="cost === 0">减买法帐( 100 点 )</button>
</div>
`
}
// computed . methods 的内容放在这里
}
window.customElements.define('my-button-01', MyButton01);
将昨天学到的 Proxy 建立
this.data = new Proxy
data = new Proxy(
// 将预设设定到 target 中
{
cost: 0,
left: 500,
isLogin: false
},
// handler set 资料後 , 执行 render 函式
{
get: (target, property) => target[property],
set: (target, property, value) => {
target[property] = value;
this._render()
return true
},
})
将 :XXX 的属性改成 ${} 的区块
_render() {
const rootDiv = this.shadowRoot.querySelector('div')
// template 的内容放这
rootDiv.innerHTML = `
<h2>目前有 <span class="left">${this.data.left}</span> 点数</h2>
<h2>预计花费 <span class="cost">${this.data.cost}</span> 点数</h2>
<button class="btn" style="background-color: ${this.bgColor()};" ${this.disabled() ? 'disabled':'' } @click="buy">
购买
</button>
<h2></h2>
<button @click="login">登入</button>
<button @click="logout">登出</button>
<h2></h2>
<button @click="addCost(100)">加买法帐( 100 点 )</button>
<button @click="minusCost(100)" ${this.data.cost === 0 ? 'disabled':'' }>减买法帐( 100 点 )</button>
`
}
将 @click 的事件绑定到 dom 上
建立 vOn 函式
// the :params resolve
vOn() {
// 特殊字元 ( @ : ) 在 querySelector 的处理 - https://stackoverflow.com/questions/45110893/select-elements-by-attributes-with-colon
const onClickEls = this.shadowRoot.querySelectorAll('button[\\@click]')
onClickEls.forEach(el => {
const onclickStr = el.getAttribute('@click')
if (onclickStr.indexOf('(') > -1) {
const fn = this[onclickStr.split('(')[0]]
// 取得 () 中的参数设定
const paramStrs = onclickStr.split('(')[1].replace(')', '').split(',')
const param = paramStrs.map(param => {
const numberReg = /^[\+\-]?\d*\.?\d+(?:[Ee][\+\-]?\d+)?$/
if (param === 'true') return true
else if (param === 'false') return false
else if (param === 'false') return false
else if (numberReg.test(param)) return parseFloat(param)
else if (this.data[param]) return this.data[param]
else return param
})
el.addEventListener('click', e => fn.call(this, ...param))
} else {
const fn = this[onclickStr]
el.addEventListener('click', e => fn.call(this, e))
}
})
}
每次 _render 时 , 呼叫 vOn() , 绑定 @click 事件
_render() {
// ...之前的 Code
this.vOn()
}
大功告成 ~~~~~
如果想直接体验成果 , 请到 web-component-render.html 查看
<<: Re: 新手让网页 act 起来: Day02 - 永远的起点 Hello world!
>>: 17.unity显示/隐藏物件(SetActive)
接下上集!!,我们已经完成layout,还有上传照片了。那麽接下来我们要做的就是把选取时间的日历叫...
第 22 天 ! 当我们资料项下传递的时候, 会发现, component 的阶层越深, 传递资讯会...
在 Day01 的时候我们有提到过资料可能会有杂讯、噪音,因此所使用的模型架构可以分为两个阶段:除噪...
儿童程序教学 https://wolkesau.medium.com/73094f76b216 儿童...
当我们在 GoDaddy 上申请好网域之後,就接着要把 GoDaddy 上的 DNS 转址到我们的服...