ref
# 放在组件上:
this.$refs.名字 ---组件对象.组件对象.属性
# 在vue项目中使用:// 写在组件上 <HelloWorld ref="my_hello_world"></HelloWorld> handleClick() { console.log(this.$refs) this.$refs.my_hello_world.name # 获取子组件中的name属性 this.$refs.my_hello_world.showName()# 调用子组件中得方法 this.name = this.$refs.my_hello_world.returnName()# 调用子组件中得方法取得返回值 }
# 2 this.$parent --拿到父组件对象
限制类型props
# 数组形式: props:['自定义属性的名字','自定义属性的名字1']
props: ['msg'] 没有限制类型# 对象形式,限制类型:
props:{自定义属性名字:{ type:String }}
# 对象形式,限制类型,默认值,必填:
props: { msg: { type: String, //类型 required: true, //必要性 default: '老王' //默认值 } },
混入mixin
# 定义:可以把多个组件共用的配置提取成一个混入对象
# 作用:以后再可以在组件中写 data,methods,新的不会影响,如果跟混入一样的会使用
# 列如:记录用户查看每个页面所用时间(停留)
全局每个页面都要写东西:
beforeCreate:启动一个定时器,每隔1s向后端发送一次请求
destroyd:中销毁定时器# 补充:定时器和延时器: setTimeout( ()=>{ console.log('延时器,3s后执行') },3000) setInterval(()=>{ console.log('每隔3s执行') },3000)
# 多个组件公用的,抽取出来
新建 mixin/index.js : data,methods,watch....
export default { data() { return { name: '彭于晏' }}, methods: { handleShowName() { alert(this.name) }},}
# 两种方式使用:
局部使用:配置项:mixins:[写多个]
全局使用:Vue.mixin(混入对象)import mixin from "@/mixin"; // 局部使用 export default { name: 'HomeView', mixins: [mixin], }
// 使用全局混入 main.js import mixin from '@/mixin' Vue.mixin(mixin)
插件plugins
# 作用:插件是用于增强Vue的
# 本质:install 的第一个参数是Vue,第二个以后的参数是插件使用者传递的数据#第三方 vue的插件:
vue-router
vuex (store)
elementui
# 补充:# python 中和js中往类中放属性: class Person: pass Person.name='lqz' p=Person() print(p.name)
//js中 new Vue() # Vue类 Vue.prototype.$name='lqz' # 往类中加属性,跟python有些区别 # this.$router # this代指Vue实例 this.$name # 从对象中取
# 自定义插件:
plugins/index.js里写入代码// cnpm install -g axios import axios from 'axios' export default { install(Vue) { console.log('######' + Vue) //1、设置全局变量--以后可以把axios做成全局,每个组件都直接使用this.$http Vue.prototype.$http = axios //2、设置全局函数--->以后任意组件中 this.$add(2,3) Vue.prototype.$add = (a, b) => { return a + b + 100 } //3、使用混入 Vue.mixin({ data(){ return { name:'lqz' }}, methods:{ showName(){ alert(this.name) }}}) // 4、定义指令 v-for 内置指令,指令是可以自定义的 v-lqz // 5、定义全局组件---elementui做的--<el-button></el-button> }}
# 使用插件:main.js中
// 导入插件,使用 import plugin from '@/plugins' Vue.use(plugin)
# 第三方插件的使用:
* vue-router:
Vue.use(VueRouter)
以后在组件中this.$router 就拿到的是VueRouter 对象
以后在组件中 能拿到 this.$route
全局组件: <router-view/>
* elementui:
Vue.use(Elementui)
全局组件: <el-button></el-button>
全局变量:this.$message()
插槽使用
# 背景:一般编写完1个组件之后组件的内容都是写死的,加数据需去组件中修改,扩展性差
# 作用: 1、一般在组件<Child> </Child>中插入<div>或者其他是没有效果的2、组件中添加<slot></slot>,就可以在的组件标签中添加内容
# 匿名插槽:
<template> // 子组件中 <div class="hello"> <button @click="handleClick">组件--点我看控制台</button> <div> <slot></slot> </div> </template> <HelloWorld> // 父组件中 <img src="../assets/img/1.png" alt="" width="200px" height="300px"> </HelloWorld>
# 具名插槽:
<template> // 子组件中 <div class="hello"> <button @click="handleClick">组件--点我看控制台</button> <div> <slot name='lqz'></slot> </div> </template> <HelloWorld> // 父组件中 <img src="../assets/img/1.png" alt="" width="200px" height="300px" slot='lqz'> </HelloWorld>
vuex插件
# 背景:在Vue中实现集中式状态管理的一个Vue插件,对vue应用中多个组件的共享状态进行集中式的管理,也是一种组件间通信的方式,且适用于任意组件间通信
# 组件间通信:
自定义属性、自定义事件
ref属性:this.$refs.名字 拿到组件对象
父组件中:this.$refs.名字 拿到子组件对象
子组件中:this.$parent 拿到父组件对象
vuex实现组件间通信---不需要关注父子关系
# 简单使用:
store/index.js--写代码import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) export default new Vuex.Store({ // index.js 的state中定义变量 state: { count: 0 }, getters: { }, mutations: { }, actions: { }, modules: { } })
在main.js中引入---任意组件中都会有 this.$store
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')
在任意组件中:取值,修改值
任意组件都可以操作,操作的是同一个变量
js:this.$store.state.count html中:{{$store.state.count}}
# 麻烦使用 ---》官方推荐的
1、直接操作:不用
this.$store.state.count++
2、通过actions:
this.$store.dispatch('addCountAction')
3、 通过mutations:
this.$store.commit('addCountMutations')
vue-router路由
# 简介:官方提供的用来实现SPA 的vue 插件,有着页面跳转效果
# 配置:创建项目时没有安装vue-routercnpm install -S vue-route
新建router/index.js:
import Vue from 'vue' import VueRouter from 'vue-router' import HomeView from '../views/HomeView.vue' Vue.use(VueRouter) const routes = [ { path: '/', name: 'home', component: HomeView }, ] const router = new VueRouter({ mode: 'history', base: process.env.BASE_URL, routes }) export default router
main.js中:
import router from './router' new Vue({ router, render: h => h(App) }).$mount('#app')
# 以后再任意组件中,都有
this.$router # 路由对象,当时导出的
this.$route # 当前路由对象以后只要配置路由和页面组件的对应关系,在浏览器中访问地址即可
# 在App.vue中:<template> <div id="app"> <router-view/> </div> </template>
# 路由跳转:
//通过js跳转 this.$router.push('/about') //通过组件跳转 <router-link to="/about"> //任意标签 </router-link>
# 路由跳转高级--传对象:
<template> <div class="home"> <h1>vue-router</h1> <button @click="handleChange">点我跳转到关于页面--js跳转</button> <button @click="handleChange2">点我跳转到关于页面--js跳转-传对象</button> <button @click="handleChange3">点我跳转到关于页面--js跳转-传对象-携带数据-带在地址栏中</button> <button @click="handleChange4">点我跳转到关于页面--js跳转-传对象-携带数据-带在路径中</button> <button @click="handleSave">点我向localStorage中写入名字</button> </div> </template>
methods: { handleChange() { this.$router.push('/about') }, handleChange2() { this.$router.push({ name: 'about' })}, handleChange3() { // 带在地址栏中数据 this.$router.push('/about?name=xxx') }, handleChange4() { // 带在路径中 this.$router.push({ name: 'about', params: {id: this.id} })}, handleSave() { localStorage.setItem('name', 'lqz') }}
# 使用方式四:在路径中解析出数据
// router/index.js中: { path: '/about/:id', name: 'about', component: AboutView } // 组件中跳转,携带数据 this.$router.push({ name:'about', params:{id:999} }) this.$router.push('/about/666') //在另一个组件中取: this.$route.params.名字
# 通过标签跳转传对象:
<router-link :to="to_url"><button>标签跳转-传对象</button></router-link> // 变量定义: to_url:{name:'about', query:{}, params:{}}
路由嵌套
# 子路由
# 相关api:
this.$router.push(path)--- 相当于点击路由链接(可以返回到当前路由界面)
this.$router.replace(path)---用新路由替换当前路由(不可以返回到当前路由界面)
this.$router.back()---: 请求(返回)上一个记录路由
this.$router.go(-1)--- 请求(返回)上一个记录路由
this.$router.go(1)--- 请求下一个记录路由# 路由两种工作模式:
hash模式:hash值:是指# 及其后面的内容就是hash值。
hash值不会包含在 HTTP 请求中,即:hash值不会带给服务器
缺点:地址中永远带着#号,不美观 。192.168.1.1#login 192.168.1.1#home
若app校验严格,则地址会被标记为不合法。
优点:兼容性较好。
history模式:
地址干净,美观 。 192.168.1.1/login 192.168.1.1/home
兼容性和hash模式相比略差。
应用部署上线时需要后端人员支持,解决刷新页面服务端404的问题# 路由守卫:
作用:对路由进行权限控制
全局路由前置守卫—初始化的时候被调用、每次路由切换之前被调用
router.beforeEach((to, from, next) => { console.log('前置路由守卫', to, from) if (to.name == 'home' || localStorage.getItem('name')) { next() } else { alert('您没有权限') } })
前端开源项目
# 1 后台管理
django-vue-admin:https://gitee.com/liqianglog/django-vue-admin/tree/main/web
https://gitee.com/yudaocode/yudao-ui-admin-vue2
# 2 移动端: vue 在uniapp上写
https://gitee.com/xany/yoshop2.0-uniapp 商城类
https://gitee.com/yudaocode/yudao-mall-uniapp
localStorage,sessionStorage和cookie的使用
# 浏览器可以存数据:
cookie:过期时间,过期了,就清理掉了
localStorage:永久有效,即便浏览器重启也有效,只能手动或代码删除
sessionStorage:当次有效,关闭浏览器,就没了
# vue-cookies的使用:cnpm install vue-cookies -S
cookie.set('xx', 'yy', '7d') console.log(cookie.get('xx')) cookie.remove('xx')
# localStorage和sessionStorage的使用:
methods: { saveLocalStorage() { // localStorage.setItem('name', 'xxx') // sessionStorage.setItem('name', '彭于') cookie.set('xx', 'yy', '7d') }, getLocalStorage() { // console.log(localStorage.getItem('name')) // console.log(sessionStorage.getItem('name')) console.log(cookie.get('xx')) }, deleteLocalStorage() { // localStorage.clear() // localStorage.removeItem('name') // sessionStorage.clear() // sessionStorage.removeItem('name') cookie.remove('xx') }, }