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')
原文地址:https://www.cnblogs.com/pengdt/p/13266712.html