文章内容输出来源:拉勾教育大前端高薪训练营
一、Composition API使用
在不借助任何构建工具的情况下,使用script标签设置type为module的方式引入vue.esm-browser.js模块,来学习Composition API使用
注意:如果直接右键在浏览器中打开页面,会报跨域的错误如下截图,需要借助vscode的Live Server插件在本地运行一个服务才可以正常访问,安装Live Server,然后右键“open with Live Server”,为什么会跨域可以参考:blog.csdn.net/qq_44163269…
- creatApp: 创建Vue对象
- setup: CompositionApI的入口
- reactive:创建响应式对象
<body>
<div id="app">
x: {{ position.x }} <br>
y: {{ position.y }} <br>
</div>
<script type="module">
import { createApp, reactive } from './node_modules/vue/dist/vue.esm-browser.js'
// createApp 的作用是创建一个vue对象,接收一个选项作为参数,也就是一个组件的选项,与Vue.js 2.x给Vue构造函数传入的选项一样,可以传入data,methods,created,components等
const app = createApp({
setup () {
// 第一个参数 props,响应式对象,不能被解构
// 第二个参数 context, attrs、emit、slots
const position = reactive({
x: 0,
y: 0
})
return {
position
}
},
mounted () {
this.position.x = 100
}
})
console.log(app)
app.mount('#app')
</script>
</body>
二、setup中的生命周期钩子函数
- 在setup中可以使用组件生命周期的钩子函数,但是要在函数名称前面加
on并且函数名称首字母大写,例如:mounted在setup中要写成onMounted,还要在import中导入使用的钩子函数 - setup在beforeCreate和created之间执行,对应的代码都可以在setup中执行,所以不需要再在setup中注册beforeCreate和created
- onUnmounted相当于2.x版本中的destoryed
- 新增钩子函数:
onRenderTrackedonRenderTriggered(都是在render函数被重新调用的时候触发,区别在于onRenderTracked在首次调用render时也会触发,而onRenderTriggered首次调用render时不会触发)
<body>
<div class="" id="app">
x: {{ position.x }} <br>
y: {{ position.y }}
</div>
<script type="module">
import { createApp, reactive, onMounted, onUnmounted } from './node_modules/vue/dist/vue.esm-browser.js' // 按需导入
function useMousePosition() {
const position = reactive({
x: 0,
y: 0
})
// 事件处理函数
const update = e => {
position.x = e.pageX
position.y = e.pageY
}
onMounted(() => {
window.addEventListener('mousemove', update)
})
onUnmounted(() => {
window.removeEventListener('mousemove', update)
})
return position
}
// createApp 的作用是创建一个vue对象,接收一个选项作为参数,也就是一个组件的选项,与Vue.js 2.x给Vue构造函数传入的选项一样,可以传入data,methods,created,components等
const app = createApp({
setup() {
const position = useMousePosition()
return {
position
}
}
})
console.log(app)
app.mount('#app')
</script>
</body>
三、reactive-toRefs-ref
- reactive创建的响应式数据解构后不再是响应式,toRefs可以把响应式对象的所有属性也转换成响应式的,所以可以解构toRefs返回的对象,解构之后还是响应式数据;
- reactive是把普通对象转化成响应式对象,而ref是将基本类型数据包装成响应式对象。 toRefs的使用:
<body>
<div class="" id="app">
x: {{ x }} <br>
y: {{ y }}
</div>
<script type="module">
import { createApp, reactive, onMounted, onUnmounted, toRefs } from './node_modules/vue/dist/vue.esm-browser.js' // 按需导入
function useMousePosition() {
const position = reactive({
x: 0,
y: 0
})
// 事件处理函数
const update = e => {
position.x = e.pageX
position.y = e.pageY
}
onMounted(() => {
window.addEventListener('mousemove', update)
})
onUnmounted(() => {
window.removeEventListener('mousemove', update)
})
return toRefs(position) // toRefs把响应式对象的所有属性也转化成响应式的
}
// createApp 的作用是创建一个vue对象,接收一个选项作为参数,也就是一个组件的选项,与Vue.js 2.x给Vue构造函数传入的选项一样,可以传入data,methods,created,components等
const app = createApp({
setup() {
const { x, y } = useMousePosition() // toRefs返回的对象,解构之后还是响应式数据
return {
x,
y
}
}
})
console.log(app)
app.mount('#app')
</script>
</body>
ref的使用:
<body>
<div id="app">
<button @click="increase">点击加1</button>
<span>{{ count }}</span>
</div>
<script type="module">
import { createApp, ref } from './node_modules/vue/dist/vue.esm-browser.js'
function useCount() {
const count = ref(0) // 将基本类型数据转化成响应式对象
return {
count,
increase: () => {
count.value++ // 代码中使用的时候value不能省略,模板中使用可以省略
}
}
}
createApp({
setup() {
return {
...useCount()
} // 把变量和方法一起解构出来
}
}).mount('#app')
</script>
</body>
四、Computed
computed可以创建一个响应式数据,这个响应式数据依赖于其他响应式数据,就是计算属性。
- 第一种用法
- computed(()=>count.value+1)
- 第二种用法
const count = ref(1)
const plusOne = computed({
get: () => count.value + 1,
set: val => {
count.value = val - 1
}
})
案例:
<body>
<div id="app">
<button @click="push">添加待办</button>
<span>未完成的数量:{{ activeCount }}</span>
</div>
<script type="module">
import { createApp, reactive, computed } from './node_modules/vue/dist/vue.esm-browser.js'
const data = [
{ text: '看书', completed: false },
{ text: '敲代码', completed: false },
{ text: '约会', completed: true },
]
createApp({
setup() {
const todos = reactive(data)
const activeCount = computed(() => {
return todos.filter(item => !item.completed).length
})
return {
activeCount,
push: () => {
todos.push({
text: '开会',
completed: false
})
}
}
}
}).mount('#app')
</script>
</body>
五、Watch
1. Watch的三个参数:
- 第一个参数:要监听的数据,可以是ref或者是reactive响应式数据
- 第二个参数:监听到数据变化后执行的函数,这个函数有两个参数分别是新值和旧值
- 第三个参数:选项对象,deep和immediate
2.Watch的返回值
- 取消监听的函数 案例:
<body>
<div id="app">
请选择一个yes/no的问题:
<input v-model.lazy="question">
<p>{{answer}}</p>
</div>
<script type="module">
import { createApp, ref, watch } from './node_modules/vue/dist/vue.esm-browser.js'
createApp({
setup () {
const question = ref('')
const answer = ref('')
watch(question, async (newValue, oldValue) => {
const response = await fetch('https://www.yesno.wtf/api')
const data = await response.json()
answer.value = data.answer
})
return {
question,
answer
}
}
}).mount('#app')
</script>
</body>
六、WatchEffect
- 是Watch函数的简化版本,也用来监视数据的变化,不同的是没有第二个参数
- 接受一个函数作为参数,监听函数内响应式数据的变化,当函数内响应式数据发生变化时函数会立即再调用一次
- 也是返回一个取消监听的函数 案例:
<body>
<div id="app">
<button @click="increase">increase</button>
<button @click="stop">stop</button>
<span>{{count}}</span>
</div>
<script type="module">
import { createApp, ref, watchEffect } from './node_modules/vue/dist/vue.esm-browser.js'
createApp({
setup() {
const count = ref(0)
const stop = watchEffect(()=>{
console.log(count.value)
})
return {
count,
stop,
increase: ()=>{
count.value++
}
}
}
}).mount('#app')
</script>
</body>