vite和@vue/cli区别
@vue/cli更稳定些,提供的模块更多 vite编译速度更快
TS+Vue3安装方式
vue create vuecli-ts-test
vue add typescript
提示class-style的时候 选择no
vue-router配置
添加路由4步:
-
安装vue-router@next cnpm install vue-router@next --save
-
创建router.ts文件,配置路由
import { createRouter,createWebHashHistory } from "vue-router";
import Home from './components/Home.vue'
import User from './components/User.vue'
// 配置路由
const router = createRouter({
history: createWebHashHistory(),
routes: [
{path: '/',component: Home},
{path: '/user',component: User}
]
})
export default router
- 在main.ts中引入router.ts,并挂载
import { createApp } from 'vue'
import App from './App.vue'
import routes from './router' //不能带.ts,不然会报错
let app= createApp(App)
app.use(routes)
app.mount('#app')
- 在app.vue根组件中动态加载配置的组件
<router-view></router-view>
根据链接地址动态的跳转到路由地址
<router-link to='/user'>跳转到user</router-link>
其他同Vue2
集成vuex
- 安装vuex@next
cnpm install vuex@next --save
- 新建store.ts文件
import {createStore, Store} from 'vuex'
import {ComponentCustomProperties} from 'vue'
// 能在vue中得到this,必须加这些
declare module '@vue/runtime-core' {
// 在传给createStore的state中定义的属性都得在interface中申明,不然在vue中是获取不到的通过store是获取不到state中的元素
interface State{
count: number,
list: string[],
msg: string
}
interface ComponentCustomProperties {
$store: Store<State>
}
}
const store = createStore({
state(){
return{
count:1,
list:['马总','李总'],
msg:'你好vue'
}
},
mutations:{
incCount(state:any){
state.count++
},
setCount(state, num){
state.count = num
},
setMsg(state,msg){
state.msg = msg
}
},
getters: {
reverseMsg(state){
return state.msg.split('').reverse().join('')
},
num(state){
return state.count + 10
}
},
actions: {
incCount(context){
context.commit('incCount')
},
setCount({commit},num){
commit('setCount',num)
}
}
})
export default store
- 在main.ts中引入store.ts,并挂载
app.use(store)
- 在vue文件中使用 引入useStore,加上lang="ts"
<script lang="ts">
import { computed, defineComponent } from 'vue';
import { useStore } from 'vuex'
// 比如必须传指定的接口
// defineComponent不能少,启用类型判断
export default defineComponent({
setup(){
// 在defineComponent获取store
const store = useStore()
let incCount=()=>{
store.commit('incCount')
}
let incActionCount=()=>{
store.dispatch('incCount')
}
// 获取到store,就能获取到store中的数据
return {
count: computed(()=>{
return store.state.count
}),
incCount,
num: computed(()=>{
return store.getters.num
}),
incActionCount,
setActionCount:(q:any)=>{
store.dispatch('setCount',q)
}
}
}
<、script>
小项目中vuex可以不使用,vue3中可以使用provide和inject来代替
在provide使用一些组件实例 property,以下使用方式则这将不起作用
data() {
return {
todos: ['Feed a cat', 'Buy tickets']
}
},
provide: {
todoLength: this.todos.length // 将会导致错误 'Cannot read property 'length' of undefined`
},
要访问组件实例 property,我们需要将 provide 转换为返回对象的函数
provide() {
return {
todoLength: this.todos.length
}
}
在上面的例子中,如果我们更改了 todos 的列表,这个更改将不会反映在注入的 todoLength property 中。这是因为默认情况下,provide/inject 绑定不是被动绑定
。
可以通过将 ref property 或 reactive 对象传递给 provide
来更改此行为。
也可以分配一个组合式 API computed property
provide() {
return {
todoLength: Vue.computed(() => this.todos.length)
}
}
怎么增加提供值和注入值之间的响应性?
为了增加提供值和注入值之间的响应性,我们可以在提供值时使用 ref 或 reactive
const location = ref('North Pole')
const geolocation = reactive({
longitude: 90,
latitude: 135
})
provide('location', location)
provide('geolocation', geolocation)
当使用响应式提供/注入值时,建议尽可能,在提供者内保持响应式 property 的任何更改
methods: {
updateLocation() {
this.location = 'South Pole'
}
}
有时我们需要在注入数据的组件内部更新注入的数据。在这种情况下,我们建议提供一个方法来负责改变响应式 property
const updateLocation = () => {
location.value = 'South Pole'
}
provide('updateLocation', updateLocation)
如果要确保通过 provide 传递的数据不会被注入的组件更改,我们建议对提供者的 property 使用 readonly
provide('location', readonly(location))
setup(props,context)接收两个参数
setup () 内部调用生命周期钩子
setup 函数中的 props 是响应式的,如果需要解构 prop,可以通过使用 setup 函数中的 toRefs 来完成此操作
因为 props 是响应式的,你不能使用 ES6 解构,因为它会消除 prop 的响应性
setup(props) {
const title = toRef(props, 'title')
console.log(title.value)
setup 函数中的context,不是响应式的,可以解构,暴露三个组件的 property:attrs, slots, emit
setup(props, { attrs, slots, emit }) {
}
attrs 和 slots 是有状态的对象,它们总是会随组件本身的更新而更新。这意味着你应该避免对它们进行解构,并始终以 attrs.x 或 slots.x 的方式引用 property
。
请注意,与 props 不同,attrs 和 slots 是非响应式的。如果你打算根据 attrs 或 slots 更改应用副作用,那么应该在 onUpdated 生命周期钩子中执行此操作
。
执行 setup 时,组件实例尚未被创建
只能访问以下 property:
props / attrs / slots / emit
换句话说,你将无法访问以下组件选项:
data / computed / methods
setup 可以返回一个对象
setup() {
const readersNumber = ref(0)
const book = reactive({ title: 'Vue 3 Guide' })
// expose to template
return {
readersNumber,
book
}
}
setup 可以返回一个渲染函数
该函数可以直接使用在同一作用域中声明的响应式状态
setup() {
return {
count: computed(()=>{
return store.state.count
})
}
}
在 setup() 内部,this 不会是该活跃实例的引用
因为 setup() 是在解析其它组件选项之前被调用的,所以 setup() 内部的 this 的行为与其它选项中的 this 完全不同。这在和其它选项式 API 一起使用, setup() 时可能会导致混淆。