vuex是专门用来管理vue.js应用程序中状态的一个插件。他的作用是将应用中的所有状态都放在一起，集中式来管理。需要声明的是，这里所说的状态指的是vue组件中data里面的属性。简单的来说,它就是存储公共变量的东西,然后插件可以通过它来访问,或者修改数据,来达到响应式.相当于一个仓库,里面可以放很多公共的东西,而这些公共的东西都可以让组件使用.vuex中核心模块有：StateMutationActionGetterState介绍：State提供唯一的公共数据源， 所有共享的数据都要统一放到Store的State中进行存储。类似于data函数管理数据，管理的数据是响应式的，当数据改变时驱动视图更新。第一种取数据方法 当前最新的count值为: {{$store.state.count}} 在template中访问vue实例中的内容时，this可以省略完整写法：{{this.$store.state.count}}第二种取数据方法// 1、从vuex 中按需引入 mapState import { mapState } from 'vuex' // 2、将全局数据，映射为当前组件的计算属性 computed:{ ...mapSate(['count']) } mutation的介绍Mutation用于变更Store中的数据。更新数据，state中的数据只能使用mutations去改变数据。①只能通过mutation变更Store数据,不可以直接操作Store中的数据。②通过这种方式虽然操作起来稍微繁琐-些,但是可以集中监控所有数据的变化。为啥只能通过mutation来操作store的数据呢？为了统一管理，可以将修改store值的操作，统一在一起，可以方便监控数据的变化比如：在Addition和Subtracion以及其他很多界面，都是直接修改count的值，那么后期发现count的值有问题，那么我们就需要找很多文件，一个一个文件排查才可能找出问题，不方便监控数据的变化import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) export default new Vuex.store({ state: { count: 0 }, mutations: { // 第一个默认就是state 第二个参数（step）就是携带的参数 add(state, step) { state.count++ }, actions: {} } }) 触发mutation的第一种方式 触发mutation的第二种方式// 1.从vuex 中按需导入mapMutations 函数 import { mapMutations } from 'vuex'// 2.将指定的 mutations 函数，映射为当前组件的methods函数 methods:{ ...mapMutations (['add', ' addN' ]) } action的介绍Action用于处理异步任务。请求数据，响应成功后把数据提交给mutations如果通过异步操作变更数据，必须通过Action,而不能使用Mutation,但是在Action中还是要通过触发Mutation的方式间接变更数据。actions中要操作数据，必须通过commit触发方法来修改actions中不能直接修改store的数据，数据只能在mutations中修改异步方法必须有一个参数，context，代表当前store实例对象因为为了方便通过commit触发mutations方法 触发action的第一种方式 //直接全局调用 this.$store.dispatch('addNAsync', 5)触发action的第二种方式//1.从vuex中按需导入mapActions函数 import { mapActions } from 'vuex' // 2.将指定的actions 函数，映射为当前组件的methods 函数 methods: { mapActions(['addASync','addNASync' ]) } getter的介绍Getter用于对Store中的数据进行加工处理形成新的数据。Getter 可以对Store中已有的数据加工处理之后形成新的数据，类似Vue的计算属性。Store 中数据发生变化，Getter 的数据也会跟着变化。//定义Getter : const store = new Vuex.store({ state: { count: 0 }, getters: { showNum: state => { return '当前最新的数量是[' + state.count + ']' } } }) 使用getters的第一种方式:{{ this.$store.getters.名称 }}使用getters的第二种方式: // 先按需引入 import { mapGetters } from 'vuex'; computed: { ...mapGetters(['showNum']) }
很多情况下后台会给我们做请求代理，当后台没有帮你的时候只能自己解决了，Vue-cli这里我用的是webpack，那么我们需要在webpack上做代理设置，具体步骤如下：新建一个 webpack.config.js devServer: { historyApiFallback: true, hot: true, inline: true, contentBase: "./app", // port: 3000, //前面是配置 webpack-dev-server 的，也可以 package.json 文件中配置 proxy: { "/api": { // target: 'http://localhost:8888', target: 'https: //www.baidu.com', //要跨域的地址 pathRewrite: {'^/api' : ''}, //把遇到的/api 清除掉请求 就是替换地址 changeOrigin: true, // target是域名的话，需要这个参数， secure: false, // 设置 支持https协议的代理，支持能在https服务 }, // 就可以请求以 https://www.baidu.com 开头的后台数据了 //配置 跨域的主要代码 '/api2': { ..... } //可以配置多个请求 }, }
vue 中的 .sync 修饰符 与 this.$emit('update:key', value)
vue 中 .sync 修饰符，是 2.3.0+ 版本新增的功能 其实就是一个语法糖在有些情况下，我们可能需要对一个 prop 进行“双向绑定”。不幸的是，真正的双向绑定会带来维护上的问题，因为子组件可以变更父组件，且在父组件和子组件两侧都没有明显的变更来源。这也是为什么我们推荐以 update:myPropName 的模式触发事件取而代之。举个例子，在一个包含 title prop 的假设的组件中，我们可以用以下方法表达对其赋新值的意图：在子组件中，props 中 使用 title，然后修改 title 为新的值，并通知父组件：this.$emit('update:title', newTitle)然后父组件可以监听那个事件并根据需要更新一个本地的数据 property。例如： 为了方便起见，我们为这种模式提供一个缩写，即 .sync 修饰符： 当我们用一个对象同时设置多个 prop 的时候，也可以将这个 .sync 修饰符和 v-bind 配合使用： 这样会把 doc 对象中的每一个 property (如 title) 都作为一个独立的 prop 传进去，然后各自添加用于更新的 v-on 监听器。实际应用场景：vue dialog 弹窗中使用父组件引入一个子组件，子组件是一个弹窗，父组件控制弹窗打开，子组件关闭弹窗时通知父组件，父组件不用再监听更新事件父组件： 打开弹窗 <my-dialog :sync.visible="dialogVisible" /> 子组件中： 子组件 props: { visible: { type: Boolean, require: true, default: false } }, methods: { close() { this.$emit('update:visible', false) } }
总结简单易用组件vue-count-to 简洁的数字滚动组件vue-count-to是一个无依赖，轻量级的vue组件 参数属性描述startVal开始值endVal结束值duration持续时间，以毫秒为单位autoplay自动播放decimals要显示的小数位数decimal十进制分割separator分隔符prefix前缀suffix后缀useEasing使用缓和功能easingFn缓和回调功能属性描述mountedCallback挂载以后返回回调start开始计数pause暂停计数reset重置countTonpm详情github详情
利用component组件和is属性来控制页面里面展示内容比如后台系统要实现普通用户跳转普通页面，而管理员用户跳转管理页面的这种情况就可以使用这种方式来解决一、使用方法也简单 <component :is="currentRole" /> 然后引入不同的组件// 管理员页面 import adminDashboard from './admin' // 普通页面 import editorDashboard from './editor' export default { // 同一注入一下 components: { adminDashboard, editorDashboard }, } 加载页面的时候判断权限然后重新赋值 created() { // 判断是不是管理员 然后通过component的is属性跳转不同的页面 if (!this.roles.includes('admin')) { this.currentRole = 'editorDashboard' } }
Vue Router的使用步骤（声明式导航）一、 导入js文件 注意：router.js一定要放到vue之后二、添加路由链接 路由 这里是a标签的值 注意： 是路由中提供的标签，默认会被渲染为a标签，to属性默认被渲染为href属性， to属性的值会被渲染为#开头的hash地址三、添加路由填充位（路由占位符） 路由 这里是a标签的值 注意：占位符的作用是：路由规则匹配到的组件,将会被渲染到 router-view 所在的位置四、 定义路由组件 const rou = { template: ` 这是路由页面 ` }五、 配置路由规则并创建路由实例 const router = new VueRouter({ routes: [{ path: "/rou", component: rou }] })注意：每一个路由规则都是一个对象，对象中至少包含 path 和 component 两个属性path表示 路由匹配的 hash 地址，component 表示路由规则对应要展示的组件对象routes是数组六、将路由挂载到Vue实例中 var app = new Vue({ el: '#app', router })嵌套路由一、 现在副路由上创建路由链接和添加路由填充位//这是父路由 const rou = { template: ` 这是路由页面 嵌套路由 ` }二、 定义嵌套路由组件 const rou1 = { template: ` 这是嵌套的路由页面 ` }三、 配置路由规则//用的是children 和routes差不多 const router = new VueRouter({ routes: [{ path: "/rou", component: rou, children: [{ path: "/rou1", component: rou1, }] }] })动态路由html部分 动态路由1 动态路由2 动态路由3 js部分 const rou = { template: ` 这是动态路由 ` } const router = new VueRouter({ routes: [{ path: "/rou/:id", component: rou, }] }) var app = new Vue({ el: '#app', router })其实就是在配置路由规则的时候加上"/rou/:id" 就生成动态路由了动态路由的传参props :true 直接传props:{ } 对象传pops:()=>({}) 函数传一、 直接传 在配置路由规则的时候加上 props :true 即可路由组件用props接收即可二、 props:{ uname: 'lisi', age: 20 } 三、 props:route=>({ uname: 'zs', age: 20, id: route.params.id }) 编程式导航调用js的api方法实现导航就是不用 进行处罚直接用事件触发Vue-Router中常见的导航方式：this.$router.push("hash地址");this.$router.push("/login");this.$router.push({ name:'user' , params: {id:123} });this.$router.push({ path:"/login" });this.$router.push({ path:"/login",query:{username:"jack"} });this.$router.go(n) n是数字 和history.go 相同 如-1 就是后退实例：const Register = { template: ` 后退 `, methods: { //后退方法 goBack() { this.$router.go(-1) } } }
组件的通信父组件向子组件通信props方式 加属性绑定//这是html 模板 // 1.使用自定义属性绑定父组件传过来的数据 //子组件 Vue.component('temp-div', { // 2.用props 来接收 父组件传过来的数据 props: ['msg'], template: ` {{msg}} `, })//父组件 var app = new Vue({ el: '#app', data: { msg: '我是父组件的数据' } })注意props是一个数组可以接受多个数据在props中使用驼峰形式, 模板中需要使用短横线的形式 因为 HTML 对大小写不敏感, 所以使用短横线的形式字符串形式的模板中没有这个限制props的值可以传递 字符串（String）、数值（Number）、布尔值（Boolean）、数组（Array）、对象（Object）props是单向数据流只能是父组件传向子组件子组件向父组件通信$emit语法：子组件通过自定义事件向父组件传递信息// 子组件 Vue.component('menu-item', { data: function() { return { re: '子组件的数据' } }, template: ` // 这是自定义事件名称 这是要发给父组件的数据 传递数据 ` }); 在模板里定义一个点击事件用 $emit("自定义事件名称"，传递的数据)父组件监听自定义事件// 自定义事件名 处理函数 父组件接受传过来的数据// 父组件 var vm = new Vue({ el: '#app', methods: { //这就是第二步的处理函数 用函数携带参数的形式就接受到了 handle: function(val) { console.log(val); } } }); 兄弟组件之间通信事件中心方式通信设置事件中心 // 提供事件中心 var hub = new Vue();A组件通过自定义事件向事件中心传递信息// 组件A template: ` TOM:{{num}} 点击 `, methods: { handle: function(){ // 传递给事件中心 2是传递的数据 hub.$emit('A-event', 2); } },钩子函数监听// 组件B 用mounted钩子函数监听 mounted: function() { // 监听事件 val是A组件传过来的 hub.$on('A-event', (val) => { this.num = val; });
修饰符事件修饰符语法：.stop 阻止事件继续传播.prevent 阻止标签默认行为.capture 使用事件捕获模式,即元素自身触发的事件先在此处处理，然后才交由内部元素进行处理.self 只当在 event.target 是当前元素自身时触发处理函数.once 事件将只会触发一次.passive 告诉浏览器你不想阻止事件的默认行为 ... ... ... 注意：使用修饰符时，顺序很重要；相应的代码会以同样的顺序产生。因此，用v-on:click.prevent.self会阻止所有的点击，而 v-on:click.self.prevent 只会阻止对元素自身的点击。按键修饰符语法：全部的按键别名：.enter、 .tab、 .delete (捕获“删除”和“退格”键)、.esc、.space、.up、.down、.left、.right修饰键：.ctrl、.alt、.shift、.meta Do something 与按键别名不同的是，修饰键和 keyup 事件一起用时，事件引发时必须按下正常的按键。换一种说法：如果要引发 keyup.ctrl，必须按下 ctrl 时释放其他的按键；单单释放 ctrl 不会引发事件。 表单修饰符.number 转换为数值注意点： 当开始输入非数字的字符串时，因为Vue无法将字符串转换成数值所以属性值将实时更新成相同的字符串。即使后面输入数字，也将被视作字符串。.trim 自动过滤用户输入的首尾空白字符只能去掉首尾的 不能去除中间的空格.lazy 将input事件切换成change事件.lazy 修饰符延迟了同步更新属性值的时机。即将原本绑定在 input 事件的同步逻辑转变为绑定在 change 事件上在失去焦点 或者 按下回车键时才更新自定义按键修饰符 ​
指令：插值表达式：语法：{{要插入的值}}，此时相当于占位符，到时候{{关键字}}会被替换成Model中的数据bug点：当网速较慢时，Vue初始化未完成时，插值表达式不能被解析，会直接显示出来，加载完毕之后又会被替换成真实结果，造成闪烁（Vue的加载代码写在HTML元素之后时会出现该bug）1.v-cloak指令：语法：把它当作HTML元素的一个属性使用示例：{{msg1}}特点：当Vue加载完毕后，v-cloak属性会自动消失使用：添加如下CSS样式：让所有带v-cloak属性的元素隐藏，Vue加载完成后显示实现，解决插值表达式闪烁的问题[v-cloak]{ display: none; }2.v-text：语法： 作用：和插值表达式一样，用于给HTML元素添加文本区别：v-text不会存在闪烁问题v-text会将Model中的数据完全替换到HTML元素中（覆盖）插值表达式只会将Model中的数据替换到插值表达式中（占位符内容的替换相同点：插值表达式和v-text都可以给HTML元素显示文本插值表达式和v-text都不会解析要添加文本中的HTML标签（原样显示）3.v-html：和v-text的唯一区别：给HTML添加内容时会解析内容中的HTML可能有安全问题, 一般只在可信任内容上使用 v-html，永不 用在用户提交的内容上(xss攻击)它与v-text区别在于v-text输出的是纯文本，浏览器不会对其再进行html解析，但v-html会将其当html标签解析后输出。4. v-pre：语法：{{ this will not be compiled }} 注意：显示原始信息跳过编译过程跳过这个元素和它的子元素的编译过程。一些静态的内容不需要编译加这个指令可以加快渲染5. v-bind：语法：在HTML元素的属性目前加上绑定标识，此时HTML的该属性的值就会根据属性值的名字从Model中获取数据注意：【v-bind:】用于绑定HTML元素属性的值（用来响应地更新 HTML 属性）【v-bind:】可以简写为 :v-bind后面是：属性名=，我的理解是表示绑定这个属性，绑定之后，对应的值要去vue的数据里面找 当我们在控制台改变属性值时，对应也会变化。6. v-on：语法：在HTML的事件属性（不带on）前加上绑定标识，此时HTML触发此事件时，会执行事件中绑定的代码示例：点击下显示你好 点击下显示你好注意：常见的web网页的事件都支持绑定事件名字不带on事件触发的方法必须在methods中定义v-on标识的属性会被Vue解析为特定JavaScript，只要内容符合JavaScript规范都能正确执行（比如传入参数）【v-on:】等价于【@】7.v-once语法: {{info}} 注意：只编译一次【显示内容之后不再具有响应式功能】即使data里面定义了info 后期我们修改了 仍然显示的是第一次data里面存储的数据v-once的应用场景: 如果显示的信息后续不需要再修改, 那么可以使用 v-once, 这样可以提高性能8.v-model (数据双向绑定)语法： {{msg}} 注意：限制在 、、、components 中表单中使用当输入框中内容改变的时候， 页面上的msg 会自动更新(数据双向绑定)9. v-show指令通过改变元素的 css 属性（display）来决定元素是显示还是隐藏10. v-if v-else-if v-else语法： 如果flag为true则显示,false不显示! 使用场景：多个元素 通过条件判断展示或者隐藏某个元素。或者多个元素进行两个视图之间的切换v-show 和 v-if的区别v-show本质就是标签display样式设置为none，控制隐藏v-show只编译一次，后面其实就是控制css，而v-if不停的销毁和创建，故v-show性能更好一点。v-if是动态的向DOM树内添加或者删除DOM元素v-if切换有一个局部编译/卸载的过程，切换过程中合适地销毁和重建内部的事件监听和子组件11.v-for可以循环 数组、对象、数字v-for循环对象数组 {{user.id}}---{{user.name}}-----索引:{{index}} v-for 循环对象 值：{{val}}---键：{{key}}-----索引:{{index}} v-for 循环数字 这是第{{count}}次循环 12.自定义指令内置指令不能满足我们特殊的需求Vue允许我们自定义指令Vue.directive 注册全局指令// 注册一个全局自定义指令 `v-focus` Vue.directive('focus', { // 当被绑定的元素插入到 DOM 中时…… inserted: function (el,binding) { // 当前指令绑定的dom元素 //console.log(el); // 指令传入的参数、修饰符、值 v-指令名称:参数.修饰符=值 // console.log(binding) // 聚焦元素 el.focus() } })directives: 注册局部指令：directives: { focus: { // 指令的定义 inserted: function (el) { el.focus() } } }使用：直接在元素上面使用v-focus即可 带属性的 （bind 和 inserted ） bind 方法：绑定当前指令的元素，在内存中被创建的时候就会被立即调用；指令所绑定到的元素，还没有被插入父节点中；推荐把样式相关的设置，都定义在 bind 方法中；inserted 方法：绑定当前指令的元素，被插入到DOM树之后才会被调用； 当指令所绑定到的元素，被插入到文档中的父节点时候，会立即触发 inserted 方法 推荐把行为相关的设置，都定义在 inserted 方法中；