2020.01.08
3240
fish
Vue3 尝鲜
首先,在GitHub上拉取最新代码
$ git pull https://github.com/vuejs/vue-next.git $ cd vue-next && yarn 复制代码
下载完成之后打开代码, 开启sourceMap 1、tsconfig.json 把sourceMap字段修改为true
2、rollup.onfig.js 在rollup.config.js中,手动键入output.sourcemap = true3、yarn dev4、在根目录创建一个demo目录用于存放示例代码 并在demo目录下创建html、js文件,引入构建后的vue文件第一个Hello World!!!/demo/index.html
<html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Documenttitle> <style> .container { text-align: center; font-size: 24px; padding: 32px;
} style> <script src="../packages/vue/dist/vue.global.js">script> head> <body> <div id="app">div> body> <script src="./index.js">script> html> 复制代码
/demo/index.js
const { reactive } = Vue var App = { template: `
{{message}}
`,
setup() { const state = reactive({message: "Hello World!!!"}) return {
...state
}
}
}
Vue.createApp().mount(App, '#app') 复制代码
在浏览器打开咱们编写的html文件,
这里的服务器环境使用serve库来创建的,有兴趣的话可以看下serveanyway,咱们接着看咱们的/demo/index.js文件,可以看到,咱们用了setup, reactive等函数,这就是Vue3的Composition API,相对于Vue2的组件来说 3 可以让我们很简单的通过组合API的方式创建一个 基于Vue3 响应式 Web 应用。 下边我会通过一个个的demo为大家详细解释这些API。
接下来咱们实现一个双向绑定的demo!!!
const { reactive } = Vue let App = { template: `
{{value}}
`,
setup() { return reactive({ value: '' })
}
}
Vue.createApp().mount(App, '#app') 复制代码
setup接受两个参数,第一个参数是props, 另一个参数是context,所以大家在使用2.0时习惯的在this下获取属性的方式 ,在 vue3.0 中,变成了:
setup(props, ctx) { console.log(props, ctx)
} 复制代码
不过在模板中仍然可以直接使用props的属性值,例如:
let Child = { template: `
{{title}}
`,
setup(props, context) { console.log(props)
}
} let App = { template: `
`, components: { Child }
}
Vue.createApp().mount(App, '#app') 复制代码
那reactive???之前用的 data呢??? 在Vue3中,我们可以把数据经过 reactive 加工变成响应式的对象,用于模版的渲染数据, 当然Vue的向下兼容 还是允许我们使用data的方式实现,但既然Vue3出新的写法了,何不尝试一波呢
const { reactive, toRefs } = Vue let App = { template: `
count: {{count}}
`,
setup() { const state = reactive({ count: 0 }) const handlerCountAdd = () => {
state.count++
} return { ...toRefs(state), handlerCountAdd }
}
}
Vue.createApp().mount(App, '#app') 复制代码
这个toRefs是??????????? 在说这个之前 我想先说下 ref ,vue3提供的ref让我们有机会创建单个的响应式的对象,在setup函数中return出去之后,在模板中可直接访问,例:
const App = { template: `
{{value}}
`,
setup() { const value = ref(1) return value
}
}
Vue.createApp().mount(App, '#app') 复制代码
可以看到 vulue已经被渲染到页面上。
那上文提到的reactive创建的响应式对象 在模板中访问的话,则需要state.xxx, 例:
const App = { template: `
{{state.value}}
`,
setup() { const state = reactive({ value: 'reactive' }) return { state }
}
}
Vue.createApp().mount(App, '#app') 复制代码
这样访问属性确实有点麻烦,vue3提供的toRefs正是为我们解决这个问题的,toRefs把一组的响应式对象拆成单个的响应式对象,就能够在模板中直接访问了,及:
const App = { template: `
{{value}}
`,
setup() { const state = reactive({ value: 'reactive' }) return toRefs(state)
}
}
Vue.createApp().mount(App, '#app') 复制代码
let App = { template: `
value:
rvalue: {{rvalue}}
`,
setup() { const state = reactive({ value: '', rvalue: computed(() => state.value
.split('')
.reverse()
.join('')
)
}) return toRefs(state)
}
}
Vue.createApp().mount(App, '#app') 复制代码
大家都知道, 在Vue3中实现数据响应式的方案由Vue2中的Object.defineProperty 换成了 Proxy,关于数据响应式的Api上边说到了一些,还剩下effect和watch没有提及到,effect是数据响应式中重要的一部分,watch和computed都是基于 effect 的,下边来看下代码
let App = { template: `
count: {{count}}
`,
setup() { const state = reactive({ count: 0, value: 1 }) const handlerCountAdd = () => {
state.count++
}
watch( () => state.count,
val => { console.log('watch', state.count) console.log('watch', state.value)
}
)
effect(() => { console.log('effect', state.count) console.log('effect', state.value)
}) return { ...toRefs(state), handlerCountAdd }
}
}
Vue.createApp().mount(App, '#app') 复制代码
代码是基于上边计数器的demo来实现的,可以看到咱们点击click++的时候,effect和watch都可以监听到咱们数据的变化,从而根据业务作出相应的操作, 看到这里,大家可能会有一个疑问,那就是,既然effect和watch都能监听到数据的变化,那两者有什么区别呢?
首先,effect 在响应式数据变化的时候就会执行,执行次数根据响应式数据的个数来决定,例如
let App = { template: `
`,
setup() { const r = ref(1) const s = ref(1) const t = ref(1) const handlerCountAdd = () => {
r.value *= 1 s.value *= 2 t.value *= 3 }
effect(() => { console.log('effect', [r.value, s.value, t.value])
}) return { handlerCountAdd }
}
}
Vue.createApp().mount(App, '#app') 复制代码
而watch则点击一次 ,只会触发执行一次
let App = { template: `
`,
setup() { const state = reactive({ count: 0, value: 1 }) const r = ref(1) const s = ref(1) const t = ref(1) const handlerCountAdd = () => {
r.value *= 1 s.value *= 2 t.value *= 3 }
watch([r, s, t], val => { console.log('watch', val)
}) return { handlerCountAdd }
}
}
Vue.createApp().mount(App, '#app') 复制代码
vue3 Watch的源码在这里有兴趣的小伙伴可以研究研究
好了,vue3Composition Api中常用的一些函数在咱上边的demo中使用了,接下来咱们对比一下2和3的生命周期函数有什么改变
Vue2 | Vue3 |
---|---|
beforeCreate | setup(替代) |
created | setup(替代) |
beforeMount | onBeforeMount |
mounted | onMounted |
beforeUpdate | onBeforeUpdate |
updated | onUpdated |
beforeDestroy | onBeforeUnmount |
destroyed | onUnmounted |
errorCaptured | onErrorCaptured |
虽然Vue官方说可以直接运行run dev 就可以对其进行调试,可是运行该命令后,是生成过后的代码,不能对其编写的ts源码进行调试。
开启了sourcemap之后,在编译时会生成对应的sourcemap文件,然后赞么就可以在浏览器愉快的使用断点调试Vue的源代码了篇幅很大,感谢大家耐心观看,文中如有错误欢迎指正。