Code Monkey home page Code Monkey logo

vuejs-challenges's Introduction

Collection of Vue.js challenges

English | 简体中文

📖 Introduction

I love Vue.js ♥️. It's so Awesome 🚀. It helps me finish my work well and build applications.

I was looking for a project for everyone to learn Vue.js together, and that's why this project was born. I believe we can grow together here, and hope it helps you.

This project is aimed at helping you better understand Vue.js, writing your own utilities, or just having fun with the challenges.

We are also trying to form a community where you can ask questions and get answers you have faced in the real world - they may become part of the challenges!

✏️ Challenges

Click the following badges to see details of the challenges.

1
1・Hello World

13
2・ref family 3・losing-reactivity 4・writable-computed 5・watch family 6・shallow ref 9・Dependency Injection 10・Lifecycle Hooks 11・Next DOM update flush 13・DOM Portal 14・Dynamic css values 243・prevent event propagation 305・Capitalize 323・Prop Validation

14
7・Raw API 8・effectScope API 12・Optimize performance directive 15・useToggle 16・until 17・useCounter 18・useLocalStorage 19・v-focus 20・v-debounce-click 21・functional component 25・useMouse 27・Global CSS 218・render function[h()] 232・Key Modifiers

5
22・custom element 23・custom ref 24・v-active-style 26・v-model 208・Tree Component

By Tags
#Built-ins13・DOM Portal 12・Optimize performance directive
#CSS Features14・Dynamic css values 27・Global CSS
#Components13・DOM Portal 323・Prop Validation 21・functional component 218・render function[h()] 208・Tree Component
#Composable Function15・useToggle 17・useCounter 18・useLocalStorage 25・useMouse
#Composition API2・ref family 3・losing-reactivity 4・writable-computed 5・watch family 6・shallow ref 9・Dependency Injection 10・Lifecycle Hooks 8・effectScope API 23・custom ref
#Directives305・Capitalize 12・Optimize performance directive 19・v-focus 20・v-debounce-click 24・v-active-style 26・v-model
#Event Handling243・prevent event propagation 232・Key Modifiers
#Global API:General11・Next DOM update flush
#Lifecycle10・Lifecycle Hooks
#Reactivity:Advanced6・shallow ref 7・Raw API 8・effectScope API 23・custom ref
#Reactivity:Core2・ref family 4・writable-computed 5・watch family
#Reactivity:Utilities3・losing-reactivity
#Utility Function16・until
#Web Components22・custom element

🤝 How to Contribute

There are several ways you can contribute to this project

  • Share your answers/solutions
  • Propose new challenges
  • Add more test cases to the existing challenges
  • Provide learning resources or ideas of how to solve challenges
  • Share the problems you have faced in real-world projects, regardless you have the solution or not - the community would help you as well.
  • Help others by discussing issues

Just open an issue and choose the corresponding template. Thanks!

🌸 Credits

This project is highly inspired by type-challenges ♥️.

vuejs/repl makes this project possible ♥️.

📄 License

MIT LICENSE

vuejs-challenges's People

Contributors

981377660lmt avatar enoooch avatar flippedround avatar github-actions[bot] avatar heappynd avatar holazz avatar iamdin avatar jeremielitzler avatar murongg avatar saxon-y avatar selemondev avatar wadejs avatar webfansplz avatar yash-singh1 avatar yuyinws avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

vuejs-challenges's Issues

10 - 生命周期钩子

<script setup lang="ts">
import { onMounted, inject, onUnmounted } from "vue"

const timer = inject("timer")
const count = inject("count")

onMounted(() => {
  timer.value = window.setInterval(() => {
    count.value++
  }, 1000)
})
onUnmounted(() => {
  window.clearInterval(timer.value)
})
</script>

<template>
  <div>
    <p>
      Child Component: {{ count }}
    </p>
  </div>
</template>

4 - 可写的计算属性

<script setup lang="ts">
import { ref, computed } from "vue"

const count = ref(1)
const plusOne = computed({
  get: () => count.value + 1,
  set: () => {count.value++}
})

/**
 * Make the `plusOne` can be written.
 * So we'll get the result is `plusOne` to be 3, and `count` to be 2.
*/

plusOne.value++

</script>

<template>
  <div>
    <p>{{ plusOne }}</p>
    <p>{{ count }}</p>
  </div>
</template>

14 - 动态CSS

<script setup>
import { ref } from "vue"
const theme = ref("red")

const colors = ["blue", "yellow", "red", "green"]

setInterval(() => {
  theme.value = colors[Math.floor(Math.random() * 4)]
}, 1000)

</script>

<template>
  <p>hello</p>
</template>

<style scoped>
/* 修改以下代码绑定动态颜色 */
p {
  color: v-bind(theme);
}
</style>

17 - 计数器

<script setup lang='ts'>
import { ref } from 'vue';


interface UseCounterOptions {
  min?: number
  max?: number
}

/**
 * 实现计数器函数,确保功能正常工作
 * 1. 加 (+)
 * 2. 减 (-)
 * 3. 重置 
 * 4. 最小值 & 最大值 选项支持
*/
function useCounter(initialValue = 0, options: UseCounterOptions = {}) {
  const count = ref(initialValue)
  const inc = () => {
    if (typeof options.max === 'number') options.max > count.value && count.value++
    else count.value++
  }
  const dec = () => {
    if (typeof options.min === 'number') options.min < count.value && count.value--
    else count.value--
  }
  const reset = () => {
    count.value = initialValue
  }
  return {
    count, inc, dec, reset
  }
}

const { count, inc, dec, reset } = useCounter(0, { min: 0, max: 5 })

</script>

<template>
  <div>{{ count }}</div>
  <button @click="inc">inc</button>
  <button @click="dec">dec</button>
  <button @click="reset">reset</button>
</template>

1 - 你好 !

// 你的答案
<script setup>
import { ref } from "vue"
const msg = ref("Hello World")
</script>

<template>
  <div>
    <h1>{{msg}}</h1>
  </div>
</template>

21 - 函数式组件

<script setup lang='ts'>
import { ref, h, PropType } from "vue"

/**
 * 实现该函数式组件 :
 * 1. 使用`list`数据渲染列表元素 (ul/li)
 * 2. 当点击列表子元素时,将其文本颜色更改为红色
*/
const ListComponent = (props, { attrs, emit }) => {
  const items = props.list.map((v, idx) => {
    return h('li', {
      class: `${idx === props.activeIndex ? 'active' : ''}`,
      onClick() {
        emit('toggle', idx);
      }
    }, v.name)
  });
  return h('ul', attrs, items)
}

ListComponent.props = {
  list: {
    type: Array as PropType<Array<{ name: string; }>>,
  	default() {
      return []
    },
  },
  activeIndex: {
    type: Number,
    default: 0
  },
  // emit events
  toggle: {
    type: Function as PropType<(index: number) => void>,
    default: () => {},
  },
};


const list = [{
  name: "John",
}, {
  name: "Doe",
}, {
  name: "Smith",
}]

const activeIndex = ref(0)

function toggle(index: number) {
  activeIndex.value = index
}

</script>

<template>
  <list-component
    :list="list"
    :active-index="activeIndex"
    @toggle="toggle"
  />
</template>

<style>
  li.active {
    color: red;
    use-select: none;
  }
</style>

在线答案

10 - 生命周期钩子

// 你的答案
// Child.vue
<script setup lang="ts">
import { onMounted, inject, onUnmounted } from "vue"

const timer = inject("timer")
const count = inject("count")

onMounted(() => {
  timer.value = window.setInterval(() => {
    count.value++
  }, 1000)
})

onUnmounted(() => {
  clearInterval(timer.value)
})

</script>

<template>
  <div>
    <p>
      Child Component: {{ count }}
    </p>
  </div>
</template>

依赖注入

请按照以下的模版填充相应的内容,一个 PR 会自动生成并保持与本 Issue 的内容同步。

你不需要提供详细的答案或教学,但请保证题目可解。

基本信息

# 题目难度
difficulty: easy

# 题目标题
title: 依赖注入

# 题目标签
tags: Composition API

题目

在这个挑战中,你将使用 组合式 API: 依赖注入 来完成它。
以下是你要实现的内容 :

题目模版

以下是给予挑战者开始做题的代码模版,

如果您想提交多个文件,只需创建多个<!--challenges-start--><!--challenges-end-->,并按照以下格式填写文件名和代码內容

filename: App.vue

<script setup lang="ts">
import { ref, provide } from "vue"
import Child from "./Child.vue"
const count = ref(1)
provide("count", count)
setInterval(() => {
  count.value++
}, 1000)
</script>

<template>
  <Child />
</template>

filename: Child.vue

<script setup lang="ts">
// Add code to make the `count` value injected into the child component.
</script>

<template>
  {{ count }}
</template>

27 - 全局CSS

<template>
  <p>Hello Vue.js</p>
</template>

<style scoped>

p {
  font-size:20px;
  color:red;
  text-align: center;
  line-height: 50px;
}


</style>

<style>
/* Make it works */
body {
  width: 100vw;
  height: 100vh;
  background-color: burlywood;
}
</style>

Dependency Injection

Please follow the template and fill the info. A PR will be auto-generated and always reflect on your changes.

Detailed solution/guide is not required, but please be sure the challenge is solvable.

Info

Basic info of your challenge questions,

difficulty: easy
title: Dependency Injection
tags: Composition API

Template

This is the template for challengers to start the coding.

If you want to commit multiple files, just create multiple blocks and identify the file name and code block

filename: App.vue

<script setup lang="ts">
import { ref, provide } from "vue"
import Child from "./Child.vue"
const count = ref(1)
provide("count", count)
setInterval(() => {
  count.value++
}, 1000)
</script>

<template>
  <Child />
</template>

filename: Child.vue

<script setup lang="ts">
// Add code to make the `count` value injected into the child component.
</script>

<template>
  {{ count }}
</template>

1000-hello-world

Please follow the template and fill the info. A PR will be auto-generated and always reflect on your changes.

Detailed solution/guide is not required, but please be sure the challenge is solvable.

Info

Basic info of your challenge questions,

difficulty: easy # medium / hard / extreme
title: Your Question Name
tags: Directvies, Components # separate by comma

Template

This is the template for challengers to start the coding.

If you want to commit multiple files, just create multiple blocks and identify the file name and code block

filename: App.vue

<script setup lang="ts">
import { ref, provide } from "vue"
import Child from "./Child.vue"
const count = ref(1)
provide("count", count)
setInterval(() => {
  count.value++
}, 1000)
</script>

<template>
  <Child />
</template>

999-hello-world

Please follow the template and fill the info. A PR will be auto-generated and always reflect on your changes.

Detailed solution/guide is not required, but please be sure the challenge is solvable.

Info

Basic info of your challenge questions,

difficulty: easy # medium / hard / extreme
title: Your Question Name
tags: Directvies, Components # separate by comma

Template

This is the template for challengers to start the coding.

If you want to commit multiple files, just create multiple blocks and identify the file name and code block

filename: App.vue

<script setup lang="ts">
import { ref, provide } from "vue"
import Child from "./Child.vue"
const count = ref(1)
provide("count", count)
setInterval(() => {
  count.value++
}, 1000)
</script>

<template>
  <Child />
</template>

1 - 你好 !

<script setup>
import { ref } from "vue"
const msg = ref("Hello World")
</script>

<template>
  <div>
    <h1>{{ msg }}</h1>
  </div>
</template>

依赖注入

请按照以下的模版填充相应的内容,一个 PR 会自动生成并保持与本 Issue 的内容同步。

你不需要提供详细的答案或教学,但请保证题目可解。

基本信息

# 题目难度
difficulty: easy

# 题目标题
title: 依赖注入

# 题目标签
tags: Composition API

题目

在这个挑战中,你将使用 组合式 API: 依赖注入 来完成它。
以下是你要实现的内容 :

题目模版

以下是给予挑战者开始做题的代码模版,

如果您想提交多个文件,只需创建多个<!--challenges-start--><!--challenges-end-->,并按照以下格式填写文件名和代码內容

filename: App.vue

<script setup lang="ts">
import { ref, provide } from "vue"
import Child from "./Child.vue"
const count = ref(1)
provide("count", count)
setInterval(() => {
  count.value++
}, 1000)
</script>

<template>
  <Child />
</template>

filename: Child.vue

<script setup lang="ts">
// Add code to make the `count` value injected into the child component.
</script>

<template>
  {{ count }}
</template>

11 - 下一次DOM更新

<script setup>
import { ref, nextTick } from "vue"

const count = ref(0)

function increment() {
  count.value++

  /**
   * DOM not yet updated, how to make sure the DOM udpated
   * Make the output to be true
  */

  nextTick(() => {
	  console.log(+document.getElementById("counter").textContent === 1)
  })
}
</script>

<template>
  <button id="counter" @click="increment">
    {{ count }}
  </button>
</template>

6 - 浅层 ref

<script setup>
import { shallowRef, watch } from 'vue';

const state = shallowRef({ count: 1 });

// 回调没被触发
watch(state, () => {
  console.log('State.count Updated');
}, { deep: true });

/**
 * 修改以下代码使watch回调被触发
 *
*/
state.value = {
  count: 2,
};

</script>

<template>
  <div>
    <p>
      {{ state.count }}
    </p>
  </div>
</template>

13 - DOM传送门

<script setup>

const msg = "Hello World"

</script>

<template>
  <!-- Renders its to a child element of the `body` -->
  <Teleport to="body">
	  <span>{{ msg }}</span>
  </Teleport>
</template>

依赖注入

请按照以下的模版填充相应的内容,一个 PR 会自动生成并保持与本 Issue 的内容同步。

你不需要提供详细的答案或教学,但请保证题目可解。

基本信息

# 题目难度
difficulty: easy

# 题目标题
title: 依赖注入

# 题目标签
tags: Composition API

题目模版

以下是给予挑战者开始做题的代码模版,

如果您想提交多个文件,只需创建多个<!--challenges-start--><!--challenges-end-->,并按照以下格式填写文件名和代码內容

filename: App.vue

<script setup lang="ts">
import { ref, provide } from "vue"
import Child from "./Child.vue"
const count = ref(1)
provide("count", count)
setInterval(() => {
  count.value++
}, 1000)
</script>

<template>
  <Child />
</template>

filename: Child.vue

<script setup lang="ts">
// Add code to make the `count` value injected into the child component.
</script>

<template>
  {{ count }}
</template>

23 - 自定义ref

<script setup>
import { watch, customRef } from 'vue';

/**
 * 补全以下函数来实现防抖ref :
*/
function useDebouncedRef(value, delay = 200) {
  let timer;
  let thatValue = value;
  return customRef((track, trigger) => ({
    get() {
      track();
      return thatValue;
    },
    set(newValue) {
      if (timer) {
        clearTimeout(timer);
        timer = null;
      }
      timer = setTimeout(() => {
        thatValue = newValue;
        trigger();
      }, delay);
    },
  }));
}
const text = useDebouncedRef('hello');

/**
 * 确保在输入框快速输入时, 只触发一次回调。
*/
watch(text, (value) => {
  console.log(value);
});
</script>

<template>
  <input v-model="text">
</template>

11 - 下一次DOM更新

<script setup>
import { ref, nextTick } from "vue"

const count = ref(0)

function increment() {
  count.value++;

  /**
   * DOM not yet updated, how to make sure the DOM udpated
   * Make the output to be true
  */
  nextTick(() => {
    console.log(+document.getElementById("counter").textContent === 1)
  })
}
</script>

<template>
  <button id="counter" @click="increment">
    {{ count }}
  </button>
</template>

Dependency Injection

Please follow the template and fill the info. A PR will be auto-generated and always reflect on your changes.

Detailed solution/guide is not required, but please be sure the challenge is solvable.

Info

Basic info of your challenge questions,

difficulty: easy
title: Dependency Injection
tags: Composition API

Template

This is the template for challengers to start the coding.

If you want to commit multiple files, just create multiple blocks and identify the file name and code block

filename: App.vue

<script setup lang="ts">
import { ref, provide } from "vue"
import Child from "./Child.vue"
const count = ref(1)
provide("count", count)
setInterval(() => {
  count.value++
}, 1000)
</script>

<template>
  <Child />
</template>

filename: Child.vue

<script setup lang="ts">
// Add code to make the `count` value injected into the child component.
</script>

<template>
  {{ count }}
</template>

Dependency Injection

Please follow the template and fill the info. A PR will be auto-generated and always reflect on your changes.

Detailed solution/guide is not required, but please be sure the challenge is solvable.

Info

Basic info of your challenge questions,

difficulty: easy
title: Dependency Injection
tags: Composition API

Question

For this challenge, you'll use Composition API: Dependency Injection to finish it.
Here's what you need to implement 👇:

Template

This is the template for challengers to start the coding.

If you want to commit multiple files, just create multiple blocks and identify the file name and code block

filename: App.vue

<script setup lang="ts">
import { ref, provide } from "vue"
import Child from "./Child.vue"
const count = ref(1)
provide("count", count)
setInterval(() => {
  count.value++
}, 1000)
</script>

<template>
  <Child />
</template>

filename: Child.vue

<script setup lang="ts">
// Add code to make the `count` value injected into the child component.
</script>

<template>
  {{ count }}
</template>

依赖注入

请按照以下的模版填充相应的内容,一个 PR 会自动生成并保持与本 Issue 的内容同步。

你不需要提供详细的答案或教学,但请保证题目可解。

基本信息

# 题目难度
difficulty: easy

# 题目标题
title: 依赖注入

# 题目标签
tags: Composition API

题目模版

以下是给予挑战者开始做题的代码模版,

如果您想提交多个文件,只需创建多个<!--challenges-start--><!--challenges-end-->,并描述文件名和代码內容

filename: App.vue

<script setup lang="ts">
import { ref, provide } from "vue"
import Child from "./Child.vue"
const count = ref(1)
provide("count", count)
setInterval(() => {
  count.value++
}, 1000)
</script>

<template>
  <Child />
</template>

filename: Child.vue

<script setup lang="ts">
// Add code to make the `count` value injected into the child component.
</script>

<template>
  {{ count }}
</template>

依赖注入

请按照以下的模版填充相应的内容,一个 PR 会自动生成并保持与本 Issue 的内容同步。

你不需要提供详细的答案或教学,但请保证题目可解。

基本信息

# 题目难度
difficulty: easy

# 题目标题
title: 依赖注入

# 题目标签
tags:  Composition API

题目模版

以下是给予挑战者开始做题的代码模版,

如果您想提交多个文件,只需创建多个<!--challenges-start--><!--challenges-end-->,并按照以下格式填写文件名和代码內容

filename: App.vue

<script setup lang="ts">
import { ref, provide } from "vue"
import Child from "./Child.vue"
const count = ref(1)
provide("count", count)
setInterval(() => {
  count.value++
}, 1000)
</script>

<template>
  <Child />
</template>

filename: Child.vue

<script setup lang="ts">
// Add code to make the `count` value injected into the child component.
</script>

<template>
  {{ count }}
</template>

3 - 响应性丟失

<script setup lang="ts">
import { reactive, toRefs } from "vue"

function useCount() {
  const state = reactive({
    count: 0,
  })

  function update(value: number) {
    state.count = value
  }

  return {
    state: toRefs(state),
    update,
  }
}

// Make ensure the destructure without losing reactivity
const { state: { count }, update } = useCount()

</script>

<template>
  <div>
    <p>
      <span @click="update(count-1)">-</span>
      {{ count }}
      <span @click="update(count+1)">+</span>
    </p>
  </div>
</template>

1111-hello-world

请按照以下的模版填充相应的内容,一个 PR 会自动生成并保持与本 Issue 的内容同步。

你不需要提供详细的答案或教学,但请保证题目可解。

基本信息

# 题目难度
difficulty: easy

# 题目标题
title: hello-world

# 题目标签
tags: Components # separate by comma

题目模版

以下是给予挑战者开始做题的代码模版,

如果您想提交多个文件,只需创建多个<!--challenges-start--><!--challenges-end-->,并描述文件名和代码內容

filename: App.vue

<script setup lang='ts'>
import { ref } from "vue"

const count = ref(0)

/**
 * Implement the until function
*/

function until(initial) {
  function toBe(value) {

  }

  return {
    toBe,
  }
}

async function increase() {
  count.value = 0
  setInterval(() => {
    count.value++
  }, 1000)
  await until(count).toBe(3)
  console.log(count.value === 3) // Make sure the output to be true
}

</script>

<template>
  <p @click="increase">
    Increase
  </p>
</template>

11 - 下一次DOM更新

<script setup>
import { ref, nextTick } from 'vue'

const count = ref(0)

function increment () {
  count.value++

  /**
   * DOM not yet updated, how to make sure the DOM udpated
   * Make the output to be true
  */

  nextTick(() => {
    console.log(+document.getElementById('counter').textContent === 1)
  })
}
</script>

<template>
  <button id="counter" @click="increment">
    {{ count }}
  </button>
</template>

10 - 生命周期钩子

<script setup lang="ts">
import { onMounted, inject, onUnmounted } from "vue"

const timer = inject("timer")
const count = inject("count")

onMounted(() => {
  timer.value = window.setInterval(() => {
    count.value++
  }, 1000)
})
onUnmounted(() => {
  window.clearInterval(timer.value)
  timer.value = null
})

</script>

<template>
  <div>
    <p>
      Child Component: {{ count }}
    </p>
  </div>
</template>

你好啊

请按照以下的模版填充相应的内容,一个 PR 会自动生成并保持与本 Issue 的内容同步。

你不需要提供详细的答案或教学,但请保证题目可解。

基本信息

# 题目难度
difficulty: easy

# 题目标题
title: 你好啊

# 题目标签
tags: Components

题目模版

以下是给予挑战者开始做题的代码模版,

如果您想提交多个文件,只需创建多个<!--challenges-start--><!--challenges-end-->,并描述文件名和代码內容

filename: App.vue

<template>M</template>

14 - 动态CSS

<script setup>
import { ref } from "vue"
const theme = ref("red")

const colors = ["blue", "yellow", "red", "green"]

setInterval(() => {
  theme.value = colors[Math.floor(Math.random() * 4)]
}, 1000)

</script>

<template>
  <p>hello</p>
</template>

<style scoped>
/* Modify the code to bind the dynamic color */
p {
  color: v-bind(theme);
}
</style>

1112-hello-world

Please follow the template and fill the info. A PR will be auto-generated and always reflect on your changes.

Detailed solution/guide is not required, but please be sure the challenge is solvable.

Info

Basic info of your challenge questions,

difficulty: medium
title: hello-world
tags: Composable Function

Template

This is the template for challengers to start the coding.

If you want to commit multiple files, just create multiple blocks and identify the file name and code block

filename: App.vue

<script setup lang='ts'>

/**
 * Implement a composable function that toggle state
 * Make the function work fine
*/
function useToggle() {

}

const [state, toggle] = useToggle(false)

</script>

<template>
  <p>State: {{ state ? 'ON' : 'OFF' }}</p>
  <p @click="toggle">
    Toggle state
  </p>
</template>

5 - watch 全家桶

<script setup lang="ts">
import { ref, watch } from "vue"

const count = ref(0)

/**
 * Challenges 1: Watch once
 * Make sure the watch callback only trigger once
*/
const unWatch = watch(count, () => {
  console.log("Only triggered once1")
  unWatch()
})

count.value = 1
setTimeout(() => count.value = 2)

/**
 * Challenges 2: Watch object
 * Make sure the watch callback triggered
*/
const state = ref({
  count: 0,
})

watch(state, () => {
  console.log("The state.count updated")
}, {
  deep: true
})

state.value.count = 2

/**
 * Challenges 3: Callback Flush Timing
 * Make sure visited the updated eleRef
*/

const eleRef = ref()
const age = ref(2)
watch(age, () => {
  console.log(eleRef.value)
}, {
  flush: 'post'
})
age.value = 18

</script>

<template>
  <div>
    <p>
      {{ count }}
    </p>
    <p ref="eleRef">
      {{ age }}
    </p>
  </div>
</template>

14 - 动态CSS

<script setup>
import { ref } from "vue"
const theme = ref("red")

const colors = ["blue", "yellow", "red", "green"]

setInterval(() => {
  theme.value = colors[Math.floor(Math.random() * 4)]
}, 1000)

</script>

<template>
  <p>hello</p>
</template>

<style scoped>
/* Modify the code to bind the dynamic color */
p {
  color: v-bind(theme)
}
</style>

13 - DOM传送门

<script setup>

const msg = "Hello World"

</script>

<template>
  <Teleport to="body">
    <!-- Renders its to a child element of the `body` -->
    <span>{{ msg }}</span>
  </Teleport>
</template>

Dependency Injection

Please follow the template and fill the info. A PR will be auto-generated and always reflect on your changes.

Detailed solution/guide is not required, but please be sure the challenge is solvable.

Info

Basic info of your challenge questions,

difficulty: easy
title: Dependency Injection
tags: Composition API

Template

This is the template for challengers to start the coding.

If you want to commit multiple files, just create multiple blocks and identify the file name and code block

filename: App.vue

<script setup lang="ts">
import { ref, provide } from "vue"
import Child from "./Child.vue"
const count = ref(1)
provide("count", count)
setInterval(() => {
  count.value++
}, 1000)
</script>

<template>
  <Child />
</template>

filename: Child.vue

<script setup lang="ts">
// Add code to make the `count` value injected into the child component.
</script>

<template>
  {{ count }}
</template>

1 - Hello World

<script setup>
import { ref } from "vue"
const msg = ref("Hello World")
</script>

<template>
  <div>
    <h1>{{ msg }}</h1>
  </div>
</template>

14 - 动态CSS

<script setup>
import { ref } from "vue"
const theme = ref("red")

const colors = ["blue", "yellow", "red", "green"]

setInterval(() => {
  theme.value = colors[Math.floor(Math.random() * 4)]
}, 1000)

</script>

<template>
  <p>hello</p>
</template>

<style scoped>
/* Modify the code to bind the dynamic color */
p {
  color: v-bind('theme')
}
</style>

1001-hello-world

Please follow the template and fill the info. A PR will be auto-generated and always reflect on your changes.

Detailed solution/guide is not required, but please be sure the challenge is solvable.

Info

Basic info of your challenge questions,

difficulty: easy # medium / hard / extreme
title: Your Question Name
tags: Directvies, Components # separate by comma

Template

This is the template for challengers to start the coding.

If you want to commit multiple files, just create multiple blocks and identify the file name and code block

filename: App.vue

<script setup lang="ts">
import { ref, provide } from "vue"
import Child from "./Child.vue"
const count = ref(1)
provide("count", count)
setInterval(() => {
  count.value++
}, 1000)
</script>

<template>
  <Child />
</template>

依赖注入

请按照以下的模版填充相应的内容,一个 PR 会自动生成并保持与本 Issue 的内容同步。

你不需要提供详细的答案或教学,但请保证题目可解。

基本信息

# 题目难度
difficulty: easy

# 题目标题
title: 依赖注入

# 题目标签
tags: Composition API

题目

在这个挑战中,你将使用 组合式 API: 依赖注入 来完成它。
以下是你要实现的内容 :

题目模版

以下是给予挑战者开始做题的代码模版,

如果您想提交多个文件,只需创建多个<!--challenges-start--><!--challenges-end-->,并按照以下格式填写文件名和代码內容

filename: App.vue

<script setup lang="ts">
import { ref, provide } from "vue"
import Child from "./Child.vue"
const count = ref(1)
provide("count", count)
setInterval(() => {
  count.value++
}, 1000)
</script>

<template>
  <Child />
</template>

filename: Child.vue

<script setup lang="ts">
// Add code to make the `count` value injected into the child component.
</script>

<template>
  {{ count }}
</template>

25 - 鼠标坐标

<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue'

// Implement ...
function useEventListener(target, event, callback) {
  onMounted(() => target.addEventListener(event, callback))
  onUnmounted(() => target.removeEventListener(event, callback))
}

// Implement ...
function useMouse() {
  const x = ref(0)
  const y = ref(0)

  useEventListener(window, 'mousemove', (event) => {
    x.value = event.pageX
    y.value = event.pageY
  })

  return { x, y }
}
const { x, y } = useMouse()
</script>

<template>Mouse position is at: {{ x }}, {{ y }}</template>

2 - ref 全家桶

<script setup lang="ts">
import { ref, Ref, toRefs, isRef, unref, reactive } from "vue"

const initial = ref(10);
const count = ref(0)

// Challenge 1: Update ref
function update(value) {
  count.value = value;
}

/**
 * Challenge 2: Checks if `count` is a ref object.
 * Make the output to be 1
*/
console.log(
  isRef(count) ? 1 : 0
)

/**
 * Challenge 3: Unwrap ref
 * Make the output to be true
*/
function initialCount(value: number | Ref<number>) {
  // Make the output to be true
  console.log(unref(value) === 10)
}

initialCount(initial)

/**
 * Challenge 4:
 * create a ref for a property on a source reactive object.
 * The created ref is synced with its source property:
 * mutating the source property will update the ref, and vice-versa.
 * Make the output to be true
*/
const state = reactive({
  foo: 1,
  bar: 2,
})
const fooRef = toRefs(state)

// mutating the ref updates the original
fooRef.foo.value++
console.log(state.foo === 2)

// mutating the original also updates the ref
state.foo++
console.log(fooRef.foo.value === 3)

</script>

<template>
  <div>
    <p>
      <span @click="update(count-1)">-</span>
      {{ count }}
      <span @click="update(count+1)">+</span>
    </p>
  </div>
</template>

15 - 切换器

<script setup lang='ts'>
import {ref} from 'vue'
/**
 * Implement a composable function that toggle state
 * Make the function work fine
*/
function useToggle(args:boolean) {
	const state = ref(args);
  const toggle = ()=>{
    state.value = !state.value
  }
  return [state,toggle]
}

const [state, toggle] = useToggle(false)

</script>

<template>
  <p>State: {{ state ? 'ON' : 'OFF' }}</p>
  <p @click="toggle">
    Toggle state
  </p>
</template>

依赖注入

请按照以下的模版填充相应的内容,一个 PR 会自动生成并保持与本 Issue 的内容同步。

你不需要提供详细的答案或教学,但请保证题目可解。

基本信息

# 题目难度
difficulty: easy 

# 题目标题
title: 依赖注入

# 题目标签
tags: Composition API

题目模版

以下是给予挑战者开始做题的代码模版,

如果您想提交多个文件,只需创建多个<!--challenges-start--><!--challenges-end-->,并描述文件名和代码內容

filename: App.vue

<script setup lang="ts">
import { ref, provide } from "vue"
import Child from "./Child.vue"
const count = ref(1)
provide("count", count)
setInterval(() => {
  count.value++
}, 1000)
</script>

<template>
  <Child />
</template>

filename: Child.vue

<script setup lang="ts">
// Add code to make the `count` value injected into the child component.
</script>

<template>
  {{ count }}
</template>

2 - ref 全家桶

<script setup lang="ts">
import { ref, isRef, unref, toRef, Ref, reactive } from "vue"

const initial = ref(10)
const count = ref(0)

// Challenge 1: Update ref
function update(value) {
  // impl...
  count.value = value
}

/**
 * Challenge 2: Checks if `count` is a ref object.
 * Make the output to be 1
*/
console.log(
  // impl ? 1 : 0
  isRef(count) ? 1 : 0
)

/**
 * Challenge 3: Unwrap ref
 * Make the output to be true
*/
function initialCount(value: number | Ref<number>) {
  value = unref(value)
  // Make the output to be true
  console.log(value === 10)
  update(value)
}

initialCount(initial)

/**
 * Challenge 4:
 * create a ref for a property on a source reactive object.
 * The created ref is synced with its source property:
 * mutating the source property will update the ref, and vice-versa.
 * Make the output to be true
*/
const state = reactive({
  foo: 1,
  bar: 2,
})
const fooRef = toRef(state, 'foo') // change the impl...

// mutating the ref updates the original
fooRef.value++
console.log(state.foo === 2)

// mutating the original also updates the ref
state.foo++
console.log(fooRef.value === 3)

</script>

<template>
  <div>
    <p>
      <span @click="update(count-1)">-</span>
      {{ count }}
      <span @click="update(count+1)">+</span>
    </p>
  </div>
</template>

4 - 可写的计算属性

<script setup lang="ts">
import { ref, computed } from "vue"

const count = ref(1)
const plusOne = computed({
  get: () => count.value + 1,
  set: (v) => {count.value = v}
})

/**
 * Make the `plusOne` can be written.
 * So we'll get the result is `plusOne` to be 3, and `count` to be 2.
*/

plusOne.value++

</script>

<template>
  <div>
    <p>{{ count }}</p>
    <p>{{ plusOne }}</p>
  </div>
</template>

Dependency Injection

Please follow the template and fill the info. A PR will be auto-generated and always reflect on your changes.

Detailed solution/guide is not required, but please be sure the challenge is solvable.

Info

Basic info of your challenge questions,

difficulty: easy
title: Dependency Injection
tags: Composition API

Question

For this challenge, you'll use Composition API: Dependency Injection to finish it.
Here's what you need to implement 👇:

Template

This is the template for challengers to start the coding.

If you want to commit multiple files, just create multiple blocks and identify the file name and code block

filename: App.vue

<script setup lang="ts">
import { ref, provide } from "vue"
import Child from "./Child.vue"
const count = ref(1)
provide("count", count)
setInterval(() => {
  count.value++
}, 1000)
</script>

<template>
  <Child />
</template>

filename: Child.vue

<script setup lang="ts">
// Add code to make the `count` value injected into the child component.
</script>

<template>
  {{ count }}
</template>

13 - DOM传送门

<script setup>

const msg = "Hello World"

</script>

<template>
  <!-- Renders its to a child element of the `body` -->
  <Teleport to="body">
    <span>{{ msg }}</span>
  </Teleport>
</template>

9 - 依赖注入

<script setup lang="ts">
// Add code to make the `count` value injected into the child component.
import { inject } from 'vue'
  
const count = inject('count')
</script>

<template>
  {{ count }}
</template>

12 - 优化性能的指令

<script setup>
import { ref } from "vue"

const count = ref(0)

setInterval(() => {
  count.value++
}, 1000)
</script>

<template>
  <span v-once>Make it never change: {{ count }}</span>
</template>

1 - 你好 !

<script setup>
import { ref } from "vue"
const msg = ref("Hello World")
</script>

<template>
  <div>
    <h1>{{msg}}</h1>
  </div>
</template>

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.