vue学习中的问题,以及综合小项目

1、vue知识点的综合使用:不能把所学的vue知识点串起来
2、vue项目的创建流程:

(1)vue init webpack 项目名称 -- vue-cli + webpack

(2)webStorm创建vue项目:

A、简洁方式创建:基本的vue项目结构

B、带有语法检查、测试模块的项目:自带有ESLint模块、vue.config.js文件(vue项目的配置文件--如配置vue2项目的默认端

口号)

3、组件的创建

(1)组件:是一个html、css、js的封装体,可以复用。是vue的核心之一。

面试问题:组件的data为什么必须是函数

(2)组件的通信:

A、组件之间的关系:父子关系(props、$emit)、兄弟关系(mitt、vuex)、跨级关系(vuex、provider/inject)

(3)组件的插槽:扩展组件的功能

(4)组件的注册:通过components进行注册

4、vue-router:路由模块

(1)路由:当用户单击某个超链接时,将对应组件渲染出来的过程称为路由

(2)路由配置文件:

A、 创建全局的VueRouter对象(路由器):定义路由表(跳转路径和组件之间的映射关系)、路由模式(hash、history)

B、路由表:是一个数组,包含了若干条路由信息

路由信息:path(路由路径)、component(路由路径对应的组件)、name(路由路径的别名)、

children(配置子路由)

特殊的路由路径:/(项目的根路径)

/*:表示匹配所有路径,通常放在路由路径的末尾(如404页面)

C、三大组成部分:

A、< router-link to="url">:超链接组件,作用类似a标签

B、< router-view> :路由视图,组件渲染的出口

C、VueRouter

(3)在全局的Vue实例中注册路由器

5、axios模块:异步请求模块,封装了ajax

(1)什么是ajax:异步的javascript和xml

(2)同步和异步

(3)回调函数:

(4)数据封装:将服务器端响应的数据统一封装在响应对象的data属性中

(5)请求对象(request)--- 简写为req,客户端向服务器发起的请求(请求头信息、请求数据等)都封装在该对象中

在服务器端通过request对象来获取客户端数据时,都要使用该对象

(6)响应对象(response)--- 简写res,通过该对象将服务器端处理后的数据响应给客户端

(7)axios拦截器:

A、请求拦截器:对客户端的请求进行过滤

B、响应拦截器:对服务器端的响应信息进行拦截,简化前端页面对服务器端响应数据的处理

二、示例:
1、技术点:vue2.6 、 element-ui 、 axios 、 vue-router 、 vuex 、mockjs 、数据可视化(Echarts、antv)
2、突出vue2技术:不写node后台,使用mockjs模拟后台数据、后台接口
3、安装相关的技术模块

(1)安装mockjs:npm i mockjs

(2)安装element-ui:npm i element-ui

(3)安装axios:npm i axios

(4)安装vue-router:npm i vue-router@3

(5)安装vuex:npm i vuex@3

4、定义mockjs的配置文件:生成后台的模拟数据、接口

(1) src / mock / mock.js

import Mock from "mockjs"

const Random=Mock.Random

const data=[]

//调用Mock.mock方法生成随机数据
Mock.mock(()=>{
    for (let i =0;i<10;i++ ){
        //利用mockjs的Random随机生成数字并转化为十六进制,拼接
        const a="#"+Random.integer(180,255).toString(16)+
            Random.integer(180,255).toString(16)+
            Random.integer(120,220).toString(16)

        let t =null //用来存放Random随机生成的用户名
        let male=["男","女"] // 用来存放性别信息的数组
        data.push({
            "userId":1001+i,
            userName:t=Random.cname(), //随机生成中文名字
            userMale:male[Random.integer(0,1)], //在下标,随机生成0或1,就可以随机获取性别
            headImage:Random.image("140x140",a,t),//第一个参数图片的大小,第二个参数颜色,第三个参数是图片上显示的文本
            userBirthday:Random.datetime('yyyy-MM-dd HH:mm:ss'),//生成随机日期,yyyy格式
            userAddress:Random.county(true) //省市县区随机地址
        })
    }
})
//查询所有-接口 (模拟后台接口)
Mock.mock("/api/find","get",data)//第一个参数,接口地址 。第二个参数:请求方式,第三个参数:响应数据

//在main.js中去导入,将mockjs文件在项目中共享,项目中的所有组件都可以访问接口

(2)在项目的main.js中导入mockjs的配置文件:将mockjs文件在项目中共享,项目中的所有组件都可以访问mockjs提供的数据和接口

import './mock' //默认导入的是mock目录下的index.js文件

如果不是,则要写全部地址 import "./mock/mock" //导入mock

  1. 使用axios模块:不做全局配置(即哪个组件使用axios就在组件中引用即可)

6、使用vuex进行全局的数据处理

(1)创建vuex的配置文件:/src/store/index.js

(2)在项目的main.js文件中注册store对象

import store from "./stroe/index";
new Vue({
  store,
  router,
  render: function (h) { return h(App) },
}).$mount('#app')
7、在组件中使用vuex
8、使用element-ui组件库

(1)在项目的main.js导入element-ui、导入element-ui的样式文件

import ElementUI from "element-ui" //导入element-ui库
import "element-ui/lib/theme-chalk/index.css" //导入element-ui的样式文件
Vue.use(ElementUI)

(2)el-table的基本用法

A、给el-table的data属性绑定变量:该变量是一个数组或集合,即在表格中展示的数据

B、el-table的事件:

a、select:当用户手动勾选数据行的 Checkbox 时触发的事件,默认参数是selection, row

参数selection:是用户选择的数据,是数组类型,即用户选择了几行,selection数组就有几个单元

参数row:用户选择的当前行

b、select-all:当用户手动勾选全选的 Checkbox 时触发的事件,默认参数是selection

参数selection:是一个数组,存放的全选的所有数据

c、selection-change:当选择项发生变化时会触发该事件,默认参数是selection

(3)在组件中加入分页

强调的问题:

A、表格(el-table)的样式问题:如A组件是父组件,B组件是子组件,在B组件中使用el-table,出现表格的表头高度不受控制的情况(在B组件中设置表头的高度无效),原因是样式污染即在A组件的样式中有height属性的设置,它污染了B组件中的el-table

B、表格中数据的获取途径:

组件(el-table) —->向vuex的actions派发动作 —-> 在actions的函数中向后台接口发起异步的请求—->actions向mutations提交

修改state的请求同时将从服务器端获取的数据传递过去 —-> 修改state属性的值(即将服务器端的响应数据赋给state属性) —-> 在组件中

通过vuex的getters获取state中的数据并渲染到el-table中

C、分页思想

a、数据总量:数据的记录总数

b、每页显示的记录数

c、总页数

d、分页实现方法:

总记录数:20 —-> arr

每页显示的记录数:5 —->pageCount

页数:4 —->pagesize

1 2 3 4 —->currentPage

每页第一个数据在数组中的下标:start = (currentPage - 1) * pageCount

取分页数据:arr.splice(start,pageCount)

(4)路由问题

A、< router-link to=”url”>链接文本 | 图像 | 视频< /router-link > //封装了a标签

B、< router-view></ router-view>:路由视图 (路由出口)

import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const router = new VueRouter({
    routers:[
        {
            path:'/home',
            name: 'home',
            component: ()=>import Home from './componets/Home'
        }
    ],
    mode: 'history'
})
export default router

在main.js中注册路由器

import Vue from 'vue'
import App from './App.vue'
import store from "./store/index"
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
import './mock'
import router from './router/index'
Vue.use(ElementUI) //在Vue实例中注册element-ui
new Vue({
  store,
  router,  
  render: h => h(App),
}).$mount(

在组件中使用(App.vue)

<router-view name="命名视图"></router-view>

Son.vue

<router-link :to="{name:'home'}">首页</router-link>

(5)axios的拦截器

A、响应拦截器:对服务器的响应数据进行过滤,使前端能够更简单的使用这些数据

B、请求拦截器:对客户端的请求进行拦截,保证只有合法的请求才能进入服务器

import axios from 'axios'
const $http =  axios.create({
    baseURL: 'http://localhost:8089',
    timeout: 2000
})
async $http.getAll(url,params){
    return await this.get(url,params)
}
export default $http

(6)数据可视化

A、Echarts

a、安装:npm i echarts@4.9.0

b、在main.js中配置:

import * as echarts from ‘echarts’

Vue.prototype.echarts = echarts

c、在vue组件的虚拟DOM中定义echarts的挂载点

d、对echarts的各个配置项进行配置(以柱状图bar为例)

title:图表的标题

tooltip:鼠标悬浮在图表上时显示的提示信息

xAxis:x轴的文本

yAxis:y轴的文本

series:是一个数组,包含多个对象,一个对象就是图表中一组柱子

type:表示的图表的类型(bar表示柱状态图、line表示折线图、pie表示饼图……)

data:是一个数组,有多少个单元就显示多少个柱子

B、vue-echarts模块的使用

a、安装:npm i vue-echarts

b、导入:

import 'echarts'
import VueECharts from "vue-echarts";
import "echarts/lib/chart/bar";

c、在vue组件中注册vue-echarts

export default {
     name: 'App',
     components: {
        'v-chart':VueECharts
     }
}

d、在vue组件的data函数中定义vue-echarts配置项

data: function () {
    return {
      bar: {
        color: ["#ffdd38", "#0fc7ab"], // 柱状图颜色设置
        title: {
          text: "Vue-ECharts 入门示例",
          left: 'center'             //标题居中
        },
        tooltip: {},
        animation: false, //不显示动画效果
        legend: {  //图例设置
          //show: false, //是否显示图例
          icon: "circle", // 将图例设置成原型
          bottom: 0,  //图例显示的位置
          left: "center",
          itemWidth: 10,
          itemHeight: 10,
        },
        xAxis: { //x轴显示的内容
          data: ["衬衫","羊毛衫","雪纺衫","裤子","高跟鞋","袜子"],
          axisLabel: {
            rotate: -30 //显示内容的倾斜度
          }
        },
        yAxis: [
          {
            type: 'value',
            name: '销量',
            min: 0,    //设置y轴刻度的最小值
            max: 40,   //设置y轴刻度的最大值
            interval: 5, //y轴的间隔数
            axisLabel: { //y轴标签的显示格式
              formatter: '{value}件'
            },
            splitLine: { //y轴分隔线
              show: true, //显示分隔线
              lineStyle: {
                type: "dashed", //线型
                color: 'red' //线条颜色
              }
            },
            axisLine: {
              show: true, //是否显示坐标轴轴线
            },
            axisTick: {
              show: false, //去掉y轴刻度线
            }
          }
        ],
        series: [
          {
            name: "实体店",
            type: "bar",
            data: [5,20,36,10,10,20]
          },
          {
            name: "网店",
            type: "bar",
            data: [15,30,39,18,22,35]
          }
        ]
      }
    }
  }
}

e、在vue组件的DOM中应用

<v-chart :options="bar"></v-chart>

实现购物车的功能

(1)数据来源:商品信息保存在goods.js文件中。(商品信息:编号、名称、单价)

(2)使用element-ui的el-table显示所有商品信息

(3)在el-table中增加’购买数量’和’操作’两列

a、’购买数量’:可以实现购买数量的增加和减少,数量最低值必须是1

b、’操作’:有“删除”按钮,可以删除所在行的商品

(4)根据用户对商品的选择和购买数量,显示总价

二、MVVM架构:Model — View — ViewModel
1、数据的双向绑定:Model ——> View View ——>Model
2、vue中MVVM的体现:

Model(数据模型):是存放数据的。组件或vue实例的data。

View(视图模型):是渲染数据的。组件中的DOM部分(template中的内容)

ViewModel(视图-模型):实现了Model和View之间的绑定。vue实例就是ViewModel

三、vue中computed计算属性和methods的区别
1、methods方式:

控制台输出:

当修改其中一个属性时,其他属性的值都没改变,但会发现method里的方法都被执行

2、computed方式

控制台输出:

会发现当修改其中一个值得时候,只会执行与其相关的方法

3、总结

(1)methods和computed,两种方式的最终结果完全相同

(2)不同的是计算属性是基于它们的响应式依赖进行缓存的

只有相关响应式依赖发生改变时它们才会重新求值,多次访问getAge会立即返回之前的计算结果,而不必再次执行函数。

(3)methods方法,每当触发重新渲染时,调用方法将总会再次执行函数

建议:对于任何复杂逻辑,都应当优先使用计算属性

三、vue的响应式原理是什么?
1、vue响应式的基本原理:

(1)通过Object.defineProperty来实现监听数据的改变和读取(属性中的getter和setter方法) 实现数据劫持

(2)观察者模式(发布者-订阅者模式)

观察者(订阅者) – Watcher:

update():当事件发生时,具体要做的事情

目标(发布者) – Dep:

①subs 数组:存储所有的观察者

②addSub():添加观察者

③notify():当事件发生,调用所有观察者的 update() 方法

(3)数据发生改变通过发布者订阅者模式来进行通知 进行界面刷新

2、响应过程

(1)首先要对数据(data)进行劫持监听,所以我们需要设置一个监听器Observer,用来监听所有属性。如果属性发生变化了,就需

要告诉订阅者Watcher看是否需要更新。因为订阅者是有很多个,所以我们需要有一个消息订阅器(发布者)Dep来专门收集这些订阅

者,然后在监听器Observer和订阅者Watcher之间进行统一管理的。

(2)接着还需要有一个指令解析器Compile,对每个节点元素进行扫描和解析,将相关指令对应初始化成一个订阅者Watcher,并

替换模板数据或者绑定相应的函数,此时当订阅者Watcher接收到相应属性的变化,就会执行对应的更新函数,从而更新视图。

Vue实例中的data中的每个属性都会被创建一个Dep(发布者)对象,且解析el时进行视图的初始化如果html中有多个地方用到该属性,

则每个地方都会生成一个Watcher(订阅者)的实例被放入到该属性对应Dep(发布者)的实例中的subs数组中。当属性发生改变

时,Observe监听到属性的改变,然后调用该属性对应的Dep(发布者)实例的notify方法,然后notify方法会对Dep(发布者)实例中的

数组进行遍历然后同时调用遍历出的Watcher(订阅者)的实例进行update方法的调用进行视图的更新。伪代码如下:

const obj = {a:15}
    Object.keys(obj).forEach(key => {
      let value = obj[key]
      Object.defineProperty(obj, key, {
        get() {
          console.log('试图读取obj的a属性')
        },
        set(newValue) {
          console.log('试图改变obj的a属性')
          //属性变化时进行对Watcher实例进行通知
          dep.notify()
        }
      })
    })
    //发布者
    class Dep{
      constructor(){
        this.subs = []
      }
      addSub(watch){
        this.subs.push(watch)
      }
      //属性变化发送通知函数
      notify(){
      //接受到通知后 调用update函数进行视图的更新
        this.subs.forEach(item => {
          item.update()
        })
      }
    }
    //订阅者
    class Watcher {
      constructor(name){
        this.name =name
      }
      update(){
        console.log(this.name+'发生update');
      }
    }
    //模拟创建一个发布者
    const dep = new Dep()
    //模拟创建一个订阅者
    const w1 = new Watcher('第一个实例')
    //将订阅者添加到发布者中subs的数组里进行管理
    dep.addSub(w1)
    const w2 = new Watcher('第二个实例')
    dep.addSub(w2)
    const w3 = new Watcher('第三个实例')
    dep.addSub(w3)

(3)因此我们可以执行以下3个步骤,实现数据的双向绑定:

A、实现一个监听器Observer,用来劫持并监听所有属性,如果有变动的,就通知订阅者。

B、实现一个订阅者Watcher,可以收到属性的变化通知并执行相应的函数,从而更新视图。

C、实现一个解析器Compile,可以扫描和解析每个节点的相关指令,并根据初始化模板数据以及初始化相应的订阅器。

四、 AntV数据可视化
1、简介: AntV 是一套专业的数据可视化规范,这套规范的目的是为了让可视化的使用者更懂数据可视化。这套规范是蚂蚁金服在可
视化建设过程中的理论沉淀,它可以很好得指引产品经理,设计师和工程师怎样正确得使用可视化及可视化技术,规避常见的错误。
2、全局使用方法

(1)安装antv/g2

yarn add @antv/g2 --save
或
npm install @antv/g2 --save

(2)全局使用(在main.js中挂在到vue原型实例中)

const G2 = require('@antv/g2')
Vue.prototype.$G2 = G2

(3)vue组件中能够直接在mounted生命周期中直接使用

<template>
  <div id="c1"></div>
</template>
<script>
export default {
  name: "AntV",
  data(){
    return {
      msg: "",
      chart: null,
      data: [
        { genre: "运动", sold: 275 },
        { genre: "行动", sold: 115 },
        { genre: "动作", sold: 120 },
        { genre: "设计", sold: 350 },
        { genre: "其他", sold: 150 }
      ]
    }
  },
  methods:{
    initComponent() {
      const chart = new this.$G2.Chart({
        container: "c1",
        width: 600,
        height: 300
      });
      chart.source(this.data);
      chart
          .interval()
          .position("genre*sold")
          .color("genre");
      this.chart = chart;
      this.chart.render();
    }
  },
  mounted() {
    this.initComponent()
  }
}
</script>
3、按需使用方法

(1)安装antv/g2

yarn add @antv/g2 --save
或
npm install @antv/g2 --save

(2)在组件中按需引入

<template>
  <div>
    <div id="l1"></div>
  </div>
</template>
<script>
import { Chart } from "@antv/g2";
export default {
  name: "AntV2",
  data() {
    return {
      year: [
        { year: "1991", value: 3 },
        { year: "1992", value: 4 },
        { year: "1993", value: 3.5 },
        { year: "1994", value: 5 },
        { year: "1995", value: 4.9 },
        { year: "1996", value: 6 },
        { year: "1997", value: 7 },
        { year: "1998", value: 9 },
        { year: "1999", value: 13 }
      ]
    };
  },
  methods: {
    initLineChart() {
      const chart = new Chart({
        container: "l1",
        autoFit: true,
        height: 500
      });
      chart.data(this.year);
      chart.scale({
        year: {
          range: [0, 1]
        },
        value: {
          min: 0,
          nice: true
        }
      });
      chart.tooltip({
        showCrosshairs: true, // 展现 Tooltip 辅助线
        shared: true
      });
      chart
          .line()
          .position("year*value")
          .label("value");
      chart.point().position("year*value");
      chart.render();
    }
  },
  mounted() {
    this.initLineChart()
  }
}
</script>
4、水平柱状图

(1)安装:npm i @antv/g2plot

(2)在组件中引入:import { Bar } from “@antv/g2plot”

(3)创建图表对象:

<template>
  <div>
    <div id="l2"></div>
  </div>
</template>
<script>
import { Bar } from "@antv/g2plot"
export default {
  name: "AntV2",
  data() {
    return {
      years: [
        { year: "1991", value: 3 },
        { year: "1992", value: 4 },
        { year: "1993", value: 3.5 },
        { year: "1994", value: 5 },
        { year: "1995", value: 4.9 },
        { year: "1996", value: 6 },
        { year: "1997", value: 7 },
        { year: "1998", value: 9 },
        { year: "1999", value: 13 }
      ]
    };
  },
  methods: {
    initBar(){
      const bar = new Bar('l2', {
        data:this.years,
        xField: 'value',
        yField: 'year',
        seriesField: 'year',
        legend: {
          position: 'top-left',
        }
      });
      bar.render();
    }
  },
  mounted() {
    this.initBar()
  }
}
</script>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值