Vue 2
创始人
2024-05-28 13:10:06
0

文章目录

  • 1. 简介
  • 2. 第一个Vue程序
  • 3. 指令
    • 3.1 判断循环
    • 3.2 操作属性
    • 3.3 绑定事件
    • 3.4 表单中数据双向绑定
    • 3.5 其他内置指令
    • 3.6 自定义指令
  • 4. 组件
    • 4.1 全局注册
    • 4.2 局部注册
    • 4.3 组件通讯
    • 4.4 单文件组件
  • 5. 组件插槽
    • 5.1 单个插槽
    • 5.2 具名插槽
    • 5.3 作用域插槽
  • 6. 内置组件
    • 6.1 component组件
    • 6.2 keep-alive组件
    • 6.3 transition组件
  • 7. axios网络通信
    • 7.1 第一个Axios
    • 7.2 各种请求方式
    • 7.3 跨域问题
  • 8. Vue的其他配置
    • 8.1 计算属性
    • 8.2 监视属性
    • 8.3 过滤器
  • 9. 生命周期
  • 10. vue-cli
    • 10.1 简介
    • 10.2 创建项目
    • 10.3 项目目录结构
  • 11. webpack
    • 11.1 简介
    • 11.2 安装使用
  • 12. vuex
    • 12.1 vuex原理
    • 12.2 基本使用
    • 12.2 四个map方法
    • 12.3 模块化+命名空间
  • 13. vue-router
    • 13.1 简介
    • 13.2 简单使用
    • 13.3 单文件注册路由
    • 13.4 路由跳转/传递接受参数
    • 13.5 两个钩子
    • 13.6 路由守卫
    • 13.7 路由两种模式
  • 14. 组件库

1. 简介

Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。

Vue是个MVVM框架,使用了模块化+虚拟DOM

MVVM:Model-View-ViewModel ,核心是ViewModel层,负责转化Model中的数据对象来让数据变得更容易管理和使用

作用:

  • ViewModel层向上与视图层View进行双向绑定
  • ViewModel层向下与Model层通过接口请求进行数据交互

MVVM模式和MVC模式一样,主要目的是分离视图(View)和模型(Model),有一下好处:

  • 低耦合
  • 可复用
  • 独立开发
  • 可测试

⭐解释(思想很重要!):

​ 双向数据绑定 <–(JSON)

View(HTML,CSS,Templates) <- -> ViewModel(JavaScrip,Runtime,Complier) -->(AJAX) Model (Java业务逻辑层->数据库)

​ 前端页面 即时运行即时编译 后端

和JSP本质不一样了,如果前端给我们页面还要${key},这个key还要我们Java程序员写上去,而Vue我们只需要用JSON把数据返回给前端就行了,前端根据模板{{ }}进行显示就行了,这个模板我们不需要我们Java程序员去改去写!!

完全解耦了View层 和Model层,这个是至关重要的,前后端分离的重要一环!!!

Vue.js就是MVVM的实现者,核心就是实现类DOM监听和数据绑定

笔记:前端笔记


2. 第一个Vue程序



Title

Java

{{ message }}

Vue对象7个常用属性:

  • el
  • data
  • template
  • methods
  • rander
  • computed
  • watch

3. 指令

3.1 判断循环

指令带有前缀v,代表他们是Vue提供的特殊特征

v-ifv-elsev-else-if ,根据表达式的真假切换元素的显示和隐藏(操作DOM元素,直接把DOM元素移除了)

yes

No

A

B

C

v-for

  • {{item}} ---> {{index}}

  • 3.2 操作属性

    v-bind 设置元素是属性, 冒号后面代表属性名 v-bind:属性名=表达式

    {{ message }} { message.reverse() }} --> 鼠标悬停几秒查看此处动态绑定提示信息!图片

    ..

    ..

    图片

    简写:图片


    3.3 绑定事件

    v-on 绑定事件,监听DOM事件

    v-on:都是相同的,所以可以简写:

    v-on还可以传递参数,事件修饰符等

    事件修饰符

    • .prevent 阻止标签的默认行为
    • .stop 阻止事件的冒泡
    • .once 事件只触发一次

    还有audio标签里面的play(播放) pause(暂停) 事件等


    3.4 表单中数据双向绑定

    v-model 获取和设置表单元素的值!!

    v-model 在表单是input,textarea,select…元素上创建双向数据绑定,会根据控件类型自动选取正确的方式来更新元素

    v-model会忽略所有表单元素的value,checked,selected特性的初始值而总是将Vue实例的数据作为数据源,你应该在JavaScrip在组件date中设置初始值!!!

    修饰符:v-model.lazy v-model.number v-model.trim


    你输入的文本是:{{message}}
    性别:
    你选中的性别的:{{str}}爱好:你选中的爱好是:{{temp}}

    3.5 其他内置指令

    1. v-show 根据表达式的真假切换元素的显示和隐藏(和v-if效果一样,但这个v-show是操作disabled属性,DOM元素始终都在)

      频繁切换建议使用v-show ,因为频繁操作DOM消耗大。

      =18"/>  
      
    2. v-test 设置标签的文本值。例如

      ,缺点会全部替换掉。解决:可以使用{{ }}语法

    3. v-html设置标签的innerHTML,可能会有XSS攻击

    4. v-cloak 没有值,配合css可以防止vue介入慢,而引起的页面闪烁

    5. v-once 没有值,在初始动态渲染后,都视为静态内容了

    6. v-pre 没有值,跳过所在结点的编译过程(可以利用它跳过没有使用指令差值语法的结点,加快编译)

    7. ref 属性,这个可以简洁操作DOM(id的替代者。如果写在组件标签上,则拿到的是ref属性所在标签对应子组件的实例对象)


    3.6 自定义指令

    directives,注意:自定义函数里面的this不是vm了,而是window!!


    4. 组件

    组件:是可复用Vue实例,就是可以重复使用的模板(局部功能代码和资源的集合)

    4.1 全局注册

    简单的:

    动态数据:


    4.2 局部注册

    (注册的时候是什么名,标签里面用就得用什么名)

    new Vue({el: "#app",     // 局部注册只能在这个根实例中使用components: {'my-com-a': {  // 横线命名要加单引号template: `

    {{ title }}

    `,data() { // data: function{}== data(){}后面是ES6的写法。写成方法是为了多个组件实例数据不相互影响return { title: '我是标题A' }}},MyComB: { // 这样可以不用加单引号,html中使用时会自动映射为上面那种命名template: `

    {{ title }}

    `,data() {return { title: '我是标题A' }}}} }) // 单独配置组件的选项对象 // 每次调用Vue.extend就是调用VueComponent的构造函数,每次返回的都是一个全新的VueComponent,即组件实例对象 // var MyComA = Vue.extend({ }) 简写: var MyComA = { },简写的话注册组件的时候框架会帮我们调用Vue.extend() var MyComA = {/* */} var MyComB = {/* */} new Vue({el: "#app",components: {'my-com-a' : MyComA, //或者MyComA: MyComA (推荐单词首字母都大写,标签里使用也是,但需要在脚手架里面使用)'my-com-b' : MyComb,} }); // 简写 new Vue({el: "#app",components: {MyComA, // 当组件名和属性变量变量的话,可以简写, 这样是ES6的写法MyComb,} });

    4.3 组件通讯

    1. 父组件向子组件传值⭐

      通过props选项接受父组件的传值

      父组件
      
      传递静态的值 动态绑定,绑定静态字符串值需要加单引号 msg父组件中data的值

      props是只读的,如果强转修改Vue有警告。父子组件的所有prop都是单向向下绑定的!!

      如果真的想要改的话,请复制一份到data中,然后再去修改data中的数据。(因为先接受props,再去加载data)

    2. 子组件向父组件传值

      通过自定义事件实现⭐

      绑定自定义事件:

      1. 第一种方式,在父组件中,

      2. 第二种方式,在父组件中,this.$refs.demo.$on('事件名',回调方法)

      注意第二种方式,绑定自定义事件时,回调函数要么配置在methods中,要么用箭头函数,否则this指向会出问题

      触发自定义事件:在子组件中,this.$emit('事件名',数据)

      解绑自定义事件:this.$off('事件名')

      购物车

      总数为: {{totalCount}}

    3. 非父子组件传值

      • 通过父组件进行数据的中转 (兄弟组件)

        如果只有一层的话使用父组件进行中转很简单,如果组件层数很多的话,将会变得非常繁琐!不建议


      • 全局事件总线 ⭐: 独立的事件中心,用于管理不同组件间的传值操作 ,任意两个组件都可以通信,开发中用的最多。

        安装全局事件总线:

        // 标准的写法,在src/main.js中:
        // 在其他组件中直接this.$eventBus.$emit(),this.$eventBus.$on(),所有的组件实例对象,即vc,vm都能看到!!
        new Vue({el: '#app',render: h => h(App),beforeCreate() {// 安装全局事件总线(往Vue的原型对象上放的,所有的组件实例对象都有),this就是根vmVue.prototype.$eventBus = this; }
        })
        

        使用事件总线(最好用完在beforeDestory钩子中,解绑当前组件所用到的事件!):

        购物车


    4.4 单文件组件

    组件配置中,data,methods,watch中的函数…它们的this都是VueComponent实例对象

    Test.vue:(表示一个独立的组件,一般是MyTest用单词首字母都大写的这种命名)

    
    
    

    App.vue :(App一般是根组件,一人之上万人之下,管理所有的子组件)

    vm  -> App.vue  ->  Student.vue  -> Person.vue..->  School.vue   -> ...
    
    
    

    main.js ,人口文件(创建vm)

    import App from './App.vue'new Vue({el: "#root",              // 指定为哪个容器服务template: ``,  // 这个不写也行,或者在下面的id为root的div中写,或者render: h => h(App)components: {App}         // 只注册APP主组件即可,因为App管理所有的子组件
    })
    

    ⭐在脚手架中,自动引入的vue是残缺版的vue,即vue.runtime.esm.js,里面没有模板解析器,因为最终使用webpack打包发布的时候已经解析过了,就不应该有模板解析器了(体积不小),只能用这个方式:render: h => h(App),而用template: 会报错。

    因为vue.runtime.xxx.js,没有模板解析器,所以不能使用template配置项(template属性),需要rander函数接收到的createElement函数去指定内容。(而vue文件里面的template标签里内容是由一个专门的独立模块vue-template-complier解析的,这个脚手架帮已经我们引入了

    index.html (单页面应用,就这一共html)

    
    Title 

    vue单文件开发,js模块化开发需要在脚手架环境下才能执行。


    多个组件共享的配置可以抽取出来一个混合对象。例如:export const hunhe = { data(){...}, methods: {...} }

    局部:{ mixin: [hunhe] }, 全局:Vue.mixin(hunhe)


    this.$nextTick(function() {}) 指定的回调方法会在Dom元素更新完毕后再去执行!!一般用于当数据修改后,要基于更新后新的DOM进行某些操作时,要在nextTick所指定的回调方法中执行。


    5. 组件插槽

    在Vue中我们可以使用元素作为承载分发内容的出口,称为插槽,可以应用在组合组件的场景中。

    以前我们是使用props进行传递,不太繁琐,但也不算简单,使用插槽更简单一点。

    5.1 单个插槽

    不使用插槽中间的内容会被抛弃,使用插槽的话中间写的内容会替换组件中的slot标签

    slot中可以设置默认值,这是默认值,父组件中如果设置了插槽内容会被替换掉!

    (挖个坑,等着组件的使用者进行填充)

    实例文本

    苏瞳

    这里是父组件的视图模板,只能使用父组件的数据!!(因为这部分是父组件来渲染的){{ parValue }}

    5.2 具名插槽

    多个位置需要设置插槽,需要给slot设置name


    5.3 作用域插槽

    作用域插槽:用于让插槽可以使用子组件中的数据

    组件将需要被插槽使用的数据通过v-bind绑定给,这种用于给插槽传递数据的属性称为插槽prop

    组件绑定数据后,插槽中需要使用v-slot接受数据

    (数据在组件的自身,但根据数据生成的结构需要组件的使用者来决定)

    {{ dataObj.value }}{{ dataObj.num }} {{ num }}

    6. 内置组件

    6.1 component组件

    适用于多个组件进行频繁切换的处理,例如选项卡操作

    用于将一个元组件渲染为动态组件,以is属性值决定渲染那个组件。类似v-ifv-else-if的结构。

    is属性在每次进行切换时,Vue都会创建一个新的组件实例 (组件的状态无法进行保留)

    // 下面三个组件进行切换时,前一个输入框的内容就会消失!!
    var ComA = { template: `
    A组件内容,
    ` } var ComB = { template: `
    B组件内容,
    ` } var ComC = { template: `
    C组件内容,
    ` }

    6.2 keep-alive组件

    用于保留组件状态或避免组件重新渲染。

    使用很简单:

    include属性,可以知道哪些组件进行保留状态,哪些不保留!!

     	
     	
    
    

    6.3 transition组件

    在Vue插入,更新,移除DOM时,提供多种不同的方式的应用过渡动画效果。标签

    哈哈哈哈


    7. axios网络通信

    Axios是一个开源的可以用在浏览器端和NodeJS的异步通信框架,主要作用的实现AJAx异步通信,体积小

    特点:

    • 从浏览器创建 XMLHttpRequests
    • 从 node.js 创建 http 请求
    • 支持 Promise API
    • 拦截请求和响应
    • 转换请求和响应数据
    • 取消请求
    • 自动转换JSON数据
    • 客户端支持防御XSRF

    Vue.js由于是视图层框架,所以不支持AJAX的通信功能,为了解决,单独开发了一个vue-resource的插件,但这个进入2.0后就停止了改插件对的维护并**推荐了Axios框架,少用JQuery,**因为操作DOM太繁琐!!


    7.1 第一个Axios

    安装:

    • cdn :
    • npm: npm install axios --save

    data.json

    {"name":"苏瞳java","url": "http://baidu.com","address": {"street": "含光门","city":"陕西西安","country": "中国"}
    }
    

    test.html

    {{info.name}}
    {{info.address.street}}
    点我

    test02.html

    {{ joke }}


    7.2 各种请求方式

    get/delete请求:

    第一个参数:url,第三个参数:config

    这里最好使用箭头函数,这样this才是组件实例对象

    // 向给定ID的用户发起请求
    axios.get('/user?id=12345').then(function (response) {// 处理成功情况console.log(response);}).catch(function (error) {// 处理错误情况console.log(error);}).then(function () {// 总是会执行});// 上述请求也可以按以下方式完成(可选)!! 第二个参数和Post不太一样哦
    axios.get('/user', {params: {id: 12345}}).then(function (response) {console.log(response);}).catch(function (error) {console.log(error);}).then(function () {// 总是会执行});      
    

    post/put请求:

    第一个参数:url,第二个参数:data,第三个参数:config(后两个参数可选)

    axios.post('/user', {        firstName: 'Fred',              lastName: 'Flintstone'}).then(function (response) {console.log(response);}).catch(function (error) {console.log(error);});
    

    四种请求方式的参数:

    axios.get(url[, config])

    axios.delete(url[, config])

    axios.post(url[, data[, config]])

    axios.put(url[, data[, config]])


    7.3 跨域问题

    自己开发情况下会出现跨域问题,解决:

    1. cors

      后端设置响应头(使用多)

    2. jsonp

      利用

      调用发放每次都要计算,都有开销,那这个结果是不经常变化的呢?此时就可以考将这个结果缓存起来,采用计算属性可以很方便的做到这一点,计算属性的特性就是将不经常变化的的计算结果进行缓存,以节约我们的系统开销

      什么使用更新缓存? 1.初次读取计算属性时 2. 所依赖的数据发送变化时


      8.2 监视属性

      监视相比较计算属性能开启异步任务

      切换

      ⭐⭐⭐⭐

      • 被Vue管理的函数,最好写成普通函数,这样this才是vm对象 或 组件实例对象
      • 所有不被Vue所关闭的函数(定时器的回调函数,ajax的回调函数,Promis的回调函数),最好写成箭头函数(监听函数没有this,就会往外找),这样这样this才是vm对象 或 组件实例对象。

      8.3 过滤器

      对要显示的数据进行特定格式化后再显示,(适用于一些简单逻辑的处理)(Vue3已经移除)

      (其实用方法,计算属性都能完成)

      当前时间戳:{{time}}

      转换后时间:{{time | timeFormater()}}

      转换后时间:{{time | timeFormater('YYYY-MM-DD HH:mm:ss')}}


      9. 生命周期

      生命周期函数里面的this都是vm 或者 组件实例对象

      所有的函数看图片!

      • beforeCreate:此时无法通过vm访问data中的数据和methods中的方法(即数据检测,数据代理创建之前)

      • created ⭐:此时就可以通过vm访问data中的数据和methods中的方法

      • beforeMount:挂载之前,页面呈现未经Vue编译的DOM结构(在此时刻自己操作DOM不会生效,因为Vue在下一步会替换你的操作)

      • mounted ** ⭐:挂载完毕,页面呈现经过Vue编译的DOM结构。完成了模板的解析并把初始的真正的DOM放入(即把虚拟DOM转化为真实DOM后,只调用一次), 至此初始化过程结束。一般再此开启定时器,发送请求,绑定自定义事件,订阅消息…等初始化工作**

      • beforeUpdate此时数据是新的,但页面是旧的

        • 它两个之间:会生成新的虚拟DOM,和旧DOM比较是否可以复用,最终完成页面的渲染,Model -> View
      • updated此时数据是新的,页面也是新的

      • beforeDestroy ⭐:此时vm的data,motheds,指令都还可以用,马上执行销毁过程(但再次操作数据页面不在触发更新了),一般进行关闭定时器,取消订阅消息,解除自定义事件…等收尾工作(销毁可以调用vm.$destroy())

      • destroyed:已经销毁

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PT0lVOvZ-1677805762929)(Vue(QuickStart)].assets/生命周期.png)

      10. vue-cli

      10.1 简介

      vue-cli官方提供的一个脚手架,可以快速生成一个vue项目模板。

      主要作用:统一的目录结果,本地调试,热部署,单元测试,集成打包上线(类似后端的Maven

      1. 先安装node.js环境(npm随着nodejs自动安装),一路next就行,会自动配置Path环境变量,node -v/npm -v可查看是否成功。(npm就是一个软件包管理工具,和Linux下的apt软件管理差不多)

      2. 安装node.js淘宝镜像加速器cnpm,这样后续下载会更快,注意:安装都要用管理员运行cmd

        npm install -g cnpm --registry=https://registry.npm.taobao.org

        (下载前可以修改一下npm默认的下载路径,防止占用C盘空间。-g代表全局安装)

      3. 安装vue-cli

        cnpm install @vue-cli -g :vue-cli最新版,输入vue ui即可进入图形化创建项目界面

      4. vue list 可查看可以基于哪些模板创建vue应用程序


      10.2 创建项目

      vue-cli3版本以上创建项目:

      1. 打开命令行,进入你想在哪创建的目录
      2. vue create 项目名
      3. 选择Vue.js的版本 ,选完等待即可
      4. cd 项目名 进入项目,npm run serve 运行项目
      5. 浏览器访问http://localhost:8080/ 即可看到脚手架帮我们写好的HelloWord(ctrl+c停止)

      或者进入你要创建到的目录,执行vue ui图形化界面创建项目:


      10.3 项目目录结构

      文件目录
      ├── node_modules 
      ├── public
      │   ├── favicon.ico: 页签图标
      │   └── index.html: 主页面
      ├── src
      │   ├── assets: 存放静态资源
      │   │   └── logo.png
      │   │── component: 存放组件
      │   │   └── HelloWorld.vue
      │   │── App.vue: 汇总所有组件
      │   └── main.js: 入口文件
      ├── .gitignore: git版本管制忽略的配置
      ├── babel.config.js: babel的配置文件 (ES6 -> ES5)
      ├── package.json: 应用包配置文件 
      ├── README.md: 应用描述文件,怎么使用
      └── package-lock.json: 包版本控制文件
      

      可以在项目目录下创建vue.config.js文件,修改一些默认的配置。配置项官网:配置参考 | Vue CLI (vuejs.org)


      11. webpack

      11.1 简介

      webpack:一个现代JavaScript应用程序的静态模块打包器(module bundler)。当webpack处理应用程序时,他会递归的构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有的这些模块打包成一个或多个bundle。当下最热的前端资源模块化管理工具和打包工具,可以将许多松散耦合的模板按照依赖和规则打包成符合生产环境部署的前端资源。

      ⭐ES6规范,EcmaScirpt6标准增加了JavaScirpt语言层面的模块体系定义。尽量静态化,使编译时就能确定模板依赖关系,以及输入输出的。容易进行静态分析,但有些原生浏览器还没正常这个。可以使用webpack把ES6规范打包成ES5规范。

      import "jquery"
      export dunction doStuff() {}
      module "localModele" {}
      

      11.2 安装使用

      安装webpack

      1. cnpm install webpack -g

        cnpm install webpack-cli -g

      2. webpack -v webpack-cli -v 查看是否成功

      3. 配置:创建webpack.config.js配置文件,有entry,output,module,plugins,resolve,watch等属性…(了解一下)

      使用webpack

      • 创建一个项目(目录),例如 D:\webpack-study
      • 创建modules目录写js代码,要有这个主入口,main.js
      • 工程下创建webpack.config.js (看下面)
      • 运行webpack命令
      • 打包后html页面引入用就行了
      // webpack-study/webpack.config.js文件
      module.exports = {entry: "./modules/main.js",        // 主程序入口,自动把入口所需要的东西全部打包进来output: {                          // 打包输出到那?filename: "./js/bundle.js"}....
      };
      

      然后运行webpack命令,就会生成一个bundle.js打包后的文件(打开看一下是个很长的一行)

      可以使用webpack --watch : 一直监听变化,js变化就重新打包(ctrl+c停止)


      12. vuex

      12.1 vuex原理

      概念:专门在Vue中实现集中式状态(数据)管理的一个Vue插件,对Vue应用中多个组件的共享状态进行集中式的管理(读/写),也是一种组件间通信的方式,且适用于任意组件间通信。

      • 全局事件总线,如果很多组件的话,实现共享数据(读/写)比较乱,麻烦
      • vuex,不属于任何一个组件,要共享的数据都放到vuex中,读写两个api就能实现

      什么时候使用vuex:

      1. 多个组件依赖同一状态
      2. 来自不同组件的行为需要变更同一状态

      原理图:


      12.2 基本使用

      安装:

      Vue 2 匹配 Vuex 3 。Vue 3 匹配 Vuex 4 。

      我用的vue2,安装vuex3版本:npm install vuex@3 --save

      基本使用:

      1. 初始化数据state,配置actions,mutations,操作文件store.js

      2. 组件中读取vuex中的数据$store.state.数据

      3. 组件中修改vuex中的数据$store.dispatch('action中的方法名',数据) ,或者$store.commit('mutations中的方法名',数据)

        若没有网络请求或其他业务逻辑,组件中也可越过actions,即不写dispatch直接调用commit

      Count.vue相当于Controller,action相当于Service,mutatisons相当于Dao

      src/store/index.js 该文件用于创建Vuex中最为核心的store,⭐⭐⭐

      import Vue from 'vue'
      import Vuex from 'vuex'Vue.use(Vuex)	// 应用Vuex插件// 准备actions —— 用于响应组件中的动作 (可以复用)
      // 一般把业务逻辑和发送ajax请求写在actions里面
      const actions = {/* 若没有网络请求或其他业务逻辑,组件中也可越过actionsjia(context,value){console.log('actions中的jia被调用了')context.commit('JIA',value)},jian(context,value){console.log('actions中的jian被调用了')context.commit('JIAN',value)}, */jiaOdd(context, value) {	// context 相当于精简版的 $storeconsole.log('actions中的jiaOdd被调用了')if (context.state.sum % 2) {context.commit('JIA', value)// context.diapath('demo', value) 如果业务复杂的话还可以继续,调diapath(),找actions的方法继续处理}},jiaWait(context, value) {console.log('actions中的jiaWait被调用了')setTimeout(() => {context.commit('JIA', value)}, 500)}
      }// 准备mutations —— 用于操作数据(state)
      // 名字一般大写,便于和actions区分
      const mutations = {JIA(state, value) {console.log('mutations中的JIA被调用了')state.sum += value},JIAN(state, value) {console.log('mutations中的JIAN被调用了')state.sum -= value}
      }// 准备state —— 用于存储共享数据
      const state = {sum: 0 // 当前的和
      }// 准备getters —— 用于将state中的数据进行加工(类似计算属性,但这个可以复用,可以不写这个配置)
      const getters = {bigSum(state) {return state.sum * 10}
      }// 创建并暴露store
      export default new Vuex.Store({actions,mutations,state,getters
      })
      

      src/main.js

      import Vue from 'vue'
      import App from './App.vue'
      import store from './store'Vue.config.productionTip = falsenew Vue({store,        // vm和所有的组件实例对象有个$store对象了render: h => h(App) 
      }).$mount('#app')
      

      Count.vue :单个组件,案例使用(多个组件操作$store.state都一样操作即可)

      
      


      12.2 四个map方法

      1. mapState方法:用于帮助映射 state 中的数据为计算属性

        例如:$store.state.sum -> sum,就不用写这么长了

        import {mapState} from "vuex"computed: {// 借助mapState生成计算属性:从state中读取数据,sum、school、subject(对象写法一)  // ...是ES6语法,把mapState返回的对象每组k-v展开放到computed对应对象中...mapState({sum:'sum', school:'school', subject:'subject'}),// 借助mapState生成计算属性:sum、school、subject(数组写法二)...mapState(['sum', 'school', 'subject'])
        }
        
      2. mapGetters方法:用于帮助映射 getters 中的数据为计算属性

        import {mapGetters} from "vuex"computed: {//借助mapGetters生成计算属性:bigSum(对象写法一)...mapGetters({bigSum:'bigSum'}),//借助mapGetters生成计算属性:bigSum(数组写法二)...mapGetters(['bigSum'])
        }
        
      3. mapMutations方法:用于帮助生成与 mutations 对话的方法,即$store.commit(xxx)的函数

        import {mapMutations} from "vuex"methods: {//靠mapActions生成:increment方法、decrement方法(对象形式)...mapMutations({increment:'JIA', decrement:'JIAN'}),//(数组形式),这样的话使用方法就得...mapMutations(['JIA','JIAN']),
        }// 生成的是这样的。和我们自己写的还是有一点区别的,
        // 自动生成的话就要传参了
        methods: {increment(value) {this.$store.commit('JIA', value)}
        }
        
      4. mapActions方法:用于帮助生成与 actions 对话的方法,即$store.dispatch(xxx)的函数

        import {mapActions} from "vuex"methods:{//靠mapActions生成:incrementOdd、incrementWait(对象形式)...mapActions({incrementOdd:'jiaOdd', incrementWait:'jiaWait'})//(数组形式)...mapActions(['jiaOdd','jiaWait'])
        }// 生成的样式和上面的一样也要传数据
        

        mapActions,mapMutations使用时,若需要传递参数,在模板中绑定事件时传递好参数,否则参数是事件对象。


      12.3 模块化+命名空间

      目的:让代码更好维护,让多种数据分类更加明确

      修改store/index.js文件,为了解决不同模块命名冲突的问题,将不同模块的namespce: true,之后在不同页面中引入getter, actions, mutations时,需要加上所属的模块名。

      // 求和相关的配置 (可以把这个countAbout写到一个文件中,然后暴露)
      const countAbout = {namespaced: true,	// 开启命名空间(默认false)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: countAbout,  // 简写countAboutpersonAbout: personAbout}
      })
      

      获取数据:

      // 自己写:
      this.$store.state.countAbout.sum
      this.$store.commit('countAbout/JIA',this.n)
      this.$store.getters['countAbout/bigSum']// 自动生成:
      computed: {// 第一个参数可以指定分类,从countAbout中去后面的state中数据进行映射...mapState('countAbout', ['sum', 'school', 'subject']),  ...mapState('personAbout', ['personList'])
      },
      methods: {// 这个也要指定命名空间(其他两个map方法一样)...mapMutations('countAbout', {increment:'JIA', decrement:'JIAN'})
      }
      

      13. vue-router

      13.1 简介

      vue-router:官方的路由管理器,它和 Vue.js 的核心深度集成,让构建单页面应用变得易如反掌

      专门用来构建SPA(single page web application)单页面应用,而且点击页面中的导航链接不会刷新页面,只会做页面的局部更新。

      功能:

      • 嵌套的路由/视图表
      • 模块化的、基于组件的路由配置
      • 路由参数、查询、通配符
      • 基于 Vue.js 过渡系统的视图过渡效果
      • 细粒度的导航控制
      • 带有自动激活的 CSS class 的链接
      • HTML5 历史模式或 hash 模式,在 IE9 中自动降级
      • 自定义的滚动条行为

      Vue 2 匹配 Vue-Router 3 。Vue 3 匹配 Vue-Router 4 。

      安装路由插件:当前项目下安装vue-router ,进入当前项目目录 (我用的vue2,先安装vue-router3版本)

      • nmp: cnpm install vue-router@3 --save-dev
      • cdn:

      13.2 简单使用

      单HTML路由演示:

      
      

      Hello App!

      Go to FooGo to Bar


      13.3 单文件注册路由

      src/router/index.js:(配置路由)

      // 该文件专门用来创建整个应用的路由器
      import Vue from 'vue'
      import VueRouter from 'vue-router'
      import HomeView from '../views/HomeView.vue'  // 一般组件放到commponents文件夹里,路由组件放到views或pages里
      import Test from '../views/Test.vue'
      import Abc from '../views/Abc.vue'Vue.use(VueRouter) // 应用路由插件const routes = [{path: '/',name: 'home',   // name可以简化路由跳转,如果是二级路由就不用带一级路由的路径了,直接写name即可component: HomeView},{path: '/test',name: 'test',component: Test,children: [    // 嵌套路由,记得在Test组件中指定Abc组件的渲染位置,即使用{path: 'abc'   // 注意不用加/了,只需要一级路由加component: Abc}   ]},{path: '*',          // 上面匹配不到就去下面指定的redirect: '/'  }
      ]const router = new VueRouter({mode: 'history',  			//代表路由模式,默认是hash,带#号的那种base: process.env.BASE_URL,   //应用的基路径,process.env.BASE_URL指从环境进程中根据运行环境获取的api的base_urlroutes                        //具体的路由配置列表
      })export default router  // 导出
      

      src/main.js

      import Vue from 'vue'
      import App from './App.vue'
      import router from './router'  // 默认是: import router from './router/index.js'Vue.config.productionTip = falsenew Vue({router,  // 安装了路由就有router这个配置项render: h => h(App)
      }).$mount('#app')
      

      实现切换使用标签,active-class属性可以设置高亮样式,vue帮我们自动切换高亮。

      指定展示位使用标签

      当切换路由时,路由组件是被频繁销毁挂载的,可以使用keep-alive标签把要缓存组件包起来,让不展示的路由组件保持挂载,不被销毁


      13.4 路由跳转/传递接受参数

      ⭐⭐⭐⭐

      1. ,本质是个a标签,a标签的属性都可以写。

          
          
        
        
        
      2. this.$router.push()

        这种一般是按钮之类的使用这种跳转方式

        this.$router.push({          path: "/lujing",            // name: "lujing" 也行,前提得配置好路由名query: { value: 2 }    	    // 传递参数,会用&拼接到url中,即 /lujing?value=2// 传递参数,会用/拼接到url中,即 /lujing/2 (router路由器中需要配置占位符,即 path: '/lujing/:value') // 注意:使用params传参不能用path,只能用name!name: "lujing",params: { value: 2 }   
        })
        
      3. this.$router.replace() 用法和上面的push一样,只是history栈中不会有记录(一般做404页面)

      4. this.$router.go(n)

        n为1,即在浏览器记录中前进一步,this.$router.forward()

        n为 -1,即后退一步记录,等同于this.$router.back()

      this.$router对象是全局路由的实例(整个应用的路由器),是router构造方法的实例。pushreplacego方法

      this.$route对象表示当前的路由信息/路由规则,包含了当前 URL 解析得到的信息。

      // 接受参数:
      this.$route.query.xxx   // 取query参数
      this.$route.params.xxx  // 取params参数// 怎么模板中减少重复写this.$route.query.xxx?? 下面只是为了让路由组件更方便的收到参数!
      // 如果是params传参,在路由规则中把props设置为true,使用组件中props接受,直接写{{xxx}}来获取数据
      {name:'test',path:'test/:id',component: Test,// 第一种写法:props值为对象,该对象中所有的key-value的组合最终都会通过props传给Test组件// Test组件中页需要props接受, props: ['a'],就可以直接使用了(使用少,传递的是死数据)// props: {a: 900}// 第二种写法:props值为布尔值,为true时,则把路由收到的所有params参数通过props传给Test组件// Test组件中页需要props接受,props: ['id'],这样使用的时候就不用写this.$route.params.xxx了,直接使用id即可// props: true// 第三种写法:props值为函数,该函数返回的对象中每一组key-value都会通过props传给Test组件// Test组件中页需要props接受,props: ['id']props($route) {return {id: $route.query.id}}// ES6的解构赋值操作props({query}) {return {id: query.id}}
      }//
      // this.$route对象属性:
      fullPath: "/“ 	// 全路径
      hash: ""		
      matched: []		// 返回一个数组,包含当前路由的所有嵌套路径片段的路由记录
      meta: {}		// 可以附加一些数据
      name: null   	// 路径名name
      params: {}		// params参数
      path: "/"  		// 当前的路径path
      query: {}		// query参数
      

      这两个每个组件实例对象都有,router每个组件都相同是一个对象。route每个组件都不同,存放这自己的路由信息。


      13.5 两个钩子

      如果组件里面有定时器,并且我们写了在beforeDestory()里面进行关闭定时器,销毁的时候会关闭定时器。

      但如果我们使用keep-alive缓存路由组件的话,就不会销毁组件,所以定时器也不会关闭,一直开着。所以有了下面这两个钩子:

      路由组件所特有的两个生命周期钩子函数(类似:mounted -> activated, beforeDestory -> deactivated)

      • activated 激活
      • deactivated 失活
      
      

      13.6 路由守卫

      对路由进行权限控制,类似拦截跳转

      全局全局守卫:

      • 全局前置路由守卫
      • 全局后置路由守卫

      src/router/index.js

      import Vue from 'vue'
      import VueRouter from 'vue-router'
      import Test from '../views/Test.vue'Vue.use(VueRouter)const routes = [{path: '/test',name: 'test',component: Test,meta: {    // 一个一个判断path是否需要守卫太麻烦,可以标记一个值,来判断是否需要守卫,里面可以自定义一些属性title: '测试',isAuth: true}  }
      ]const router = new VueRouter({mode: 'history',  			base: process.env.BASE_URL,   routes           
      }) 暴露之前加入一些守护规则 !!
      // 全局前置路由守卫  ->  每次路由切换之前被调用(初始化的时候也会被调用一次)
      // to是要跳转取路由信息, from的当前路由信息,这两个都是路由信息对象$route。
      router.beforEach((to, from, next) => { if (to.path == '/test' && sessionStorage.getItem('user') !== 'admin') {alert("你需要admin身份才能访问");} else {next();  // 放行}// 如果自己配置类路由元信息即meta可以这么写!if (to.meta.isAuth && sessionStorage.getItem('user') !== 'admin') {alert("你需要admin身份才能访问");} else {next();  }
      });// 全局后置路由守卫  ->  每次路由切换之后被调用(初始化的时候也会被调用一次)
      // 没有next(用的不多,可以用来改变一些网页的title)
      router.aferEach((to, from) => {alert("666"); 
      })export default router  // 暴露
      

      独享路由守卫:(注意没有后置路由守卫!!!)

      import Vue from 'vue'
      import VueRouter from 'vue-router'
      import Test from '../views/Test.vue'  Vue.use(VueRouter) const routes = [{path: '/test',name: 'test',  component: Test,beforeEnter: (to, from, next) => {  // ...}}
      ]const router = new VueRouter({mode: 'history',  			base: process.env.BASE_URL,  routes                        
      })export default router  // 导出
      

      组件内守卫:

      • beforeRouteEnter
      • beforeRouteUpdate
      • beforeRouteLeave
      
      

      13.7 路由两种模式

      1. 对于一个url什么是hash值? #及其后面的内容就是hash值

      2. hash值不会包含到http请求中,即hash值不会带给服务器

      hash模式:

      • 地址中永远带着#号,不美观
      • 若以后将地址通过第三方手机app分享,若app校验严格,则地址会被标记为不合法
      • 兼容性较好

      history模式:

      • 地址干净,美观
      • 兼容性相比hash模式略差
      • 应用部署上线时需要后端人员支持,解决刷新页面服务端404的问题

      切换:

      const router =  new VueRouter({mode:'history',routes:[...]
      })export default router
      

      14. 组件库

      移动端:Vant,Cube UI,Mint UI

      PC端:Element UI,IView UI

      1. ElementUI插件安装: npm i element-ui -S

        iinstall 的缩写

        -S--save 的缩写,局部安装,写入到 dependencies对象。

        -D--save-dev 的缩写,局部安装,模块写入到 devDependencies 对象。

        总结:运行时需要用到的包使用–S,否则使用–D

      2. 安装SASS加载器

        cnpm install sass-loader --save-dev
        cnpm install node-sass --save-dev

      src/main.js

      import Vue from 'vue'
      import App from './App.vue'
      import ElementUI from 'element-ui';							// 1. 引入ElementUI组件库
      import 'element-ui/lib/theme-chalk/index.css';				// 2. 引入ElementUI全部样式Vue.config.productionTip = false
      Vue.use(ElementUI)	// 3. 使用ElementUI(所有组件,有点大)new Vue({el:"#app",render: h => h(App),
      })
      

      src/App.vue

      
      

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4SEwWG8C-1677805762931)(Vue(QuickStart)].assets/image-20220430123219471.png)

      按需引入⭐⭐:

      1. 安装:npm install babel-plugin-component -D

      2. 修改src/babel.config.js文件:

        module.exports = {presets: ['@vue/cli-plugin-babel/preset',  // 这个是一开始就有的,其他是配置的["@babel/preset-env", { "modules": false }]],plugins: [["component",{        "libraryName": "element-ui","styleLibraryName": "theme-chalk"}]]
        }
        
      3. src/mian.js

        import Vue from 'vue'
        import App from './App.vue'
        import { Button,Row } from 'element-ui'	// 按需引入组件(样式会根据用的组件自动引入!!)Vue.config.productionTip = falseVue.component(Button.name, Button); 	// Vue.use(Button)
        Vue.component(Row.name, Row);       	// Vue.use(Row)new Vue({el:"#app",render: h => h(App),
        })
        

    相关内容

    热门资讯

    监控摄像头接入GB28181平... 流程简介将监控摄像头的视频在网站和APP中直播,要解决的几个问题是:1&...
    Windows10添加群晖磁盘... 在使用群晖NAS时,我们需要通过本地映射的方式把NAS映射成本地的一块磁盘使用。 通过...
    protocol buffer... 目录 目录 什么是protocol buffer 1.protobuf 1.1安装  1.2使用...
    在Word、WPS中插入AxM... 引言 我最近需要写一些文章,在排版时发现AxMath插入的公式竟然会导致行间距异常&#...
    【PdgCntEditor】解... 一、问题背景 大部分的图书对应的PDF,目录中的页码并非PDF中直接索引的页码...
    修复 爱普生 EPSON L4... L4151 L4153 L4156 L4158 L4163 L4165 L4166 L4168 L4...
    Fluent中创建监测点 1 概述某些仿真问题,需要创建监测点,用于获取空间定点的数据࿰...
    educoder数据结构与算法...                                                   ...
    MySQL下载和安装(Wind... 前言:刚换了一台电脑,里面所有东西都需要重新配置,习惯了所...
    MFC文件操作  MFC提供了一个文件操作的基类CFile,这个类提供了一个没有缓存的二进制格式的磁盘...