混入mixin
在Vue中,混入(mixin)是一种可以在多个组件中重复使用的对象。它允许您将组件中的一些选项提取出来,然后在多个组件中进行重复使用。混入可以包含组件中的任何选项,例如数据、计算属性、方法等。
使用步骤
- 在src文件夹下新建一个文件夹,比如
mixin
,然后再这个文件夹下面新建一个脚本,比如index.js
。 - 使用混入必须要导出,export default,在导出的对象内部写上需要的方法以及data属性等。
- 局部使用:
- 再自己的.vue中,导入
- import hunru from "@/mixin"
- 自己的组件中,写上mixin:[hunru]
- 再自己的.vue中,导入
- 全局使用:
- 在main.js中:
- import hunru from "@/mixin"
- Vue.mixnin(hunru)
- 就可以了,可以写多个:需要写多个,然后导入多个。
- import hunru2 from "@/mixin"
- Vue.mixin(hunru2)
- 在main.js中:
案例
- 引用的组件一定要要有自定义混入的属性或者方法,如果没有则会报错。
- 如果组件有自己的属性以及方法,会优先使用自己的,没有再使用混入的。
局部使用
全局使用
// 1. 导入
import hunru from "@/mixin"
// 2. 使用
Vue.mixin(hunru)
// 这样局部就不用导入和引入了
自定义插件
使用别人写好的插件
- 在main.js中导入。
- Vue.use()
# 1 写plugins/index.js
import Vue from "vue";
import axios from "axios";
import hunru from "@/mixin";
export default {
install(a,name) {
console.log('----------',name)
// 1 定义全局变量,放到原型中
// prototype 原型链,一般定义在原型中的变量,都用 $ 开头,防止污染---》对象中可以定义同名属性,冲突
Vue.prototype.$axios = axios
// Vue.prototype.$BASE_URL='http://127.0.0.1:8000/'
// 2 定义指令 自定义指令
//定义全局指令:跟v-bind一样,获取焦点
Vue.directive("fbind", {
//指令与元素成功绑定时(一上来)
bind(element, binding) {
element.value = binding.value;
},
//指令所在元素被插入页面时
inserted(element, binding) {
element.focus();
},
//指令所在的模板被重新解析时
update(element, binding) {
element.value = binding.value;
},
});
// 3 使用混入
Vue.mixin(hunru)
// 4 定义全局组件--》elementui
}
}
// 3 在main.js中使用,可以传参数
// 1 使用自定义插件
import my from '@/plugins'
Vue.use(my,'小满') // 内部本质会执行install
// 咱们需要掌握的;
-有些第三方插件,用了以后,增强了vue功能
-this.$router
-全局组件 :el-button
-this.$message--->
-this.$http.get
插件之赋值
使用步骤
-
在src下面新建一个文件夹,比如plugins
-
在这个文件夹下面新建一个脚本文件,比如index.js
-
必须导出,并且内部有一个install对应一个对象,所有代码写在install中。
// 一个非常简单的插件 // 这样项目运行, 都会在控制台打印 export default { install: function (xm){ // 这个xm是什么 就是view的实例对象 console.log("小满最棒啦") console.log(xm) } }
-
在main.js中导入,import xx from "@/plugins",然后使用Vue.use(my) ,这句话内部本质就会执行install
可以被赋值,根据这个属性,可以把一些第三方的包,比如axios提前写入到插件里面,然后所有视图都可以使用了。
通过赋值axios,然后发送请求
为什么名称前面有一个$
防止和视图内部的变量名起冲突,一般定义在原型中的变量都使用$开头。
插件之自定义指令(了解即可)
写上自定义指令之后全局都可以使用我们自定义的指令。
https://juejin.cn/post/7114267523415015455
自定义插件之混入
和之前一样,先定义一个混入。
导入的时候,不需要在main.js里面导入了,直接通过自定义插件去导入。
// 自定义插件
import Vue from 'vue'
import hunru from "@/mixin"
export default {
install: function (xm){
Vue.mixin(hunru)
}
}
插槽
<!--
子组件
src/components/MySlot.vue
-->
<template class="my-slot">
<div>
<h3>小满三岁啦</h3>
<slot></slot>
<p>{{message}}</p>
</div>
</template>
<!--
父组件
src/views/HomeView.vue
-->
<template>
<div class="home">
<MySlot>
<!-- @代表的就是src路径 -->
<img src="@/assets/logo.png" alt="">
</MySlot>
</template>
<script>
import MySlot from "@/components/MySlot.vue"
export default {
name: "HomeView",
components: {
MySlot
}
}
</script>
本地存储 cookie/sessionStorage/localStorage
前提是登录成功。
存储类型 | 说明 | 其他 |
---|---|---|
cookie | 登录信息放这里,有过期时间,一旦过期就没有了 | 需要下载第三方模块vue-cookies ,cnpm install vue-cookies -S,记得main.js注册 |
sessionStorage | 当前浏览器生效,浏览器一旦关闭,数据就没有了 | |
localStorage | 永久生效,除非删除代码或者清空浏览器缓存 | 案例:未登录,加入购物车 |
// localStorage
// 存 setItem 取 getItem 删 removeItem clear()
// sessionStorage
// 存 setItem 取 getItem 删 removeItem clear()
// cookies
// 需要下载第三方模块 npm install vue-cookies -S
this.$cookies.set("name", "小满", "1d") // 存 -->1d 1天 2h 2小时
this.$cookies.get("name") //取
this.$cookies.remove("name")// 删
vue-cookies的第三个参数
vue-cookies
插件中设置 Cookie 的第三个参数是过期时间,可以使用以下单位:
'1s'
: 1 秒'1m'
: 1 分钟'1h'
: 1 小时'1d'
: 1 天'1y'
: 1 年
你可以根据需要选择合适的单位,例如:
this.$cookies.set("name", "xm", "1h"); // 表示1小时过期
这样就会在 1 小时后过期。
如何使用
<!--视图层-->
<template>
<div class="home">
<h3>localStorage 案例演示</h3>
<button class="btn btn-outline-primary" @click="handleSaveLocalStorage">存储到localStorage</button>
<button class="btn btn-outline-primary" @click="handleGetLocalStorage">从localStorage取出</button>
<button class="btn btn-outline-primary" @click="handleDeleteLocalStorage">从localStorage删除/清空</button>
<hr>
<h3>sessionStorage 案例演示</h3>
<button class="btn btn-outline-primary" @click="handleSaveSessionStorage">存储到sessionStorage</button>
<button class="btn btn-outline-primary" @click="handleGetSessionStorage">从sessionStorage取出</button>
<button class="btn btn-outline-primary" @click="handleDeleteSessionStorage">从sessionStorage删除/清空</button>
<hr>
<h3>cookieStorage 案例演示</h3>
<button class="btn btn-outline-primary" @click="handleSaveCookieStorage">存储到cookieStorage</button>
<button class="btn btn-outline-primary" @click="handleGetCookieStorage">从cookieStorage取出</button>
<button class="btn btn-outline-primary" @click="handleDeleteCookieStorage">从cookieStorage删除</button>
</div>
</template>
<script>
export default {
name: "HomeView",
methods: {
// 本地存
handleSaveLocalStorage() {
// 方式1
// 因为是在window对象里面的,所以可以直接使用 localStorage
localStorage.setItem("name", "小满")
// 方式2
let user = {
hobby: "摸鱼",
age: 3
}
localStorage.setItem("user", JSON.stringify(user)) // 这里要放字符串,不要放对象
},
// 本地取
handleGetLocalStorage() {
// 取出
let name = localStorage.getItem("name")
let user = localStorage.getItem("user")
console.log(name);
console.log(user);
},
// 本地删
handleDeleteLocalStorage() {
// 删除指定的
localStorage.removeItem("name")
// 删除全部
localStorage.clear()
},
// session存
handleSaveSessionStorage() {
// 方式1
sessionStorage.setItem("name", "大乔")
// 方式2
let user = {name:"大乔", hobby: "欺负小满"}
sessionStorage.setItem("user", JSON.stringify(user)) // 不要放对象进去
},
// session取
handleGetSessionStorage() {
let name = sessionStorage.getItem("name")
let user = sessionStorage.getItem("user")
console.log(name);
console.log(user);
},
// session删
handleDeleteSessionStorage() {
// 按指定删
sessionStorage.removeItem("name")
// 清空 删全部
sessionStorage.clear()
},
// 存cookie
handleSaveCookieStorage(){
this.$cookies.set("name", "小满", "1h") // 这里的1h 表示1小时 1d 表示1天 类推
},
// 取cookie
handleGetCookieStorage(){
let name = this.$cookies.get("name")
console.log(name);
},
// 清空全部cookie
handleDeleteCookieStorage(){
this.$cookies.remove("name") // 只能一个一个的删
},
},
}
</script>
<style>
.home {
margin: 20px;
}
.home button {
margin: 10px
}
</style>
// main.js
// 导入vue-cookies
import VueCookies from "vue-cookies"
Vue.use(VueCookies)
vuex状态管理器
- vuex在vue2中,大量使用
- vue3中,Pinia 或 vuex
- 作用:主要用来跨组件通信。
集中式状态管理-->组件有自己的数据-->放在组件中-->有了状态管理器,多个组件可以共同操作这个管理器-->实现了组件间通信-->跨组件。
如何使用
// 1. 安装 cnpm install vuex -S
// 2. 新建 store/index.js 写入代码
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
// 应用数据存储在这里面
},
getters: {
// 从state中获取数据
},
mutations: {
// 修改state中的数据
},
actions: {
// 提交muations
// 异步操作也放在这里面
},
modules: {
// modules 是 Vuex 中用于将 store 分割成模块的功能。它允许你将 store 分割成模块,每个模块拥有自己的 state、getters、mutations 和 actions。
}
})
// 3. 在main.js 导入
import store from './store'
new Vue({
store,
})
// 上面三步 默认创建好项目就已经自动弄好了,如果项目中没有再去操作上面的步骤,如果有,就直接跳过上面步骤按下面继续。
//------------------- 关注下面 -------------------- //
// 4. 在store/index.js 中写代码
// 5 在组件中使用 (拿变量)
js:this.$store.state.count
html:$store.state.count
// 6 修改变量
js中:
1 this.$store.dispatch('actions定义的函数名',参数)
2 this.$store.commit('mutations定义的函数名',参数)
3 this.$store.state.count++
所有组件中使用到的位置,都会变量
// 7 为什么经过 actions和mutations
-可以跟后端交互,可以做数据验证
// 8 getters:
可以通过getters获取数据--》对state中的数据,再做处理
// 9 modules:
分到不同模块中,不同模块有自己的state,actions
[this.]$store.state.变量名 视图中显示数据
// store/index.js
export default new Vuex.Store({
state: {
count: 0
},
// 视图
{{ this.$store.state.count }}
// 等同于
{{ $store.state.count }}
和后端交互 actions
所以可以在这里发送Ajax请求给后端
坑
actions: {
this.$store.commit("addOne", num) // 报错
}
根据您提供的代码和错误信息,问题出在您在actions
中的addCount
方法中尝试直接访问this.$store.commit
。在actions
中,您不能直接访问this.$store
,因为actions
中的方法会接收一个与store
实例具有相同方法的上下文对象。因此,您应该将commit
方法作为第二个参数传递给addCount
方法,而不是直接访问this.$store.commit
。这应该可以解决您遇到的错误。
下面是您可以尝试的修改:
actions: {
addCount({ commit }, num) {
console.log(commit); // 可以直接访问commit方法
console.log(num); // 1 是dispatch传递的参数
// 通过commit方法来触发mutations中的函数
commit("addOne", num);
}
}
通过这种方式,您应该能够正确调用commit
方法而不会再出现TypeError: Cannot read properties of undefined (reading 'commit')
的错误。希望这能帮助您解决问题!
全部代码
两个子组件
<!-- 购物车 -->
<template>
<div class="shopping-car">
<div>
<p>商品数量: {{this.$store.state.count}}</p>
</div>
</div>
</template>
<style scoped>
.shopping-car p {
text-align: right;
margin-right: 20px;
}
</style>
<!-- 商品列表 -->
<template>
<div class="good-list">
<!--
点击按钮 触发handleClick
↓
触发this.$store.dispatch("addCount", 1)
↓
是否要与后端交互,发送Ajax请求
触发mutations内部的函数
↓
触发state
↓
完成修改
-->
<p>商品名称:摸鱼套餐,价格$100<button class="btn btn-outline-primary" @click="handleClick">加入购物车</button></p>
<p>商品名称:逃课套餐,价格$200<button class="btn btn-outline-danger" @click="handleClick">加入购物车</button></p>
</div>
</template>
<script>
export default {
methods: {
handleClick(){
// 1. 直接操作变量
// this.$store.state.count++
// 2. 间接操作变量 借助 actions
// dispatch会触发actions中某个方法的执行,这个方法在dispatch中要用括号括起来。
this.$store.dispatch("addCount", 1)
}
},
}
</script>
<style scoped>
button {
margin: 10px;
}
</style>
主视图
<template>
<div class="state-view">
<ShoppingCar></ShoppingCar>
<hr>
<GoodList></GoodList>
</div>
</template>
<script>
import GoodList from '@/components/GoodList.vue';
import ShoppingCar from '@/components/ShoppingCar.vue';
export default {
name: "StateView",
components: {
GoodList,
ShoppingCar
}
}
</script>
<style scoped>
.state-view {
margin: 20px;
padding: 10px;
border: 1px solid black;
}
</style>
store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
count: 100
},
getters: {
},
mutations: {
// 这里的函数名可以和actions的函数名一样 不影响的
// 这里的state 就是state的对象
addOne(state, num) {
console.log(state);
console.log(num);
state.count += num
}
},
actions: {
// 在这里发送Ajax请求,数据库数量增加成功,然后本地(页面)数量再加1 ,这样保证了数据的安全。
// 这个函数会传递一个东西进来,与store实例具有相同方法的上下文对象, 就是mutations 简写成m
// 这个m其实就是state的对象,所以可以用来传参数
// addCount(m, num) ==> this.$store.dispatch("addCount", 1)
addCount(m, num) {
console.log(m);
console.log(m.state.count); // 100
console.log(num); // 1 就是dispatch传过来的数
// 这句化会触发 mutations内部函数 addOne()的执行
// 它一样可以传递参数
// this.commit("addOne", num)
// 3. 间接操作,不通过actions校验,直接请求mutations
// m.commit("addOne", num)
// 4. 通过第一个对象操作
// m.state.count++
}
},
modules: {
}
})
页面跳转
前提,路径已经在app.vue中写好了
<!-- App.vue 就这么多代码就可以了 -->
<template>
<div id="app">
<router-view/>
</div>
</template>
方式1:router.push('path')
这个path里面写router.js里面的path地址,不是name地址!
- HTML属性中跳转,直接写
$router.push("path地址")
- JavaScript内部函数跳转,写
this.$router.push("path地址")
<p><button @click="$router.push('/pe')" class="btn btn-outline-success">回到体育馆</button></p>
<p><button @click="$router.push('/sale')" class="btn btn-outline-primary">回到小卖部</button></p>
方式2:用<router-link to="path">
包裹要跳转的标签
to表示要跳转的地址,这个地址就是指的是router.js中path的地址
<router-link to="/pe">
<p><button class="btn btn-outline-success">回到体育馆</button></p>
</router-link>
<router-link to="/sale">
<p><button class="btn btn-outline-primary">回到小卖部</button></p>
</router-link>
方式3:通过router.push指定方式
<!-- html代码 -->
<p><button class="btn btn-outline-success" @click="toPE">回到体育馆</button></p>
<p><button class="btn btn-outline-primary" @click="toSale">回到小卖部</button></p>
<!-- js methods函数内部代码 -->
this.$router.push({
path: "/pe"
})
this.$router.push({
name: "sale"
})
方式4:通过:to绑定对象跳转
<router-link :to="{path:'/pe'}">
<p><button class="btn btn-outline-success">回到体育馆</button></p>
</router-link>
<router-link :to="{name:'sale'}"> <!-- 通过name指定找不到控制台会报错 -->
<p><button class="btn btn-outline-primary">回到小卖部</button></p>
</router-link>
标签:插件,Vue,name,自定义,js,state,跳转,import,store
From: https://www.cnblogs.com/ccsvip/p/18168723