Vue3.0-beta
笔记来自
lookroot视频
lookroot博客
前提
- 查看vue脚手架版本,必须是最新版
vue -V
- 创建项目
vue create vue3demo
- 升级3.0
cd vue3demo
vue add vue-next
- 开始写代码
- 如果不想用脚手架可以用cdn引入,或者去下载源码自己build,build的结果是dist里的
vue.global.js
- 源码地址
有什么变化
- vue的功能模块可以单独使用了
// 这些功能往下看
import { reactive, toRefs, ref, computed, watch } from "vue";
- 定义变量和方法,都写在setup方法里,这个方法不需要引入
// ref,reactive,toRefs 怎么用
export default {
name: "Home",
setup() {
// 这种新写法就有 react-hook 内味了
// 定义一个ref响应式对象
const count = ref(0);
// 如果要定义多个可以使用reactive
const state = reactive({
size: 36,
color: "red"
});
// 定义一个方法
const increment = () => {
count.value++;
};
const talk = e => {
console.log(e);
};
// 变量和方法都需要return
return {
count,
increment,
// state
...toRefs(state),
talk
};
}
};
- 生命周期变了
// beforeCreate -> 使用 setup()
// created -> 使用 setup()
// beforeMount -> onBeforeMount
// mounted -> onMounted
// beforeUpdate -> onBeforeUpdate
// updated -> onUpdated
// beforeDestroy -> onBeforeUnmount
// destroyed -> onUnmounted
// errorCaptured -> onErrorCaptured
// 生命周期同样需要引入,写在setup里面,但不需要return
import { onMounted, onUnmounted } from "vue";
export default {
name: "Home",
setup() {
onMounted(() => {
console.log("onMounted");
});
}
};
- 计算属性和watch
<template>
<div>
<div>{{num2}}</div>
<button @click="increment">increment</button>
<button @click="stopwatch">stopwatch</button>
</div>
</template>
import { reactive, watch, computed, toRefs, watchEffect } from "vue";
export default {
setup() {
const state = reactive({
num1: 1,
num2: computed(() => state.num1 * 2)
});
// 如果响应性的属性有变更,就会触发这个函数,但他是惰性的
const watcheffectstop = watchEffect(() => {
console.log(`effect 触发了!${state.num1}`);
});
// 定义一个监听器
const stop = watch(state, (val, oldVal) => {
console.log("watch ", oldVal.num1);
});
//数值增加方法
const increment = () => state.num1++;
// 停止监听,
const stopwatch = () => {
stop();
watcheffectstop();
};
return {
...toRefs(state),
stopwatch,
increment
};
}
};
- 双ref控制dom
<template>
<div>
// 第一个ref
<div ref="refdemo">domref</div>
<input type="range" v-model="size" />
</div>
</template>
import { ref, watch, } from "vue";
export default {
setup() {
// 定义空白ref作为Template ref操作 dom
const refdemo = ref(null);
const size = ref(24);
// 监听拖动
watch(size, (val, oldVal) => {
refdemo.value.style.fontSize = size.value + "px";
});
return {
refdemo,
size
};
}
};
- 使用组件
import HelloWorld from "../components/HelloWorld";
import DomRef from "../components/DomRef";
export default {
name: "Home",
components: {
HelloWorld,
DomRef,
}
}
- 组件传参
<template>
<div>
<ComDemo :name="name" @talk="talk"></ComDemo>
</div>
</template>
import ComDemo from "../components/ComDemo";
export default {
name: "Home",
components: {
ComDemo
},
setup() {
const name = ref("name");
const talk = e => {
console.log(e);
name = e;
};
return {
name,
talk,
};
}
};
// ComDemo.vue
export default {
props: {
name: String
},
setup(props, context) {
// setup中使用 prop
// console.log("props.name:" + props.name);
// 供父组件测试
const talk = () => {
// 第二个参数会传给父组件
context.emit("talk", "我是子组件我触发你了");
};
return {
str,
talk
};
}
};
- mixin,这个直接消失了
// mixin.js
export useMouse = () => {
const state = reactive({
x: 0,
y: 0
});
const update = e => {
state.x = e.pageX;
state.y = e.pageY;
};
onMounted(() => {
window.addEventListener("mousemove", update);
});
onUnmounted(() => {
window.removeEventListener("mousemove", update);
});
return toRefs(state);
};
// 监控键盘事件
export useKeyBoard = () => {
const status = ref(false);
const update = () => {
status.value = !status.value;
};
onMounted(() => {
window.addEventListener("keypress", update);
});
onUnmounted(() => {
window.removeEventListener("onkeydown", update);
});
return {
status
};
};
// 在别的模块使用
import { useKeyBoard, useMouse } from "mixin";
export default {
name: "HelloWorld",
setup() {
return {
...useMouse(),
...useKeyBoard()
};
}
};
- vuex变了
// vuex
import Vuex from 'vuex'
export default Vuex.createStore({
state: {
count: 0
},
mutations: {
increment(state) {
state.count++;
console.log('当前count:',state.count);
}
},
actions: {},
modules: {}
});
// 使用
export default {
setup() {
// 使用vuex
const store = useStore();
const count = store.state.count;
console.log("vuex >>", count);
const increment = () => {
// mutations
store.commit("increment");
};
}
};
- vue-router变了
// vue-router
import {
createRouter,
createWebHashHistory
} from 'vue-router';
import Home from '../views/Home.vue'
const routes = [{
path: '/',
name: 'Home',
component: Home
},
{
path: '/about',
name: 'About',
component: () => import( /* webpackChunkName: "about" */ '../views/About.vue')
}
]
const router = createRouter({
history: createWebHashHistory(),
routes
})
export default router
// 使用
import { useRouter } from "vue-router";
export default {
setup() {
// 使用vue-router
const router = useRouter();
const gotoAbout = () => {
router.push("About");
};
return {
gotoAbout
};
}
};
- main.js示例
// 旧版
import App from './App'
import store from './store'
import router from './router'
new Vue({
// 这个就是路由
router,
// 这个是vuex
store,
// render渲染,$mount是代表index.html的id
// 即我把App.vue渲染到id为app的div里
render: h => h(App)
}).$mount('#app')
// 新版
import { createApp } from 'vue';
import App from './App.vue'
import router from './router'
import store from './store'
createApp(App).use(router).use(store).mount('#app')