main.js
Vue2
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
Vue.config.productionTip = false
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
Vue3
createApp : 返回值:一个提供应用上下文的实例 实例挂载的组件树,共享同一个上下文- 可以在
createApp 之后链式调用其它方法
import {
createApp
} from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
createApp(App).use(store).use(router).mount('#app')
store 文件
Vue2
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {},
mutations: {},
actions: {},
modules: {}
})
Vue3
import {
createStore
} from 'vuex'
export default createStore({
state: {},
mutations: {},
actions: {},
modules: {}
})
Vuex 的使用
import {
createStore
} from 'vuex'
export default createStore({
state: {
name: "superman",
arr: [1, 2, 3]
},
mutations: {
muModify(state, val) {
console.log("commit muModify", val)
state.name += val
}
},
actions: {
acModify(context, val) {
console.log("dispatch acModify", val)
context.commit("muModify", val)
}
},
getters: {
getArr(state) {
return state.arr.map(item => item * 2)
}
},
modules: {}
})
- Vue3 中需要通过
useStore 方法使用 vuex
<template>
<p>普通使用:</p>
<p>$store.state.name: {{ $store.state.name }}</p>
<p>$store.state.arr: {{ $store.state.arr }}</p>
<p>$store.getters.getArr: {{ $store.getters.getArr }}</p>
<hr />
<p>Vue 3:</p>
<p>name: {{ name }}</p>
<p>arr: {{ arr }}</p>
<p>getArr: {{ getArr }}</p>
<hr />
<button @click="coModify">coModify name</button> |
<button @click="diModify">diModify name</button>
</template>
<script>
import { useStore } from "vuex";
export default {
name: "App",
setup() {
// 通过 useStore 使用 Vuex
const store = useStore();
// 获取数据
let name = store.state.name;
let arr = store.state.arr;
let getArr = store.getters.getArr;
// 调用 dispatch 方法
function diModify() {
store.dispatch("acModify", "(Actions)");
}
// 调用 commit 方法
function coModify() {
store.commit("muModify", "(Mutations)");
}
return { name, arr, getArr, coModify, diModify };
},
};
</script>
- 但是,通过该方法获取的数据不是响应式的
- 响应式数据设置如下:需要配合
computed 方法使用
let name = computed(() => store.state.name);
let arr = computed(() => store.state.arr);
let getArr = computed(() => store.getters.getArr);
router 文件
Vue2
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'
Vue.use(VueRouter)
const routes = [{
path: '/',
name: 'Home',
component: Home
},
{
path: '/about',
name: 'About',
component: () => import('../views/About.vue')
}
]
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})
export default router
Vue3
import {
createRouter,
createWebHistory
} from 'vue-router'
import Home from '../views/Home.vue'
const routes = [{
path: '/',
name: 'Home',
component: Home
},
{
path: '/about',
name: 'About',
component: () => import('../views/About.vue')
}
]
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes
})
export default router
vue-router 的使用
import {
createRouter,
createWebHistory
} from 'vue-router'
import Home from '../views/Home.vue'
const routes = [{
path: '/',
name: 'Home',
component: Home
},
{
path: '/about',
name: 'About',
component: () => import('../views/About.vue')
}
]
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes
})
export default router
- Vue3 中需要通过
useRoute 方法使用 vue-router
<template>
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>
<router-view />
</template>
<script>
export default {
name: "App",
};
</script>
<template>
<h1>About</h1>
</template>
<script>
import {
onBeforeRouteLeave,
onBeforeRouteUpdate,
useRoute,
useRouter,
} from "vue-router";
export default {
name: "About",
setup() {
// 当前路由对象
let route = useRoute();
console.log("route", route);
// 总路由对象
let router = useRouter(router);
console.log("router", router);
// 路由守卫
onBeforeRouteLeave(() => {
console.log("onBeforeRouteLeave:离开路由时触发");
});
onBeforeRouteUpdate(() => {
console.log("onBeforeRouteUpdate:复用路由时触发");
});
return {};
},
};
</script>
<template>
<h1>Home</h1>
</template>
<script>
export default {
name: "Home",
};
</script>
config
globalProperties
- 添加一个可以在任何组件中访问的全局 property
- 组件的 property 在命名冲突时具有优先权
import {
createApp
} from 'vue'
import App from './App.vue'
const app = createApp(App)
app.config.globalProperties.$myData = "superman"
app.mount('#app')
<template>
<h1>App</h1>
</template>
<script>
export default {
name: "App",
mounted() {
console.log(this.$myData); // superman
},
};
</script>
自定义指令
- 格式:
app.directive("自定义指令名", 配置对象)
import {
createApp
} from 'vue'
import App from './App.vue'
const app = createApp(App)
app.directive('myIns', {
created() {},
beforeMount() {},
mounted() {},
beforeUpdate() {},
updated() {},
beforeUnmount() {},
unmounted() {}
});
app.mount('#app')
钩子函数接收 2 个参数:
el :指令绑定到的元素,可用于直接操作 DOM。eg:el.focus() binding :包含以下 property 的对象
instance :使用指令的组件实例value :传递给指令的值oldValue :先前的值,仅在 beforeUpdate 和 updated 中可用。无论值是否有更改都可用arg :传递给指令的参数(如果有的话) eg:v-my-directive:foo 中,arg 为 "foo" 。modifiers :修饰符对象(如果有的话) eg:v-my-directive.foo.bar 中,修饰符对象为 {foo: true,bar: true} dir :配置对象本身
fragment
- Vue3 可以没有根标签,因为会默认添加根标签
<fragment>
<template>
<h1>App</h1>
<p>superman</p>
</template>
<script>
export default {
name: "App",
};
</script>
Teleport
- 用于将组件的 HTML 结构移动到指定位置
- 需设置
to 属性,属性值为 选择器 ,以指定移动到的位置
<template>
<div class="box">
<h1>App</h1>
<button @click="bol = !bol">显示 / 隐藏</button>
<About v-if="bol" />
</div>
</template>
<script>
import { ref } from "@vue/reactivity";
import About from "./views/About.vue";
export default {
name: "App",
components: { About },
setup() {
let bol = ref(false);
return { bol };
},
};
</script>
<style>
.box {
width: 200px;
height: 200px;
background: palevioletred;
position: relative;
}
</style>
<template>
<!-- 这里的内容默认显示在 .box 下面 -->
<h2>About</h2>
<!-- 设置了 Teleport 的内容会被移到 #app 下面 -->
<Teleport to="#app">
<h2>Teleport About</h2>
</Teleport>
</template>
<script>
export default {
name: "About",
};
</script>
<style>
h2 {
width: 100%;
height: 100%;
position: absolute;
background: palegoldenrod;
left: 50%;
top: 0;
}
</style>
keep-alive
- 组件在需要使用时,会被创建;使用完后,会被销毁
- 我们可以使用 keep-alive 标签,以缓存组件,使其不会被销毁
<template>
<button @click="change">点击切换</button>
<!-- 使用组件缓存标签,使其不会被销毁 -->
<keep-alive> <About v-if="bol" /> </keep-alive>
</template>
<script>
import { ref } from "@vue/reactivity"
import About from "./views/About.vue"
export default {
name: "App",
components: {
About,
},
setup() {
let bol = ref(true);
function change() {
bol.value = !bol.value;
}
return { bol, change };
},
};
</script>
<template>
<h1>{{ msg }}</h1>
<button @click="msg += '!'">更新数据</button>
</template>
<script>
import {
onBeforeMount,
onMounted,
onBeforeUpdate,
onUpdated,
onBeforeUnmount,
onUnmounted,
ref,
} from "@vue/runtime-core";
export default {
name: "About",
setup() {
let msg = ref("About");
onBeforeMount(() => {
console.log("onBeforeMount:挂载之前");
});
onMounted(() => {
console.log("onMounted:挂载之后");
});
onBeforeUpdate(() => {
console.log("onBeforeUpdate:更新之前");
});
onUpdated(() => {
console.log("onUpdated:更新之后");
});
// 此时,即使不使用组件,组件也不会被销毁
onBeforeUnmount(() => {
console.log("onBeforeUnmount:销毁之前");
});
onUnmounted(() => {
console.log("onUnmounted:销毁之后");
});
return { msg };
},
};
</script>
缓存组件的钩子函数
- 钩子函数:activated、deactivated
- setup 中的钩子函数:onActivated、onDeactivated
- 钩子函数可以一起使用
- setup 中的钩子函数会先执行
<template>
<h1>About</h1>
</template>
<script>
import { onActivated, onDeactivated } from "@vue/runtime-core";
export default {
name: "About",
setup() {
onActivated(() => {
console.log("onActivated:激活缓存组件");
});
onDeactivated(() => {
console.log("onDeactivated:离开缓存组件");
});
},
activated() {
console.log("activated:激活缓存组件");
},
deactivated() {
console.log("deactivated:离开缓存组件");
},
};
</script>
CSS 方法
v-bind 方法
<template>
<p class="list">APP 组件</p>
<button @click="change">修改</button>
</template>
<script>
import { ref } from "vue";
export default {
name: "App",
setup() {
let color = ref("pink");
function change() {
color.value = "skyblue";
}
return {
color,
change,
};
},
};
</script>
<style>
.list {
/* 使用 v-bind 方法 */
background: v-bind(color);
}
</style>
CSS选择器:deep(子级CSS选择器)
.father:deep(.son) {
background: pink;
}
:global(CSS选择器)
- 用于设置全局样式,下例的
redFont 可以作用于所有组件中
:global(.redFont) {
color: brown;
}
|