一、创建文件
名字要使用驼峰命名法、后缀要使用vue 比如 VueObj.vue
<template>
<div>
这里写内容 //内容写在这里
</div>
</template>
<style lang="scss"></style> //这里面写css样式 可以用scss格式写
<script>
export default {
data() {
return {} //vue的配置
},
}
</script>
二、去router引入组件
const routes = [
{
path: "/tabobj", //访问地址
name: "tabobj",
component: () => import("../views/TabObj.vue"), //创建的文件地址
},
]
三、想使用插件
首先在components 创建一个vue文件
在需要的地方引入插件
import TabBle from '../components/TabBle.vue' //第一步
export default {
data() {
return {
arr: {}
}
},
components: { //第二步
TabBle //你写的名字
}
}
父传子传参
<TabBle :arr="arr"></TabBle>
接受传参
<script>
export default {
data() {
return {}
},
props: ['arr'] //直接接受传参 这个是默认 第一种
props:{
arr{
type:'Number' //传过来的数据必须是数值类型
required:true,//默认这个arr的数据必须要传
default:8888 //制定默认值 如果父组件没有传参 使用这个默认真 数值可以这个
default:function(){ //如果默认值给对象的情况
return {message:'hellow'}
}
}
}
}
</script>
4、将变成全局使用
4.1首先找到main.js 里面加
import BeiEr from "./components/BeiEr.vue";
Vue.component("BeiEr", BeiEr);
然后直接用标签使用就可以
5、子传父传参
//第一步 点击传参
<button @click="btnFun()">发布</button> //先写个点击事件
第二步
methods: {
btnFun() {
let obj = {
names: this.names,
content: this.content,
timer: this.timer
}
this.arr.push(obj)
this.$emit('shuju', this.arr) //这里传参 this.$emit
}
}
//第三步在父亲里面接受传参
<BeiEr @shuju="shuju"></BeiEr> //这里不要写() 可能传过来的不止一个参数
methods: {
shuju(arr) { //arr就是穿过来的参数
this.arr = arr
console.log(this.arr, 111);
},
}
6、插槽的介绍
插槽分三种 默认插槽、具名插槽、作用域插槽。
默认插槽、具名插槽、是父传子。
作用域插槽是子传父
7、插槽的使用
7.1默认插槽 父传子
在父里面写 <ChaCao>我是默认插槽<ChaCao>
在子里面写 <slot></slot> 写几个接收几个
7.2具名插槽 父传子
在父里面写
<MianSan>
<template v-slot:neirong> //这里传的名字
<div>我是内容管理</div> //这里是传的内容
</template>
</MianSan>
在子里面写
<slot name="neirong"></slot>
7.3作用域插槽 子传父在子里面传参
<template>
<div>
<slot :arr="arr"></slot> //传入数据arr
</div>
</template>
<script>
export default {
data() {
return {
arr: ['作用域插槽1', '作用域插槽2', '作用域插槽3', '作用域插槽4', '作用域插槽5', '作用域插槽6']
}
}
}
</script>
在父里面接受传参
<YouMian>
<template scope="a">
<div> //a 就是接受的数据
<ul>
<p v-for="(item, index) in a.arr" :key="index">
{{ item }}
</p>
</ul>
</div>
</template>
</YouMian>
八、大生命周期函数
Vue 的生命周期总共分为8个阶段:创建前、后,载入前、后,更新前、后,销毁前、后。
1、beforeCreate(创建前)
在beforeCreate函数执行时候,data和methods中的数据都还没有初始 此时还不能访问
2、created(创建后)
在created中 data和methods已经初始化完毕,可以访问
3、beforeMount maote(挂载前)
此函数执行时,模板已经在内存中编译好了,但是还未挂载到页面去,此时页面还是旧的
4、mounted maoteite(挂载后)
只要执行了mounted,就表示整个vue已经初始化完毕了 dom元素也已经加载完毕
5、beforeUpdate(更新前)
当页面变化时,会触发beforeUpdate方法 。data 数据尚未和最新的数据保持同步。
6、updated(更新后)
当 data 变化时,会触发 updated 方法。页面和 data 数据已经保持同步了。
7、beforeDestroy di si zhuo a (销毁前)
组件销毁之前调用 ,在这一步,data和methods还能访问。
8、destroyed di si zhuo a te(销毁后)
组件销毁之后调用,此时已经不能访问data和methods
九、在Vue中,可以使用以下指令和钩子函数来实现动画效果:
//标签里面的name名字 可以说就是类
//使用插件
require('animate.css') 单独引入
<transition name="abc"
enter-active-class="animate__animated animate__zoomIn"
leave-active-class="animate__animated animate__zoomOut"
>
<div v-show="show" class="bianhua">123</div>
</transition>
.abc-enter:元素进入动画的开始状态。
.abc-enter-active:元素进入动画的过渡状态。
.abc-enter-to:元素进入动画的结束状态。
.abc-leave:元素离开动画的开始状态。
.abc-leave-active:元素离开动画的过渡状态。
.abc-leave-to:元素离开动画的结束状态。
/如果使用插件 请在main.js写入这段代码
import animate from "animate.css";
Vue.use(animate);
十、单独的事件监听
watch: {
usdPrice: function (o, i) {
console.log(o, i); // o是现在 i是以前
this.rmbPrice = +o * 6.8759
}
obj:{
deep:true,//true为进行深度监听,false为不进行深度监听
handler(newVal){
console.log(newVal);
} }
},
十一、vue打包
在vue.config.js
const { defineConfig } = require("@vue/cli-service");
module.exports = defineConfig({
publicPath: "./", //添加一个这个属性
transpileDependencies: true,
});
然后cmd 发送npm run build 这个
文件里面会出现一个dist的文件夹
十二、vue路由
1.基本路由
router-link 的四个属性
1.1 to=“/about” 跳转页面那个页面
1.2 tag="li" router-link默认是a标签 可以用tag属性把他变成li或者div
1.3 active-class="aaa' 这个a标签是类名 可以设置激活链接时的状态 就是点击时候
1.4 event(声明可以用来触发导航的事件 )
默认router是自定义标签 没有点击事件 可以用 @click.native来触发原生事件
<router-link to="/about">Home</router-link>
router-view 这个标签你写在那 内容就显示到哪
<router-view />
2.嵌套路由
{
path: "/about",
name: "about",
component: () =>
import(/* webpackChunkName: "about" */ "../views/AboutView.vue"),
children:[ //这里面写 可以嵌套很多子元素
{
path: "/houtai/yulan",
name: "yulan",
component: () => import("../views/YuLan.vue"),
},
]
},
3.路由懒加载
懒加载的写法
{
path: "/about",
name: "about",
component: () =>
import(/* webpackChunkName: "about" */ "../views/AboutView.vue"),
},
非懒加载的写法
import HomeView from "../views/HomeView.vue"; 这里每进来一次都要写一次
{
path: "/home",
name: "home",
component: HomeView
},
4.编程式路由(跳转页面)
this.$router.push({path:'/about'})
或者
this.$router.replace({path:'/about'})
或者用name跳转
this.$router.push('about')
5.路由的重定向
{
path: "/about",
name: "about",
redirect:'/about/one' //访问about 直接显示 about下面的one页面
component: () =>
import(/* webpackChunkName: "about" */ "../views/AboutView.vue"),
},
6.路由的其他配置
const router = new VueRouter({
mode: "history", //写这个 网址上面的#就没有了 但是要和后端沟通
routes,
});
7.路由的传参
7.1path传参
1.router里面的index.js 写:id
{
path: "/houtai/shili/:id", //这里写个:id
name: "shili",
component: () => import("../views/ShiLi.vue"),
},
2.然后再houtai找到 router-link 跳转标签 to后面加上要传的参数
2.1 <router-link active-class="aaa" to="/houtai/shili/888"> 直接传参
2.2 <router-link active-class="aaa" :to="{ path: '/houtai/shili/999' }"> to前面加:变成动态传参
2.3 <router-link active-class="aaa" :to="{ name: 'shili', params: { id: 666 } }"> 通过name传参
3.再找到shili文件里面里面使用
this.route.params.id 接受 {{this.route.params.id }}
6.2query传参
1.router里面的index.js 写
{
path: "/houtai/shili/",
name: "shili",
component: () => import("../views/ShiLi.vue"),
props: true, //加这个配置项 加不加都实现 按道理要加上
},
2.然后再找到 router-link 跳转标签 to后面加上要传的参数
<router-link active-class="aaa" :to="{ path: '/houtai/shili', query: {name:'张三',sex:18}}">
3.再找到shili文件里面里面使用(点击跳转的页面)
{{ this.$route.query }}
或者直接拿值
{{ this.$route.query.name }}
7.vue路由守卫
在router里面的index.js里面写
7.1全局前置守卫
router.beforeEach((to, from, next) => {
//to 去的新地址
//from 旧地址
next()//通道 开走
if (to.name == "denglu") {
next();
} else {
let isDengLu = localStorage.getItem("isDengLu");
isDengLu = JSON.parse(isDengLu);
if (isDengLu == null || isDengLu == "") {
next("/");
} else {
next();
}
}
});
7.2后置守卫
router.afterEach((to, from) => {
console.log(to);
console.log(from);
});
7.3路由独享的守卫
//写道单独 path文件里面
{
path: "/houtai/shili",
name: "shili",
component: () => import("../views/ShiLi.vue"),
props: true,
beforeEnter: (to, from, next) => {
let isDengLu = localStorage.getItem("isDengLu");
isDengLu = JSON.parse(isDengLu);
if (isDengLu.username == "admisn") {
next();
} else {
alert("此账号不能进入");
next(from.path);
}
},
},
十三、VueX的使用
1.在store~index里面写
export default new Vuex.Store({
state(斯得特): { //
num: 100, //购物车总和加的就是这个值
},
getters(盖特斯): { //相当于是计算属性
getNum(state) {
return state.num + 100; //调用一下加100 但是总体不变
},
},
mutations(美腿神思): { //不能直接提交 要委婉一点
add(state, n) {
state.num = state.num + n;
},
},
actions(啊可深思): { //使用 context.commit("add", n); 然后再调用mutations add方法 这样中转一下 这样有数据记录 不容易丢失
addbtn(context, n) {
context.commit("add", n);
},
},
modules(毛豆斯): {},
});
2.使用属性
{{this.$store.statae.num }} //复杂写法调用
1.首先引入mapState
import { mapState} from 'vuex';
1.然后再计算属性里面写
computed: {
...mapState({
num: state => state.a.num,
}),
}
3.简化写法
{{num}}
3.调用this.$store.commit('add', 100) //通过commit 来修改这个值 然后去(store~index 里面mutations写add事件)
<button @click="jiaFun()">加</button>
jiaFun() {
this.$store.commit('add', 100)
}
这样写也可以实现 但是记录不了vuex的行动日志 怎么看下一步
4.但是不能这么直接 应该 (store~index 里面actions写addbtn事件)
<button @click="jiaFun()">加</button>
jiaFun() {
this.$store.dispatch('addbtn', 1000)
}
十四、vue axios使用(vue中的ajax)
1:引入axios
cnpm install --save axios
2.如果单个文件使用 引入
import axios from 'axios'
全局引入
import axios from "axios";
Vue.prototype.$axios = axios;
全局引入后 使用要用this.$axios({})
14.2怎么请求?
get请求
单个文件夹 axios.get({})
全局引入
this.$axios.get('http://47.94.4.201/index.php/index/index/getcode').then(res => {
if (res.data.code == 0) {
this.textyzm = res.data.msg
}
})
post请求
this.$axios({
method: 'post',
url: 'http://47.94.4.201/index.php/index/index/login',
params: {
name: this.username,
pwd: this.pwd,
vercode: this.yanzheng,
},
}).then((res) => {
console.log(res)
}
14.3axios封装
//现在scr里面 创建一个api再再api里面创建一个api.js
import axios from "axios";
axios.defaults.baseURL = "https://zzgoodqc.cn"; //全局配置ip地址 写个这别的就不要在写了
axios.defaults.timeout = 30000;//超过30s报错
//添加响应拦截器
axios.interceptors.response.use(function (response) {
//可以写if判断,提前拦截错误信息
return response;
}, function (err) {
return Promise.reject(err);
});
//post封装
export function apiPost(url, params){
return new Promise((resolve, reject) => {
axios({
method: 'post',
url:url,
data:params
}).then(res => {
resolve(res.data);
}).catch(err =>{reject(err.data)})
});
}
//get 封装
export function apiGet(url, params){
return new Promise((resolve, reject) =>{
axios.get(url, {
params: params,
headers:{"token":sessionStorage.getItem('token')}
}).then(res => {
resolve(res.data);
}).catch(err =>{
reject(err.data)
})
});
}
14.4axios二次封装 有些需要多次使用 可以选择二次封装
//在api文件夹里面创建个http.js
import { apiGet } from "./api";
export function getCode() {
return new Promise((resolve, reject) => {
apiGet("https://zzgoodqc.cn/index.php/index/index/getcode")
.then((res) => {
resolve(res);
})
.catch((err) => {
reject(err);
});
});
}
//如果要使用 请在要使用的文件里面写
import { getCode} from '../api/http'
直接getCode().then(res=>{})
再在main.js引入
//引入封装的api
import { apiPost, apiGet } from "./api/api";
Vue.prototype.$apiPost = apiPost;
Vue.prototype.$apiGet = apiGet;
使用方法
this.$apiGet(url)
this.$apiPost(url,params)
14.5vue同步和异步怎么使用
async created() {
let a = await getSar() 这个先执行 这个执行完才能执行下一个
console.log(a);
getCode().then(res => {
console.log(res);
})
}
14.5遇见跨外网应该怎么办
this.$apiGet('https://www.baidu.com/s?wd=666').then(res=>{ console.log(res) })
会报错
那要怎么解决呢
首先在vue.config.js里面
const { defineConfig } = require("@vue/cli-service"); module.exports = defineConfig({ publicPath: "./", transpileDependencies: true, //添加以下代码 devServer: { proxy: { "/api": { target: "http://www.baidu.com/", ws: true, changeOrigin: true, pathRewrite: { "^/api": "" }, }, }, }, });
使用的时候呢用
地址哪里替换成api 骗过浏览器 this.$apiGet('/api/s?wd=22').then(res => { console.log(res); })
这个只能保证本地没问题 打包过后还是不行
线上不行就找后端