Vue杂记
大体框架
- template html部分
- script js部分
- style css部分
compoents的含义
- 很多view公共使用的部分
view的含义
- 不同的页面
小问题
html部分
表单的placeholder
在没输入文字的时候做输入提醒
元素的绑定
- v-model 来绑定setup中创建的变量
JS部分
export && export default
export 的作用是输出当前模块,使之可以被其他模块 import 使用
export 和export default 的区别在于:export 可以导出多个命名模块,例如:
//demo1.js
export const str = 'hello world'
export function f(a){
return a+1
}
123456
对应的引入方式:
//demo2.js
import { str, f } from 'demo1'
12
export default 只能导出一个默认模块,这个模块可以匿名,例如:
//demo1.js
export default {
a: 'hello',
b: 'world'
}
12345
对应的引入方式:
//demo2.js
import obj from 'demo1'
导航栏对应页面高亮
<template>
<router-link :class="route_name == 'pro_info' ? 'nav-link active' : 'nav-link'" :to="{name:'pro_info'}">
</template>
import { useRoute } from 'vue-router'
import { computed } from 'vue'
export default {
setup() {
const route = useRoute();
let route_name = computed(() => route.name)
return {
route_name,
}
}
全局变量存储
操作由js文件进行 存在store文件夹下
注意!
在编写完自己的js以后一定要将它添加到mian.js中,不然组件无法调用
import { createStore } from 'vuex'
import ModuleUser from './user'
export default createStore({
state: {
},
getters: {
},
mutations: {
},
actions: {
},
modules: {
user: ModuleUser,
}
})
- user.js
//样例
import $ from 'jquery'
export default{
state: {
id: '',
username: '',
photo: '',
token: '',
is_login: false
},
getters: {
},
//同步函数放这边
mutations: {
updateUser(state, user){
state.id = user.id;
state.username = user.username;
state.photo = user.photo;
state.is_login = user.is_login;
},
updateToken(state,token){
state.token = token;
},
logout(state){
state.id = '';
state.username = '';
state.photo = '';
state.is_login = false;
state.token = '';
}
},
//异步函数放这里
actions: {
//context 使得可以使用上下文的属性和方法
login(context, data){
$.ajax({
url: 'http://localhost:3000/user/account/login',
type: 'post',
data: {
username: data.username,
password: data.password
},
success(resp){
if(resp.error_massage === "success"){
//调用样例
context.commit("updateToken",resp.token);
data.success(resp);
}else{
data.error(resp);
}
},
error(resp){
data.error(resp);
}
})
},
getInfo(context,data){
$.ajax({
url: 'http://localhost:3000/user/account/info',
type:'get',
header: {
Authorization: 'Bearer ' + context.state.token
},
success(resp){
if(resp.error === "success"){
context.commit("updateUser",{
...resp, //解析后传入
is_login: true
});
data.success(resp);
}else{
data.error(resp);
}
},
error(resp){
data.error(resp);
}
})
},
logout(context){
context.commit("logout")
}
},
modules: {
}
}
全局变量调用
- 使用useStore
- 例子 UserAccountLoginView.vue
<template>
<ContentField>
<div class="row justify-content-md-center">
<div class="col-3">
<form @submit.prevent="login">
<div class="mb-3">
<label for="username" class="form-label">用户名</label>
<input v-model="username" type="text" class="form-control" id="username" placeholder="请输入用户名">
</div>
<div class="mb-3">
<label for="password" class="form-label">密码</label>
<input v-model="password" type="text" class="form-control" id="password" placeholder="请输入密码">
</div>
<div class="error_message">{{error_message}}</div>
<button type="submit" class="btn btn-primary">提交</button>
</form>
</div>
</div>
<div class="组件中调用全局变量">{{$store.state.user.is_login}}</div>
</ContentField>
</template>
<script>
import ContentField from '@/components/ContentField.vue';
import { useStore } from 'vuex'
import { ref } from 'vue'
import router from '@/router/index';
export default {
components: { ContentField },
setup() {
const store = useStore();
let username = ref('');
let password = ref('');
let error_message = ref('');
const login = () => {
store.dispatch("login", {
username: username.value,
password: password.value,
success() {
store.dispatch("getInfo", {
success() {
router.push({ name: 'home' });
// ?
console.log(store.state.user)
}
})
},
error() {
error_message.value = "用户名或密码错误"
}
})
}
return {
username,
password,
error_message,
login
}
}
}
</script>
<style scoped>
button {
width: 100%
}
div.error_message {
color: red;
}
</style>
router 链接带上参数、请求前操作
import { createRouter, createWebHistory } from 'vue-router'
import NotFound from '../views/error/NotFound.vue'
import PkIndexView from '../views/pk/PkIndexView.vue'
import RankListIndexView from '../views/ranklist/RankListIndexView.vue'
import RecordIndexView from '../views/record/RecordIndexView.vue'
import UserBotIndexView from '../views/user/bot/UserBotIndexView.vue'
import UserAccountLoginView from '../views/user/account/UserAccountLoginView.vue'
import UserAccountRegisterView from '../views/user/account/UserAccountRegister.vue'
import store from '@/store/index'
const routes = [
{
path: '/',
name: 'home',
redirect: '/pk/',
//自定义额外参数储存空间,meta是自己起的名字
meta: {
//带上的额外参数,也是自己起的名称
requestAuth: true,
}
},
{
path: '/pk/',
name: 'pk_index',
component: PkIndexView,
meta: {
requestAuth: true,
}
},
{
path: '/ranklist/',
name: 'ranklist_index',
component: RankListIndexView,
meta: {
requestAuth: true,
}
},
{
path: '/record/',
name: 'record_index',
component: RecordIndexView,
meta: {
requestAuth: true,
}
},
{
path: '/404/',
name: '404',
component: NotFound,
meta: {
requestAuth: false,
}
},
{
path: '/user/bot/',
name: 'user_bot_index',
component: UserBotIndexView,
meta: {
requestAuth: true,
}
},
{
path: '/user/account/login/',
name: 'user_account_login',
component: UserAccountLoginView,
meta: {
requestAuthL: true
}
},
{
path: '/user/account/register/',
name: 'user_account_register',
component: UserAccountRegisterView,
meta: {
requestAuthL: true
}
}
]
const router = createRouter({
history: createWebHistory(),
routes
})
//访问之前执行操作,to是去的url,from是来的,next是规定的下一步操作
router.beforeEach((to, from, next) => {
let flag = 1;
const jwt_token = localStorage.getItem("jwt_token");
if (jwt_token) {
store.commit("updateToken", jwt_token);
store.dispatch("getInfo", {
success() {
},
error() {
alert("token无效,请重新登录!");
router.push({ name: 'userLogin' });
}
})
} else {
flag = 2;
}
if (to.meta.requestAuth && !store.state.user.is_login) {
if (flag === 1) {
next();
} else {
alert("请先进行登录!");
next({name: "userLogin"});
}
} else {
next();
}
})
export default router
引入有无大括号{}的区别
- 对于 export default{} 的对象,引入不需要 {}
- 对于 export{} 的对象,引入需要加 {} ,因为有多个对象可以调用
登陆持久化 --- 保存数据到本地
localStorage.setItem("jwt_token", resp.token);
//key = jwt_token, value = resp,token
//此条语句放在login执行成功之后设置
//logout 的时候就 removeItem
CSS部分
style scoped
- 封闭样式作用范围,使得css不会影响组件外的部分
边距规定
//上边距规定
div.对应div名称{
margin-top: 20px;
}
//居中处理
div.aaa{
margin: 40px auto; //40px与上边距的距离、其他部分居中
}
//居中处理2
div.bbb{
display: flex;
justify-content: center; //水平居中
align-items: center; //竖直居中
}
宽高的规定
div.aa{
width: 20vw;
height: 30vh;
}
其他部分
关于资源路径访问
./
访问当前目录
../
访问父目录
/
访问根目录
@/
@ == src目录
非法路径处理
访问根路径重定向
{
path: "/",
name: "home",
redirect: "/pk/"
}
访问不存在路径重定向
{
path: "/:catchAll(.*)/",
redirect: "/404"
}
导航栏切换 页面不刷新
- 将原来的导航
tmp1
换成 router-linktmp2
<!--tmp1-->
<a class="之前的class" href="之前的url">King Of Bots</a>
<!--tmp2-->
<router-link class="之前的class" :to="{name:'之前的url对应名字'}">King Of Bots</router-link>
导航栏切换 active设置
- setup() 函数设置获取route_name
import { useRoute } from 'vue-router'
import { computed } from 'vue'
export default {
setup(){
const route = useRoute();
let route_name = computed(() => route.name)
return{
route_name
}
}
}
- 判断当前路径
<router-link :class="route_name == 'pk_index' ? 'nav-link active' : 'nav-link'" :to="{name:'pk_index'}">对战</router-link>
card组件将内容放至指定区域
- 想要展示的内容会被自动渲染填充到
<slot/>
标签里面
// div.container>div.card>div.card-body + tap 自动补全
去掉导航栏中的 #
import { createRouter, createWebHashHistory } from 'vue-router'
改成
import { createRouter, createWebHistory } from 'vue-router'
向url发送请求
非常好用!
import $ from 'jquery'
setup(){
$.ajax({
url: "...",
type: "post",
headers: {
},
data: {
a: ' ',
b: ' '
},
success(resp){
console.log(resp.data)
},
error(resp){
console.log(resp.data)
}
})
}
BootStrap 小技巧
grid system
布局系统,专门拿来做样式规定,一行分成十二格
- 居中 justify-content-md-center
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具