Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

2020-02-13 实现以下功能 #8

Open
fanmingfei opened this issue Mar 12, 2020 · 3 comments
Open

2020-02-13 实现以下功能 #8

fanmingfei opened this issue Mar 12, 2020 · 3 comments

Comments

@fanmingfei
Copy link
Member

fanmingfei commented Mar 12, 2020

题目:
html

<div id="people"></div>
<div id="language"></div>

javascript

//  在此处增加代码
function People() {
  const [name, setName] = useState('LiLei')
  const [old, setOld] = useState(1)
  let i = 1
  setInterval(()=>{
    i++
    console.log(i)
    setOld(i)
  }, 1000)

  return tmpl`<div>My name is ${name}, I\'m ${old} years old.</div>`;  
}

function Language() {
  const [language, setLanguage] = useState('Toy')

  setTimeout(()=>{
    setLanguage('HTML')
  }, 2000)
  setTimeout(()=>{
    setLanguage('CSS')
  }, 4000)
  setTimeout(()=>{
    setLanguage('JavaScript')
  }, 6000)

  return tmpl`<div>I love ${language}</div>`
}


render(document.querySelector('#people'), People)
render(document.querySelector('#language'), Language)

在 javascript 最上面增加代码,实现以下效果。

效果图:

@xiaosen7
Copy link

xiaosen7 commented Mar 13, 2020

html

<div id="people"></div>
<div id="language"></div>

js

const renderList = [];

        const firstMemoized = { value: null, next: null };
        let currentMemoized = firstMemoized;

        function reRender(memoized) {
            currentMemoized = firstMemoized
            renderList.forEach(r => r());
        }

        function render(container, component) {
            renderList.push(() => container.innerHTML = component());
            container.innerHTML = component();
        }


        function tmpl(iterators, ...params) {
            return iterators.reduce((a, b, index) => a + params[index - 1] + b)
        }

        const setTimeout = (...args) => {
            const memoized = currentMemoized.next ? currentMemoized.next : (window.setTimeout(...args), currentMemoized.next = { value: undefined, next: null });
            currentMemoized = currentMemoized.next;
        }
        const setInterval = (...args) => {
            const memoized = currentMemoized.next ? currentMemoized.next : (window.setInterval(...args), currentMemoized.next = { value: undefined, next: null });
            currentMemoized = currentMemoized.next;
        }

        function useState(initialValue) {

            const memoized = currentMemoized.next ? currentMemoized.next : currentMemoized.next = { value: initialValue, next: null };
            currentMemoized = currentMemoized.next;
            const setState = newValue => (memoized.value = newValue) && reRender();
            return [
                memoized.value,
                setState
            ]
        }

        function People() {
            const [name, setName] = useState('LiLei')
            const [old, setOld] = useState(1)
            let i = 1
            setInterval(() => {
                i++
                console.log(i)
                setOld(i)
            }, 1000)

            return tmpl`<div>My name is ${name}, I\'m ${old} years old.</div>`;
        }

        function Language() {
            const [language, setLanguage] = useState('Toy')

            setTimeout(() => {
                setLanguage('HTML')
            }, 2000)
            setTimeout(() => {
                setLanguage('CSS')
            }, 4000)
            setTimeout(() => {
                setLanguage('JavaScript')
            }, 6000)

            return tmpl`<div>I love ${language}</div>`
        }


        render(document.querySelector('#people'), People)
        render(document.querySelector('#language'), Language)

@LiZhaji
Copy link

LiZhaji commented Mar 13, 2020

    const {render, useState, tmpl} = outer()

    function outer() {
      const cache = {}
      let curComponent
      const render = (node, component) => {
        curComponent = component.name
        const tpl = component()
        cache[component.name] = () => node.innerHTML = parse(tpl)
        node.innerHTML = parse(tpl)
      }

      const useState = initValue => {
        const component = curComponent

        const data = {value: initValue}
        const setData = newValue => {
          data.value = newValue
          cache[component]()
        }
        return [data, setData]
      }

      const parse = tpl =>  {
        const [strings, ...varis] = tpl
        return strings.reduce((res, item, i) => {
          res = res.concat(item, varis.slice(i, i+1)[0]?.value)
          return res
        },[]).join('')
      }

      const tmpl = (...p) => p

      return {render, useState, tmpl}
    }

    function People() {
      const [name, setName] = useState('LiLei')
      const [old, setOld] = useState(1)
      let i = 1
      setInterval(()=>{
        i++
        setOld(i)
      }, 1000)

      return tmpl`<div>My name is ${name}, I\'m ${old} years old.</div>`;  
    }

    function Language() {
      const [language, setLanguage] = useState('Toy')

      setTimeout(()=>{
        setLanguage('HTML')
      }, 2000)
      setTimeout(()=>{
        setLanguage('CSS')
      }, 4000)
      setTimeout(()=>{
        setLanguage('JavaScript')
      }, 6000)

      return tmpl`<div>I love ${language}</div>`
    }

    render(document.querySelector('#people'), People)
    render(document.querySelector('#language'), Language)

@fanmingfei
Copy link
Member Author

fanmingfei commented Mar 13, 2020

const makeHook = (hooks) => {
  let currentComponent

  let fns = {}
  for(let fnName in hooks) {
    fns[fnName] = (...args)=> hooks[fnName](currentComponent)(...args)
  }

  return {
    setComponent(Component) {
      currentComponent = Component
    },
    hooks: fns
  }
}

function createEvent () {
  const map = new Map()
  return (Component) => {
    if (map.has(Component)) return map.get(Component)
    const events = new Map()
    const obj = {
      on(name, fn) {
        if (!events.has(name)) events.set(name, [])
        events.get(name).push(fn)
      },
      emit(name, ...args) {
        console.log(name, ...args)
        if (!events.get(name)) return false
        for (let fn of events.get(name)) {
          fn instanceof Function && fn(...args);
        }
      }
    }
    map.set(Component, obj)
    return obj
  }
}

const makeEvent = createEvent()

const current = {}

const hooks = makeHook({
  useState: Component => initialValue => {
    let value = {value: initialValue}
    const setValue = (newValue)=> {
      console.log(newValue)
      value.value = newValue
      makeEvent(Component).emit('stateChange', value)
    }

    return [value, setValue]
  },
  useStateChange: Component => (callback) => {
    makeEvent(Component).on('stateChange', (value)=>callback(value))
  },

})

function makeHTML (tmpl) {
  const html = [...tmpl[0]].reduce((str, curr, i)=>{
    let {value} = tmpl[i] || {value: ''}
    return str += value + curr
  })
  return html
}

const { useState, useStateChange } = hooks.hooks


function render(dom, Component) {
  hooks.setComponent(Component)
  const tmpl = Component()
  useStateChange(()=>{
    dom.innerHTML = makeHTML(tmpl)
  })
  dom.innerHTML = makeHTML(tmpl)

}

const tmpl = (...arg)=>arg

function People() {
  const [name, setName] = useState('LiLei')
  const [old, setOld] = useState(1)
  let i = 1
  setInterval(()=>{
    i++
    setOld(i)
  }, 1000)

  return tmpl`<div>My name is ${name}, I\'m ${old} years old.</div>`;  
}

function Language() {
  const [language, setLanguage] = useState('Toy')

  setTimeout(()=>{
    setLanguage('HTML')
  }, 2000)
  setTimeout(()=>{
    setLanguage('CSS')
  }, 4000)
  setTimeout(()=>{
    setLanguage('JavaScript')
  }, 6000)

  return tmpl`<div>I love ${language}</div>`
}





render(document.querySelector('#people'), People)
render(document.querySelector('#language'), Language)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants