冠辰网站建设,网站页面好了怎么做后端,风铃微网站怎么做,wordpress带会员的主题学习vue2笔记 文章目录 学习vue2笔记脚手架文件结构关于不同版本的Vuevue.config.js配置文件ref属性props配置项mixin(混入)插件scoped样式总结TodoList案例webStorage组件的自定义事件全局事件总线#xff08;GlobalEventBus#xff09;消息订阅与发布#xff08;pubsubGlobalEventBus消息订阅与发布pubsubnextTickVue封装的过度与动画vue脚手架配置代理方法一方法二 插槽Vuex1.概念2.何时使用3.搭建vuex环境4.基本使用5.getters的使用6.四个map方法的使用7.模块化命名空间 路由1.基本使用2.几个注意点3.多级路由多级路由4.路由的query参数5.命名路由6.路由的params参数7.路由的props配置8.router-link的replace属性9.编程式路由导航10.缓存路由组件11.两个新的生命周期钩子12.路由守卫13.路由器的两种工作模式 脚手架文件结构
├── node_modules
├── public
│ ├── favicon.ico: 页签图标
│ └── index.html: 主页面
├── src
│ ├── assets: 存放静态资源
│ │ └── logo.png
│ │── component: 存放组件
│ │ └── HelloWorld.vue
│ │── App.vue: 汇总所有组件
│ │── main.js: 入口文件
├── .gitignore: git版本管制忽略的配置
├── babel.config.js: babel的配置文件
├── package.json: 应用包配置文件
├── README.md: 应用描述文件
├── package-lock.json包版本控制文件关于不同版本的Vue
vue.js与vue.runtime.xxx.js的区别 vue.js是完整版的Vue包含核心功能 模板解析器。vue.runtime.xxx.js是运行版的Vue只包含核心功能没有模板解析器。 因为vue.runtime.xxx.js没有模板解析器所以不能使用template这个配置项需要使用render函数接收到的createElement函数去指定具体内容。
vue.config.js配置文件
使用vue inspect output.js可以查看到Vue脚手架的默认配置。使用vue.config.js可以对脚手架进行个性化定制详情见https://cli.vuejs.org/zh
ref属性
被用来给元素或子组件注册引用信息id的替代者应用在html标签上获取的是真实DOM元素应用在组件标签上是组件实例对象vc使用方式 打标识h1 refxxx...../h1或 School refxxx/School获取this.$refs.xxx
props配置项 功能让组件接收外部传过来的数据 传递数据Demo namexxx/ 接收数据 第一种方式只接收props:[name] 第二种方式限制类型props:{name:String} 第三种方式限制类型、限制必要性、指定默认值 props:{name:{type:String, //类型required:true, //必要性default:老王 //默认值}
}备注props是只读的Vue底层会监测你对props的修改如果进行了修改就会发出警告若业务需求确实需要修改那么请复制props的内容到data中一份然后去修改data中的数据。
mixin(混入) 功能可以把多个组件共用的配置提取成一个混入对象 使用方式 第一步定义混合 {data(){....},methods:{....}....
}第二步使用混入 全局混入Vue.mixin(xxx) 局部混入mixins:[xxx]
插件 功能用于增强Vue 本质包含install方法的一个对象install的第一个参数是Vue第二个以后的参数是插件使用者传递的数据。 定义插件 对象.install function (Vue, options) {// 1. 添加全局过滤器Vue.filter(....)// 2. 添加全局指令Vue.directive(....)// 3. 配置全局混入(合)Vue.mixin(....)// 4. 添加实例方法Vue.prototype.$myMethod function () {...}Vue.prototype.$myProperty xxxx
}使用插件Vue.use()
scoped样式
作用让样式在局部生效防止冲突。写法style scoped
总结TodoList案例 组件化编码流程 (1).拆分静态组件组件要按照功能点拆分命名不要与html元素冲突。 (2).实现动态组件考虑好数据的存放位置数据是一个组件在用还是一些组件在用 1).一个组件在用放在组件自身即可。 2). 一些组件在用放在他们共同的父组件上状态提升。 (3).实现交互从绑定事件开始。 props适用于 (1).父组件 子组件 通信 (2).子组件 父组件 通信要求父先给子一个函数 使用v-model时要切记v-model绑定的值不能是props传过来的值因为props是不可以修改的 props传过来的若是对象类型的值修改对象中的属性时Vue不会报错但不推荐这样做。
webStorage 存储内容大小一般支持5MB左右不同浏览器可能还不一样 浏览器端通过 Window.sessionStorage 和 Window.localStorage 属性来实现本地存储机制。 相关API xxxxxStorage.setItem(key, value); 该方法接受一个键和值作为参数会把键值对添加到存储中如果键名存在则更新其对应的值。 xxxxxStorage.getItem(person); 该方法接受一个键名作为参数返回键名对应的值。 xxxxxStorage.removeItem(key); 该方法接受一个键名作为参数并把该键名从存储中删除。 xxxxxStorage.clear() 该方法会清空存储中的所有数据。 备注 SessionStorage存储的内容会随着浏览器窗口关闭而消失。LocalStorage存储的内容需要手动清除才会消失。xxxxxStorage.getItem(xxx)如果xxx对应的value获取不到那么getItem的返回值是null。JSON.parse(null)的结果依然是null。
组件的自定义事件 一种组件间通信的方式适用于子组件 父组件 使用场景A是父组件B是子组件B想给A传数据那么就要在A中给B绑定自定义事件事件的回调在A中。 绑定自定义事件 第一种方式在父组件中Demo atguigutest/或 Demo v-on:atguigutest/ 第二种方式在父组件中 Demo refdemo/
......
mounted(){this.$refs.xxx.$on(atguigu,this.test)
}若想让自定义事件只能触发一次可以使用once修饰符或$once方法。 触发自定义事件this.$emit(atguigu,数据) 解绑自定义事件this.$off(atguigu) 组件上也可以绑定原生DOM事件需要使用native修饰符。 注意通过this.$refs.xxx.$on(atguigu,回调)绑定自定义事件时回调要么配置在methods中要么用箭头函数否则this指向会出问题
全局事件总线GlobalEventBus 一种组件间通信的方式适用于任意组件间通信。 安装全局事件总线 new Vue({......beforeCreate() {Vue.prototype.$bus this //安装全局事件总线$bus就是当前应用的vm},......
}) 使用事件总线 接收数据A组件想接收数据则在A组件中给$bus绑定自定义事件事件的回调留在A组件自身。 methods(){demo(data){......}
}
......
mounted() {this.$bus.$on(xxxx,this.demo)
}提供数据this.$bus.$emit(xxxx,数据) 最好在beforeDestroy钩子中用$off去解绑当前组件所用到的事件。
消息订阅与发布pubsub 一种组件间通信的方式适用于任意组件间通信。 使用步骤 安装pubsubnpm i pubsub-js 引入: import pubsub from pubsub-js 接收数据A组件想接收数据则在A组件中订阅消息订阅的回调留在A组件自身。 methods(){demo(data){......}
}
......
mounted() {this.pid pubsub.subscribe(xxx,this.demo) //订阅消息
}提供数据pubsub.publish(xxx,数据) 最好在beforeDestroy钩子中用PubSub.unsubscribe(pid)去取消订阅。
nextTick
语法this.$nextTick(回调函数)作用在下一次 DOM 更新结束后执行其指定的回调。什么时候用当改变数据后要基于更新后的新DOM进行某些操作时要在nextTick所指定的回调函数中执行。
Vue封装的过度与动画 作用在插入、更新或移除 DOM元素时在合适的时候给元素添加样式类名。 图示 写法 准备好样式 元素进入的样式 v-enter进入的起点v-enter-active进入过程中v-enter-to进入的终点 元素离开的样式 v-leave离开的起点v-leave-active离开过程中v-leave-to离开的终点 使用transition包裹要过度的元素并配置name属性 transition namehelloh1 v-showisShow你好啊/h1
/transition备注若有多个元素需要过度则需要使用transition-group且每个元素都要指定key值。
vue脚手架配置代理
方法一
在vue.config.js中添加如下配置
devServer:{proxy:http://localhost:5000
}说明
优点配置简单请求资源时直接发给前端8080即可。缺点不能配置多个代理不能灵活的控制请求是否走代理。工作方式若按照上述配置代理当请求了前端不存在的资源时那么该请求会转发给服务器 优先匹配前端资源
方法二
编写vue.config.js配置具体代理规则
module.exports {devServer: {proxy: {/api1: {// 匹配所有以 /api1开头的请求路径target: http://localhost:5000,// 代理目标的基础路径changeOrigin: true,pathRewrite: {^/api1: }},/api2: {// 匹配所有以 /api2开头的请求路径target: http://localhost:5001,// 代理目标的基础路径changeOrigin: true,pathRewrite: {^/api2: }}}}
}
/*changeOrigin设置为true时服务器收到的请求头中的host为localhost:5000changeOrigin设置为false时服务器收到的请求头中的host为localhost:8080changeOrigin默认值为true
*/说明
优点可以配置多个代理且可以灵活的控制请求是否走代理。缺点配置略微繁琐请求资源时必须加前缀。
插槽 作用让父组件可以向子组件指定位置插入html结构也是一种组件间通信的方式适用于 父组件 子组件 。 分类默认插槽、具名插槽、作用域插槽 使用方式 默认插槽 父组件中Categorydivhtml结构1/div/Category
子组件中templatediv!-- 定义插槽 --slot插槽默认内容.../slot/div/template具名插槽 父组件中Categorytemplate slotcenterdivhtml结构1/div/templatetemplate v-slot:footerdivhtml结构2/div/template/Category
子组件中templatediv!-- 定义插槽 --slot namecenter插槽默认内容.../slotslot namefooter插槽默认内容.../slot/div/template作用域插槽 理解数据在组件的自身但根据数据生成的结构需要组件的使用者来决定。games数据在Category组件中但使用数据所遍历出来的结构由App组件决定 具体编码 父组件中Categorytemplate scopescopeData!-- 生成的是ul列表 --ulli v-forg in scopeData.games :keyg{{g}}/li/ul/template/CategoryCategorytemplate slot-scopescopeData!-- 生成的是h4标题 --h4 v-forg in scopeData.games :keyg{{g}}/h4/template/Category
子组件中templatedivslot :gamesgames/slot/div/templatescriptexport default {name:Category,props:[title],//数据在子组件自身data() {return {games:[红色警戒,穿越火线,劲舞团,超级玛丽]}},}/scriptVuex
1.概念
在Vue中实现集中式状态数据管理的一个Vue插件对vue应用中多个组件的共享状态进行集中式的管理读/写也是一种组件间通信的方式且适用于任意组件间通信。
2.何时使用
多个组件需要共享数据时
3.搭建vuex环境 创建文件src/store/index.js //引入Vue核心库
import Vue from vue
//引入Vuex
import Vuex from vuex
//应用Vuex插件
Vue.use(Vuex)//准备actions对象——响应组件中用户的动作
const actions {}
//准备mutations对象——修改state中的数据
const mutations {}
//准备state对象——保存具体的数据
const state {}//创建并暴露store
export default new Vuex.Store({actions,mutations,state
})在main.js中创建vm时传入store配置项 ......
//引入store
import store from ./store
......//创建vm
new Vue({el:#app,render: h h(App),store
})4.基本使用 初始化数据、配置actions、配置mutations操作文件store.js //引入Vue核心库
import Vue from vue
//引入Vuex
import Vuex from vuex
//引用Vuex
Vue.use(Vuex)const actions {//响应组件中加的动作jia(context,value){// console.log(actions中的jia被调用了,miniStore,value)context.commit(JIA,value)},
}const mutations {//执行加JIA(state,value){// console.log(mutations中的JIA被调用了,state,value)state.sum value}
}//初始化数据
const state {sum:0
}//创建并暴露store
export default new Vuex.Store({actions,mutations,state,
})组件中读取vuex中的数据$store.state.sum 组件中修改vuex中的数据$store.dispatch(action中的方法名,数据)或 $store.commit(mutations中的方法名,数据) 备注若没有网络请求或其他业务逻辑组件中也可以越过actions即不写dispatch直接编写commit
5.getters的使用 概念当state中的数据需要经过加工后再使用时可以使用getters加工。 在store.js中追加getters配置 ......const getters {bigSum(state){return state.sum * 10}
}//创建并暴露store
export default new Vuex.Store({......getters
})组件中读取数据$store.getters.bigSum
6.四个map方法的使用 mapState方法用于帮助我们映射state中的数据为计算属性 computed: {//借助mapState生成计算属性sum、school、subject对象写法...mapState({sum:sum,school:school,subject:subject}),//借助mapState生成计算属性sum、school、subject数组写法...mapState([sum,school,subject]),
},mapGetters方法用于帮助我们映射getters中的数据为计算属性 computed: {//借助mapGetters生成计算属性bigSum对象写法...mapGetters({bigSum:bigSum}),//借助mapGetters生成计算属性bigSum数组写法...mapGetters([bigSum])
},mapActions方法用于帮助我们生成与actions对话的方法即包含$store.dispatch(xxx)的函数 methods:{//靠mapActions生成incrementOdd、incrementWait对象形式...mapActions({incrementOdd:jiaOdd,incrementWait:jiaWait})//靠mapActions生成incrementOdd、incrementWait数组形式...mapActions([jiaOdd,jiaWait])
}mapMutations方法用于帮助我们生成与mutations对话的方法即包含$store.commit(xxx)的函数 methods:{//靠mapActions生成increment、decrement对象形式...mapMutations({increment:JIA,decrement:JIAN}),//靠mapMutations生成JIA、JIAN对象形式...mapMutations([JIA,JIAN]),
}备注mapActions与mapMutations使用时若需要传递参数需要在模板中绑定事件时传递好参数否则参数是事件对象。 7.模块化命名空间 目的让代码更好维护让多种数据分类更加明确。 修改store.js const countAbout {namespaced:true,//开启命名空间state:{x:1},mutations: { ... },actions: { ... },getters: {bigSum(state){return state.sum * 10}}
}const personAbout {namespaced:true,//开启命名空间state:{ ... },mutations: { ... },actions: { ... }
}const store new Vuex.Store({modules: {countAbout,personAbout}
})开启命名空间后组件中读取state数据 //方式一自己直接读取
this.$store.state.personAbout.list
//方式二借助mapState读取
...mapState(countAbout,[sum,school,subject]),开启命名空间后组件中读取getters数据 //方式一自己直接读取
this.$store.getters[personAbout/firstPersonName]
//方式二借助mapGetters读取
...mapGetters(countAbout,[bigSum])开启命名空间后组件中调用dispatch //方式一自己直接dispatch
this.$store.dispatch(personAbout/addPersonWang,person)
//方式二借助mapActions
...mapActions(countAbout,{incrementOdd:jiaOdd,incrementWait:jiaWait})开启命名空间后组件中调用commit //方式一自己直接commit
this.$store.commit(personAbout/ADD_PERSON,person)
//方式二借助mapMutations
...mapMutations(countAbout,{increment:JIA,decrement:JIAN}),路由
理解 一个路由route就是一组映射关系key - value多个路由需要路由器router进行管理。前端路由key是路径value是组件。
1.基本使用 安装vue-router命令npm i vue-router 应用插件Vue.use(VueRouter) 编写router配置项: //引入VueRouter
import VueRouter from vue-router
//引入Luyou 组件
import About from ../components/About
import Home from ../components/Home//创建router实例对象去管理一组一组的路由规则
const router new VueRouter({routes:[{path:/about,component:About},{path:/home,component:Home}]
})//暴露router
export default router实现切换active-class可配置高亮样式 router-link active-classactive to/aboutAbout/router-link指定展示位置 router-view/router-view2.几个注意点
路由组件通常存放在pages文件夹一般组件通常存放在components文件夹。通过切换“隐藏”了的路由组件默认是被销毁掉的需要的时候再去挂载。每个组件都有自己的$route属性里面存储着自己的路由信息。整个应用只有一个router可以通过组件的$router属性获取到。
3.多级路由多级路由 配置路由规则使用children配置项 routes:[{path:/about,component:About,},{path:/home,component:Home,children:[ //通过children配置子级路由{path:news, //此处一定不要写/newscomponent:News},{path:message,//此处一定不要写/messagecomponent:Message}]}
]跳转要写完整路径 router-link to/home/newsNews/router-link4.路由的query参数 传递参数 !-- 跳转并携带query参数to的字符串写法 --
router-link :to/home/message/detail?id666title你好跳转/router-link!-- 跳转并携带query参数to的对象写法 --
router-link :to{path:/home/message/detail,query:{id:666,title:你好}}
跳转/router-link接收参数 $route.query.id
$route.query.title5.命名路由 作用可以简化路由的跳转。 如何使用 给路由命名 {path:/demo,component:Demo,children:[{path:test,component:Test,children:[{name:hello //给路由命名path:welcome,component:Hello,}]}]
}简化跳转 !--简化前需要写完整的路径 --
router-link to/demo/test/welcome跳转/router-link!--简化后直接通过名字跳转 --
router-link :to{name:hello}跳转/router-link!--简化写法配合传递参数 --
router-link :to{name:hello,query:{id:666,title:你好}}
跳转/router-link6.路由的params参数 配置路由声明接收params参数 {path:/home,component:Home,children:[{path:news,component:News},{component:Message,children:[{name:xiangqing,path:detail/:id/:title, //使用占位符声明接收params参数component:Detail}]}]
}传递参数 !-- 跳转并携带params参数to的字符串写法 --
router-link :to/home/message/detail/666/你好跳转/router-link!-- 跳转并携带params参数to的对象写法 --
router-link :to{name:xiangqing,params:{id:666,title:你好}}
跳转/router-link特别注意路由携带params参数时若使用to的对象写法则不能使用path配置项必须使用name配置 接收参数 $route.params.id
$route.params.title7.路由的props配置
作用让路由组件更方便的收到参数
{name:xiangqing,path:detail/:id,component:Detail,//第一种写法props值为对象该对象中所有的key-value的组合最终都会通过props传给Detail组件// props:{a:900}//第二种写法props值为布尔值布尔值为true则把路由收到的所有params参数通过props传给Detail组件// props:true//第三种写法props值为函数该函数返回的对象中每一组key-value都会通过props传给Detail组件props(route){return {id:route.query.id,title:route.query.title}}
}8.router-link的replace属性
作用控制路由跳转时操作浏览器历史记录的模式浏览器的历史记录有两种写入方式分别为push和replacepush是追加历史记录replace是替换当前记录。路由跳转时候默认为push如何开启replace模式router-link replace .......News/router-link
9.编程式路由导航 作用不借助router-link 实现路由跳转让路由跳转更加灵活 具体编码 //$router的两个API
this.$router.push({name:xiangqing,params:{id:xxx,title:xxx}
})this.$router.replace({name:xiangqing,params:{id:xxx,title:xxx}
})
this.$router.forward() //前进
this.$router.back() //后退
this.$router.go() //可前进也可后退10.缓存路由组件 作用让不展示的路由组件保持挂载不被销毁。 具体编码 keep-alive includeNews router-view/router-view
/keep-alive11.两个新的生命周期钩子
作用路由组件所独有的两个钩子用于捕获路由组件的激活状态。具体名字 activated路由组件被激活时触发。deactivated路由组件失活时触发。
12.路由守卫 作用对路由进行权限控制 分类全局守卫、独享守卫、组件内守卫 全局守卫: //全局前置守卫初始化时执行、每次路由切换前执行
router.beforeEach((to,from,next){console.log(beforeEach,to,from)if(to.meta.isAuth){ //判断当前路由是否需要进行权限控制if(localStorage.getItem(school) atguigu){ //权限控制的具体规则next() //放行}else{alert(暂无权限查看)// next({name:guanyu})}}else{next() //放行}
})//全局后置守卫初始化时执行、每次路由切换后执行
router.afterEach((to,from){console.log(afterEach,to,from)if(to.meta.title){ document.title to.meta.title //修改网页的title}else{document.title vue_test}
})独享守卫: beforeEnter(to,from,next){console.log(beforeEnter,to,from)if(to.meta.isAuth){ //判断当前路由是否需要进行权限控制if(localStorage.getItem(school) atguigu){next()}else{alert(暂无权限查看)// next({name:guanyu})}}else{next()}
}组件内守卫 //进入守卫通过路由规则进入该组件时被调用
beforeRouteEnter (to, from, next) {
},
//离开守卫通过路由规则离开该组件时被调用
beforeRouteLeave (to, from, next) {
}13.路由器的两种工作模式 对于一个url来说什么是hash值—— #及其后面的内容就是hash值。 hash值不会包含在 HTTP 请求中即hash值不会带给服务器。 hash模式 地址中永远带着#号不美观 。若以后将地址通过第三方手机app分享若app校验严格则地址会被标记为不合法。兼容性较好。 history模式 地址干净美观 。兼容性和hash模式相比略差。应用部署上线时需要后端人员支持解决刷新页面服务端404的问题。