首页 Vue 正文

Vue2 脚手架结构及相关

金鹏头像 金鹏 Vue 2024-09-14 18:09:10 0 192
导读:初始化脚手架先设置一下淘宝镜像,在create项目前npmconfigsetregistryhttps://registry.npm.taobao.org/脚手架结构执行n...

初始化脚手架

image-20240206015503905

先设置一下淘宝镜像,在create项目前

npm config set registry https://registry.npm.taobao.org/

脚手架结构

执行npm run serve 之后

  1. 执行main.js文件 该文件是整个项目的入口文件

import Vue from 'vue' //引入vue
import App from './App.vue' //引入App组件,他是所有组件的父组件

Vue.config.productionTip = false //关闭vue的生产提示

new Vue({
  render: h => h(App),
}).$mount('#app')


  1. assets文件夹中配置静态资源(图片,音频等)

  2. components文件夹中写组件


render函数

创建html元素,解析组件模板

image-20240206015520262

##vue的项目流程

    就是通过main.js将App组件渲染到页面指定位置
    main.js就是vue项目的入口文件,是将App组件渲染到index.html文件的预留区域
    render函数是创建App.vue的模板

    先访问main.js
    访问App.vue ,再访问App.vue中的子组件
    解析App.vue模板,并挂载到指定的容器中

vue.js和vue.runtime.vue.js

只要有runtime就代表是运行版本的vue,不包含模板解析器,只能用render函数来解析模板

image-20240206015543589

$nextTick

  1. this.$nextTick(回调函数)

  2. vue在解析模板时,不会立即更改,只有将代码执行一遍后统一重新解析

  3. 只有在DOM元素更新到页面之后才执行函数体内代码

this.$nextTick( () =>{
        this.$refs.inputTitle.focus();
      });


mixin混入

配置mixin.js文件,写一些共用的方法,数据

export const hunru = {
  methods: {
    showName() {
      alert(this.name)
    }
  }
}
  • 在需要用到的组件里引入mixin.js文件

    import { hunru } from "../mixin";


    • 1

  • 且要在组件里配置mixins属性

    mixins: [hunru],
  • ==全局混合> vm和所有vc都会得到mixin.js中的方法

    (1)将mixin.js引入到main.js中

    (2)Vue.mixin(hunru)


插件(plugins.js)

  • 为了增强vue,在插件里写一些方法和数据,在vm和vc中都可以使用

  • 定义插件

    创建一个插件的js文件

    image-20240206015559868


使用插件

1.在main.js中引入插件js文件

2.使用插件

Vue.use(插件名)


scoped

  • 写在style标签里,为了使相同class名在不同组件中使用

    <style scoped>
  • </style>
  • 父组件里修改子组件的样式,在使用第三方组件库时,修改组件默认样式

    /deep/ h5{}


浏览器本地储存

1.浏览器通过localStorage和sessionStorage属性来实现本地储存

2.localStorage保存一些数据,关闭浏览器,再次打开是数据还在

3.sessionStorage存一些数据,随着浏览器的关闭而消失

添加一个数据

localStorage.setItem('msg','hello')
sessionStorage.setItem('msg','hello')

都是以字符串形式储存,第一个是key,第二个是value


读取数据

localStorage.getItem('msg')
//没有对应的value会返回NUll
  • 删除某个数据

    localStorage.removeItem('msg')


    • 1

  • 删除所有数据

    localStorage.clear()


父子组件传参

父向子传参,props

image-20240206015613534


props属性,父向子传参

rops传过来的属性,会直接出现在vc实例上,所以可以在插值语法中直接使用

props是只读的,不能修改props的值

如果从父组件里传的参数是通过axios请求得来的,在created、mounted中无法得到该值,可以通过watch属性监听该props属性,将值存入data中。而且必须用watch的对象方式监听。

让组件接受外部传来的数据

(1)传递数据到组件

<Student name="郭彦孚" sex="男" :age="1" />



(2)接受数据

1.简单接收

 props: ["name", "sex", "age"]

2.限制类型 限制必要性 指定默认值

image-20240206015628331

  • props中的数据名不能和data中的数据名相同,props的优先级更高,会优先显示props中属性名的值

  • :age=“js表达式”


  • 组件中先读取props中的数据

  • props中传过来的数据不能改变,如果要改变复制一份放入data中,且不能同名

props: ["name", "sex", "age"],
data() {
    return {
      myAge: this.age,
    };
  },
methods: {
    add() {
      this.myAge++;
    },
  },

##自定义事件(子向父传值)

1.主要实现子向父组件进行数据传递

2.和click等内置事件一样(@click=“”),要在父组件中给子组件添加一个自定义事件,父组件会收到子组件传过来的值

也可以添加事件修饰符.once之类的

<School @getSchoolName="schoolName" />
methods: {
 schoolName(name) {
   console.log("我的学校是" + name);
 },
},

3.在子组件内用$emit(“自定义事件名”,要传的参数) 来使用该自定义事件

methods: {
    send() {
      this.$emit("getSchoolName", this.name);
    },
  },

4.解绑自定义事件

  • 解绑一个自定义事件

    this.$off(“自定义事件”)

  • 解绑多个自定义事件

    this.$off([“自定义事件“,”自定义事件”])

  • 解绑所有自定义事件

this.$off()

第二中方法:父组件先给子组件一个函数,子组件调用该函数进行传值


子组件使用原生事件

使用一个事件修饰符(.native)

vue会将写在组件中的事件都看做自定义事件,要想触发原生的事件,要加.native

<School @click.native="schoolName" />


##ref属性

    就是id的替代者

     (1)可以在组件标签和html标签中添加ref=“xxx”

     (2)应用在html标签上时获取的是真实DOM元素,在组件中获取的是组件的实例对象vc,然后就可以调用该组件的方法和数据

     (3)获取时this.$refs.xxx

    ref可以加在组价标签里,得到这个组件的实例对象,实现父组件直接调用子组件的方法和数据,给子组件绑定事件

this.$ref.student.$on('自定义事件名',回调函数),这个要在mounted函数中执行



##全局事件总线

实现任意组件间的通信

数据发送方,调用 e m i t ( ′ 事件名 称 ′ , 要发送的数据 ) 数据接收方,调用 emit('事件名称',要发送的数据) 数据接收方,调用 emit(′事件名称′,要发送的数据)数据接收方,调用on(‘事件名称’,事件处理函数) 最后在beforeDestory()函数中解绑自定义事件

安装全局事件总线$bus
on,emit, o f f 属性只有在 v u e . p r o t o t y p e 上才有,而 v c , v m 都可以访问 v u e . p r o t o t y p e ,所以每个组件都可以获得 off属性只有在vue.prototype上才有,而vc,vm都可以访问vue.prototype,所以每个组件都可以获得 off属性只有在vue.prototype上才有,而vc,vm都可以访问vue.prototype,所以每个组件都可以获得on, e m i t , emit, emit,off属性,将 b u s 绑定在 v u e . p r o t o t y p e 上,每个组件都可以看见它,并且将 bus绑定在vue.prototype上,每个组件都可以看见它,并且将 bus绑定在vue.prototype上,每个组件都可以看见它,并且将bus配置为vm,即 b u s 也会拥有 bus也会拥有 bus也会拥有on, e m i t , emit, emit,off属性

new Vue({
  render: h => h(App),
  beforeCreate() {
    Vue.prototype.$bus = this   //this就是vm
  }
}).$mount('#app')

使用事件总线

接受数据:A组件想接受数据,就在A组件中给$bus绑定自定义事件,事件的回调留在A组件

  methods: {
    //改变done的值
    checkTodos(id) {
      this.todos.forEach((todo) => {
        if (todo.id == id) todo.done = !todo.done;
      });
    },
  },
  mounted() {
    this.$bus.$on("checkTodos", this.checkTodos); 
    //第一个是事件名,第二个是要执行的回调函数,也可以直接写成箭头函数
    this.$bus.$on('checkTodos',(val)=>{
        this.todos = val
    })
  },
  beforeDestroy() {
    this.$bus.$off("checkTodos");
},
5. 提供数据
  this.$bus.$emit("checkTodos", id);


消息订阅与发布

一种任意组件间通信的方式

使用步骤:

    1. 安装pubsub:``npm i pubsub-js``
    1. 在需要通信的组件中引入 ``import pubsub from 'pubsub-js'``
    1. 在接受数据的组件中订阅消息
mounted(){
    this.pid = pubsub.subscribe('事件名',回调函数)  //每一个订阅消息都会返回一个id,要在beforeDestory中取消订阅
},
beforeDestroy() {
    pubsub.unsubscribe(pid)
},
  1. 提供数据的组件中发布消息 pubsub.publish('事件名',数据)


插槽

就是在复用组件时,对复用组件的html结构进行调整

  1. 默认插槽

在组件标签里添加html结构,该html结构会插入到该组件里的位置

//在引入top组件的文件里,在top标签里直接添加html结构
<Top>
    <p>hello,world</p>
</Top>

//top组件中,在想插入的位置摆放<slot>标签
<template>
  <div>
    <slot></slot>
  </div>
</template>


  1. 具名插槽

每个slot标签都有name属性 <slot name='left'></slot>组件标签里加的元素要加上slot="left"

<Left>
     <template v-slot:left>      //v-solt:指定插槽,只有在template中  v-slot:简写为# 
       <p>hello</p>
     </template>
</Left>

<Top>
 <p slot="left">hello,world</p>  
 <p slot="left">hhhh</p>         
</Top>
  

//left组件
<div>
     <slot name="left"> </slot> //可以直接在slot标签中写内容,称为后备内容,当组件没有传内容时,默认显示
</div>
  1. 作用域插槽

还可以传值 父组件直接可以获得子组件传的值

数据在子组件,结构由父组件决定

//app组件
<Left> 
<template v-solt:header='params'>
        <p>{{ scope.params }}</p>    //hello
 </template>
</Left>

//left组件
<div>
      <slotname:'header' msg="hello"></slot>
</div>

ESLint

//在方法形参()之前,不需要空格

“space-before-function-paren”:[“error”,“never”]

配置代理

image-20240206015651493

在vue.config.js中进行配置

module.exports = {
  devServer: {
    proxy: {
      '/api': {  //匹配所有以api开头的路径
        target: '<url>',  //代理目标的基本路径
        pathRewrite: { '^/api': '' }, //修改传回服务器的路径
        ws: true,
        changeOrigin: true
      },
      '/foo': {
        target: '<other_url>'
      }
    }
  }
}

axios在vue中的封装

    安装axios

      npm i axios -S

    引入axios

      import axios from ‘axios’

    axios.defaults.baseURL = ‘http://www.baidu.com’ //全局配置默认请求根路径

      Vue.prototype.$http = axios

    axios的返回值是promise实例对象,用await和async进行修饰和简化


Vuex

vuex中一般存储组件之间共享的数据,适用于多组件共享某些数据,将这些共享的数据集中起来管理

vuex中数据都是响应式的,能够保持数据与页面的同步,数据改变重新解析模板

是实现集中式状态管理的一个Vue插件,适用于任意组件间通信

image-20240206015703114

搭建vuex环境

安装vuex

npm i vuex安装的是vuex4版本,该版本只能用在vue3,vue2只能用vuex3版本 npm i vuex@3

(1)创建store文件:src/store/index.js (先要有vuex,再创建store实例)

tore实例对象是由Vuex.store({})构造出来的,构造之后,在vc,vm上就会出现$store属性

$store属性中 有dispatch,commit方法

//引入vue
import Vue from 'vue'
//引入vuex
import Vuex from 'vuex'
Vue.use(Vuex)
//用于响应组件中的动作
const actions = {}
//用于储存数据
const state = {}
//用于操作数据
const mutations = {}
//创建并导出store
export default new Vuex.Store({
  actions, mutations, state
})


(2)在main.js中引入store

//引入store
import store from './store'
//创建vm
new Vue({
  render: h => h(App),
  store,
  beforeCreate() {
    Vue.prototype.$bus = this
  }
}).$mount('#app')


基本使用

1.在组件中使用dispatch给actions

 this.$store.dispatch("jia", this.n);

2.在store中配置actions,actions主要写业务逻辑,将数据commit给mutations进行操作

如果没有网络请求或业务逻辑,可以直接越过actions,直接编写commit

const actions = {
  //context上下文,有commit,dispatch,state属性
  jia(context, value) {
    context.commit('JIA', value)
  },
  jian(context, value) {
    if(context.state.sum % 2){
        context.commmit('JIA',value)
    }
  }
}

3.mutations主要进行数据加工

mutations会收到两个参数,第一个是state,第二个就是传递过来的数据

const mutations = {
  JIA(state, value) {
    state.sum += value;
  },
  JIAN(state, value) {
    state.sum -= value;
  }
}

4.state 就是将一些共享的数据存放进来,类似与组件中的data

在组件模板中想使用state中数据 $store.state.sum

//用于储存数据
const state = {
  sum: 0
}

5.getters 就是将state中的数据进行运算加工,类似与组件中的computed

在组件中读取 $store.getters.bigData

const getters = {
  bigData(state){
     return state.sum*10  //必须要用return语句,收到的参数就是state
  }
}

6.mapState帮助程序猿简化代码,优化computed计算属性

首先要在组件中引入mapState import {mapState} from 'vuex'

computed: {
    //借助mapState生成计算属性,从state中读取sum,并且形成sum函数
    ...mapState(["sum"]),//==>sum(){
                                //return this.$store.state.sum
                                    }
  },

7.mapActions,模板中调用的函数要传参increment(n)

帮我们生成与actions对话的方法,即this.$store.dispatch("jia", this.n);

  methods: {
    // increment() {
    //   this.$store.dispatch("jia", this.n);
    // },
    ...mapActions({ increment: "jia" }),
  },


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

 <button @click="increment(n)">+</button>1

 

  1. mapMutations,模板中调用的函数要传参increment(n)

  methods: {
    // increment() {
    //   this.$store.commit("jia", this.n);
    // },
    ...mapMutations({ increment: "jia" }),
  },
  1. vuex模块化

让代码更好维护,让数据分类更加明确

(1)修改store.js

// count相关配置
const countOptions = {
  namespaced:true,  //开启命名空间,mapState,mapActions等才能识别是哪个配置中的state,actions等
  actions:{
    addOdd(context,value){
      if(context.state.sum % 2){
        context.commit('ADDODD',value);
      }
    }
  },
  mutations:{
    ADD(state,value){
      state.sum += value;
    },
    DECREASE(state,value){
      state.sum -= value;
    },
    ADDODD(state,value){
      state.sum += value;
    }
  },
  state:{
    sum:0,
  },
  getters:{
  }
}

//person相关配置
const personOptions = {
  namespaced:true,
  actions:{
  },
  mutations:{
    ADDPERSON(state,value){
      console.log(value);
      state.personList.unshift(value)
    }
  },
  state:{
    personList:[{id:'000',name:'李四'}]
  },
  getters:{
    length(state){
      return state.personList.length
    }
  }
}
//导出时要加modules:{}
export default new Vuex.Store({
  modules:{
    countAbout:countOptions,
    personAbout:personOptions
  }
})

(2)组件读取数据

  • 读state中数据

//直接读取
this.$store.state.count.sum
//借助mapState
...mapState('countAbout',['sum'])
  • 组件中调用commit,dispatch,getters的方式都类似

//直接读取
this.$store.commit('countAbout/ADD',person)
//借助mapState
...mapMutations('countAbout',{add:'ADD'})


本文地址:https://www.jinpeng.work/?id=221
若非特殊说明,文章均属本站原创,转载请注明原链接。
广告3

欢迎 发表评论:

  • 请填写验证码

日历

«    2025年4月    »
123456
78910111213
14151617181920
21222324252627
282930

控制面板

您好,欢迎到访网站!
  查看权限
广告2

退出请按Esc键