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-link tmp2
<!--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
posted @ 2022-09-14 17:05  Xuuxxi  阅读(11)  评论(0编辑  收藏  举报