Vue脚手架

news/2025/2/19 17:50:27/

目录

  • 一、脚手架文件结构
    • 1.1 创建脚手架
  • 二、关于不同版本的Vue
  • 三、vue.config.js配置文件
  • 四、ref属性
  • 五、props配置项
  • 六、mixin(混入)
  • 七、插件
  • 八、scoped样式
  • 九、小结
  • 十、webStorage
  • 十一、组件的自定义事件
  • 十二、全局事件总线(GlobalEventBus)
  • 十三、nextTick
  • 十四、Vue封装的过度与动画

一、脚手架文件结构

my-app/|- node_modules/  # 依赖库|- public/        # 公共资源|   |- index.html # 应用程序的主 HTML 文件|   |- favicon.ico # 网站图标|- src/           # 源代码|   |- assets/    # 静态资源(图片、样式表等)|   |- components/  # 组件|   |- views/      # 页面级别组件|   |- App.vue     # 根 Vue 组件|   |- main.js     # 主 JavaScript 文件|- tests/         # 测试文件|- .gitignore     # Git 忽略配置文件|- babel.config.js  # Babel 编译器配置文件|- package.json   # 项目元数据和依赖信息|- README.md      # 项目文档

上述文件结构是一个典型的 Vue.js 项目的文件结构示例,其中包含了以下重要目录和文件:

  • node_modules/:存放所有的依赖库,可以通过包管理工具(如 npm 或 yarn)进行安装。
  • public/:存放应用程序的公共资源,如 HTML 文件和一些静态资源(如图标、全局 CSS 文件等)。
  • src/:存放应用程序的源代码,是开发者主要工作的目录。
    • assets/:存放静态资源文件,如图像、样式表等。
    • components/:存放 Vue 组件,用于构建应用程序的用户界面。
    • views/:存放页面级别的 Vue 组件,用于组织和布局多个相关组件。
    • App.vue:根 Vue 组件,定义了整个应用程序的外观和行为。
    • main.js:应用程序的入口文件,引入 Vue 库并创建 Vue 实例。
  • tests/:存放测试文件,用于对应用程序进行单元或集成测试。
  • .gitignore:Git 版本控制系统的忽略配置文件,指定哪些文件或目录不需要纳入版本管理。
  • babel.config.js:Babel 编译器的配置文件,用于将 ES6+ 代码转换为向后兼容的 JavaScript 代码。
  • package.json:项目的元数据和依赖信息,记录了项目名称、版本号、作者、脚本命令等信息,以及所依赖的其他包和版本。
  • README.md:项目的文档文件,通常用于描述项目的特点、使用说明和贡献指南等。

这是一个常见的示例,实际的脚手架文件结构可能因具体的脚手架工具和项目需求而有所差异。

1.1 创建脚手架

  1. 第一步(仅第一次执行):全局安装@vue/cli

    npm install -g @vue/cli

  2. 第二步:切换到你要创建项目的目录,然后使用命令创建项目

    vue create xxx

  3. 第三步:启动项目

    npm run serv

备注:
如出现下载缓慢请配置 npm 淘宝镜像:npm config set registry https://registry.npm.taobao.org

二、关于不同版本的Vue

  1. vue.js与vue.runtime.xxx.js的区别:
    1. vue.js是完整版的Vue,包含:核心功能 + 模板解析器。
    2. vue.runtime.xxx.js是运行版的Vue,只包含:核心功能;没有模板解析器。
  2. 因为vue.runtime.xxx.js没有模板解析器,所以不能使用template这个配置项,需要使用render函数接收到的createElement函数去指定具体内容。

三、vue.config.js配置文件

  1. 使用vue inspect > output.js可以查看到Vue脚手架的默认配置。
  2. 使用vue.config.js可以对脚手架进行个性化定制,详情见:https://cli.vuejs.org/zh

四、ref属性

  1. 被用来给元素或子组件注册引用信息(id的替代者)
  2. 应用在html标签上获取的是真实DOM元素,应用在组件标签上是组件实例对象(vc)
  3. 使用方式:
    1. 打标识:<h1 ref="xxx">.....</h1> <School ref="xxx"></School>
    2. 获取:this.$refs.xxx

School.vue组件

<template><div class="demo"><h2>学校名称:{{name}}</h2><h2>学校地址:{{address}}</h2></div>
</template><script>
export default {name:"School",data() {return {name:"大学",address:"四川"}},
}
</script>
<style>.demo{background-color: gray;}
</style>

App.vue

<template><div><h1 ref="title">hello,{{name}}</h1><button ref="btn" @click="showDom">点我输出上方的DOM元素</button><School ref="sch"></School></div>
</template><script>
import School from './components/School.vue'
export default {name:"App",components:{School},data() {return {name:"蓝朽",}},methods: {showDom(){console.log(this.$refs.title);//真实dom元素console.log(this.$refs.btn);//真实dom元素console.log(this.$refs.sch);//School的vc实例对象}},
}
</script>

main.js

import Vue from "vue"
import App from "./App.vue"
Vue.config.productionTip=false;
new Vue({el:"#app",render:h=>h(App)
})

npm run serve 运行

这里示范了一下简单使用,在脚手架中使用的都是单文件组件。

五、props配置项

  1. 功能:让组件接收外部传过来的数据
  2. 传递数据:
  3. 接收数据:
    1. 第一种方式(只接收):props:[‘name’]
    2. 第二种方式(限制类型):props:{name:String}
    3. 第三种方式(限制类型、限制必要性、指定默认值):
    props:{name:{type:String, //类型required:true, //必要性default:'老王' //默认值}
    }
    

    备注:props是只读的,Vue底层会监测你对props的修改,如果进行了修改,就会发出警告,若业务需求确实需要修改,那么请复制props的内容到data中一份,然后去修改data中的数据。

<template><div><h1>hello,{{msg}}</h1><h2>学生姓名:{{name}}</h2><h2>学生性别:{{sex}}</h2><h2>学生年龄:{{MyAge}}</h2><button @click="MyAge++">点我年龄自增</button></div>
</template><script>
export default {name:"Student",data() {return{msg:"蓝朽",MyAge:this.age}},//简单声明接收// props:['name','sex','age']//接收的同时对类型进行限制,对不上控制台会报错// props:{//   name:String,//   age:Number,//   sex:String// }//接收的同时对类型进行限制+必要值的设置+默认值设置props:{name:{type:String, //name的类型required:true //name属性必须传},age:{type:Number,default:90//默认值90},sex:{type:String,required:true}}
}
</script>

通过<Student name="张三" sex="男" :age="18"/>传值

六、mixin(混入)

  1. 功能:可以把多个组件共用的配置提取成一个混入对象

  2. 使用方式:
    第一步定义混合:

    {
    data(){....},
    methods:{....}
    ....
    }
    

    第二步使用混入:

     全局混入:Vue.mixin(xxx)局部混入:mixins:['xxx']
    

定义mixin.js混合

import Vue from 'vue'
export const hunhe1 = {methods: {showName(){alert(this.name);}}
}
export const hunhe2 = {data(){return {x:100,y:200}}
}

main.js全局混入

import Vue from "vue"
import App from "./App.vue"
import { hunhe1,hunhe2 } from "./mixin";
Vue.config.productionTip=false;
Vue.mixin(hunhe1,hunhe2)
new Vue({el:"#app",render:h=>h(App)
})

Student组件局部混入

<template><div><h2 @click="showName()">学生姓名:{{name}}</h2><h2>学生性别:{{sex}}</h2></div>
</template>
<script>
import { hunhe1, hunhe2 } from '@/mixin';
export default {name:"Student",data() {return{name:"蓝朽",sex:"男"}},mixins:[hunhe1,hunhe2]
}
</script>

七、插件

  1. 功能:用于增强Vue
  2. 本质:包含install方法的一个对象,install的第一个参数是Vue,第二个以后的参数是插件使用者传递的数据。
  3. 定义插件:
    对象.install = function (Vue, options) {// 1. 添加全局过滤器Vue.filter(....)// 2. 添加全局指令Vue.directive(....)// 3. 配置全局混入(合)Vue.mixin(....)// 4. 添加实例方法Vue.prototype.$myMethod = function () {...}Vue.prototype.$myProperty = xxxx
    }
    
  4. 使用插件:Vue.use()

定义插件

export default{install(Vue,x,y,z){console.log(Vue,x,y,z)//全局过滤器Vue.filter('mySlice',function(value) {return value.slice(0,4);})}
}

使用插件

import Vue from "vue"
import App from "./App.vue"
//应用插件
import plugins from './plugins'
Vue.use(plugins,1,2,3)
Vue.config.productionTip=false;
new Vue({el:"#app",render:h=>h(App)
})

School组件

<template><div><h2>学校名称:{{name | mySlice}}</h2><h2>学校地址:{{address}}</h2></div>
</template><script>
export default {name:"Student",data() {return{name:"b站大学hello world",address:"四川"}}
}
</script>

八、scoped样式

  1. 作用:让样式在局部生效,防止冲突。
  2. 写法:<style scoped>
<template><div class="demo"><h2>学校名称:{{name}}</h2><h2>学校地址:{{address}}</h2></div>
</template><script>
export default {name:"Student",data() {return{name:"b站大学",address:"四川"}}
}
</script>
<!-- 局部有效,其他组件中可能也有demo样式,所有要加上scoped-->
<style scoped>.demo{background-color: blue;}
</style>

九、小结

  1. 组件化编码流程:
    (1).拆分静态组件:组件要按照功能点拆分,命名不要与html元素冲突。
    (2).实现动态组件:考虑好数据的存放位置,数据是一个组件在用,还是一些组件在用:
    1).一个组件在用:放在组件自身即可。
    2). 一些组件在用:放在他们共同的父组件上(状态提升)。
    (3).实现交互:从绑定事件开始。
  2. props适用于:
    (1).父组件 ==> 子组件 通信
    (2).子组件 ==> 父组件 通信(要求父先给子一个函数)
  3. 使用v-model时要切记:v-model绑定的值不能是props传过来的值,因为props是不可以修改的!
  4. props传过来的若是对象类型的值,修改对象中的属性时Vue不会报错,但不推荐这样做。

十、webStorage

  1. 存储内容大小一般支持5MB左右(不同浏览器可能还不一样)
  2. 浏览器端通过 Window.sessionStorage 和 Window.localStorage 属性来实现本地存储机制。
  3. 相关API:
    1. xxxxxStorage.setItem(‘key’, ‘value’);
      该方法接受一个键和值作为参数,会把键值对添加到存储中,如果键名存在,则更新其对应的值。
    2. xxxxxStorage.getItem(‘person’);
      该方法接受一个键名作为参数,返回键名对应的值。
    3. xxxxxStorage.removeItem(‘key’);
      该方法接受一个键名作为参数,并把该键名从存储中删除。
    4. xxxxxStorage.clear()
      该方法会清空存储中的所有数据。
  4. 备注:
    1. SessionStorage存储的内容会随着浏览器窗口关闭而消失。
    2. LocalStorage存储的内容,需要手动清除才会消失。
    3. xxxxxStorage.getItem(xxx)如果xxx对应的value获取不到,那么getItem的返回值是null。
    4. JSON.parse(null)的结果依然是null。

LocalStorage

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><h1>LocalStorage</h1><button onclick="saveData()">点我保存数据</button><button onclick="readData()">点我读取数据</button><button onclick="deleteData()">点我删除数据</button><button onclick="deleteAllData()">点我清空数据</button><script>let p = {name:"zhangsan",age:18}function saveData() {localStorage.setItem('msg','hello localstorage');localStorage.setItem('person',JSON.stringify(p))}function readData() {const res = localStorage.getItem('person')console.log(JSON.parse(res))}function deleteData() {localStorage.removeItem('msg')}function deleteAllData() {localStorage.clear()}</script>
</body>

sessionStorage

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><h1>sessionStorage</h1><button onclick="saveData()">点我保存数据</button><button onclick="readData()">点我读取数据</button><button onclick="deleteData()">点我删除数据</button><button onclick="deleteAllData()">点我清空数据</button><script>let p = {name:"zhangsan",age:18}function saveData() {sessionStorage.setItem('msg','hello localstorage');sessionStorage.setItem('person',JSON.stringify(p))}function readData() {const res = sessionStorage.getItem('person')console.log(JSON.parse(res))}function deleteData() {sessionStorage.removeItem('msg')}function deleteAllData() {sessionStorage.clear()}</script>
</body>
</html>

十一、组件的自定义事件

  1. 一种组件间通信的方式,适用于:子组件 ===> 父组件
  2. 使用场景:A是父组件,B是子组件,B想给A传数据,那么就要在A中给B绑定自定义事件(事件的回调在A中)。
  3. 绑定自定义事件:
    1. 第一种方式,在父组件中:<Demo @lx=“test”/> 或
    2. 第二种方式,在父组件中:
       <Demo ref="demo"/>......mounted(){this.$refs.xxx.$on('lx',this.test)}
      
    3. 若想让自定义事件只能触发一次,可以使用once修饰符,或$once方法。
      1. 触发自定义事件:this.$emit(‘lx’,数据)
  4. 解绑自定义事件this.$off(‘atguigu’)
  5. 组件上也可以绑定原生DOM事件,需要使用native修饰符。
  6. 注意:通过this.$ refs.xxx.$on(‘lx’,回调)绑定自定义事件时,回调要么配置在methods中要么用箭头函数,否则this指向会出问题!

App.vue

<template><div class="app"><h1>{{msg}},{{studentName}}</h1><!-- 通过父组件给子组件传递函数类型的props实现:子给父传递数据 --><School :getSchoolName="getSchoolName"/><!-- 通过父组件给子组件绑定一个自定义事件实现:子给父传递数据(第一种方法,使用@或v-on) --><Student v-on:lxwork="getStudentName" @demo="m1" @click.native="show"/><!-- 通过父组件给子组件绑定一个自定义事件实现:子给父传递数据(第二种方法,使用ref)--><!-- <Student ref="student"/> --></div>
</template><script>
import School from './components/School.vue'
import Student from './components/Student.vue'
export default {name:"App",components:{Student,School},data() {return {msg:'你好啊!',studentName:''}},methods: {getSchoolName(name){console.log("组件App收到了学校名:"+name)},getStudentName(name,...params){console.log("组件App收到了学生名:"+name,params)this.studentName = name},m1(){console.log('demo事件被触发了')},show(){alert(1123)}},mounted() {//绑定自定义事件// this.$refs.student.$on('lxwork',this.getStudentName)//绑定自定义事件,只被触发一次// this.$refs.student.$once('lxwork',this.getStudentName)},
}
</script>
<style>
.app{background-color: gray;padding: 5px;
}
</style>

Student.vue

<template><div class="demo"><h2>学生姓名:{{name}}</h2><h2 class="text">学生性别:{{sex}}</h2><button @click="sendStudentName">把学校名给App组件</button><button v-on:click="unbind">点我解绑lxwork事件</button><button @click="death">销毁当前Student组件的实例(vc)</button></div>
</template><script>
export default {name:"Student",data() {return{name:"蓝朽",sex:"男"}},methods: {sendStudentName(){//触发Student组件实例身上的lxwork事件this.$emit('lxwork',this.name,1,2,3)this.$emit('demo')},unbind(){// this.$off('lxwork')//解绑一个自定义事件// this.$off(['lxwork','demo'])//解绑多个自定义事件this.$off()//解绑所有自定义事件},death(){this.$destroy()//销毁了当前Student组件的实例//销毁后所有Student实例的自定义事件全都不奏效。}},
}
</script>
<!-- less语法可与嵌套样式 -->
<style scoped lang="less">
.demo{background-color: orange;padding: 5px;margin-top: 30px;.text{font-family: 楷体;}
}
</style>

十二、全局事件总线(GlobalEventBus)

  1. 一种组件间通信的方式,适用于任意组件间通信
  2. 安装全局事件总线:
    new Vue({......beforeCreate() {Vue.prototype.$bus = this //安装全局事件总线,$bus就是当前应用的vm},......
    }) 
    
  3. 使用事件总线:
    1. 接收数据:A组件想接收数据,则在A组件中给$bus绑定自定义事件,事件的回调留在A组件自身。
      methods(){demo(data){......}
      }
      ......
      mounted() {this.$bus.$on('xxxx',this.demo)
      }
      
    2. 提供数据:this.$ bus.$emit(‘xxxx’,数据)
  4. 最好在beforeDestroy钩子中,用$off去解绑当前组件所用到的事件。

main.js:安装全局事件总线

import Vue from "vue"
import App from "./App.vue"
Vue.config.productionTip=false;
new Vue({el:"#app",render:h=>h(App),beforeCreate() {Vue.prototype.$bus=this//安装全局事件总线,在Vue的原型上面添加$bus属性},
})

Student组件给School组件发送消息
School组件

<template><div class="demo"><h2>学校名称:{{name}}</h2><h2>学校地址:{{address}}</h2></div>
</template><script>
export default {name:"Student",data() {return{name:"b站大学",address:"四川"}},mounted() {//绑定事件this.$bus.$on('hello',(data)=>{console.log("我是school组件:"+data)})},beforeDestroy(){//销毁事件this.$bus.$off('hello')}
}
</script>
<style scoped>.demo{background-color: blue;padding: 5px;}
</style>

Student组件

<template><div class="demo"><h2>学生姓名:{{name}}</h2><h2 class="text">学生性别:{{sex}}</h2><button @click="sendStudentName">把学生名给School组件</button></div>
</template><script>
export default {name:"Student",data() {return{name:"蓝朽",sex:"男"}},methods: {sendStudentName(){//触发hello事件this.$bus.$emit('hello',this.name);}},
}
</script>
<!-- less语法可与嵌套样式 -->
<style scoped lang="less">
.demo{background-color: orange;padding: 5px;margin-top: 30px;.text{font-family: 楷体;}
}
</style>

十三、nextTick

  1. 语法:this.$nextTick(回调函数)
  2. 作用:在下一次 DOM 更新结束后执行其指定的回调。
  3. 什么时候用:当改变数据后,要基于更新后的新DOM进行某些操作时,要在nextTick所指定的回调函数中执行。
    例如:
            //编辑handleEdit(todo){if (todo.hasOwnProperty('isEdit')) {todo.isEdit = true} else {this.$set(todo,'isEdit',true)}// todo.isEdit=true;this.$nextTick(function() {//获取焦点,也可以用setTimeout实现this.$refs.inputTitle.focus()})},
    

十四、Vue封装的过度与动画

  1. 作用:在插入、更新或移除 DOM元素时,在合适的时候给元素添加样式类名。

  2. 写法:

    1. 准备好样式:
      • 元素进入的样式:
        1. v-enter:进入的起点
        2. v-enter-active:进入过程中
        3. v-enter-to:进入的终点
      • 元素离开的样式:
        1. v-leave:离开的起点
        2. v-leave-active:离开过程中
        3. v-leave-to:离开的终点
    2. 使用<transition>包裹要过度的元素,并配置name属性:
              <transition name="hello"><h1 v-show="isShow">你好啊!</h1></transition>
    
    1. 备注:若有多个元素需要过度,则需要使用:<transition-group>,且每个元素都要指定key值。
      在这里插入图片描述
<template><div><button @click="isShow=!isShow">显示/隐藏</button><transition name="hello" :appear="true"><h1 v-show="isShow" class="come">你好啊!</h1></transition></div>
</template><script>
export default {name:'Test',data() {return {isShow:true}},
}
</script><style scoped>h1{background-color: orange;}.hello-enter-active{animation: Mytest 1s linear;}.hello-leave-active{animation:Mytest 1s linear reverse;}@keyframes Mytest {from{transform: translateX(-100%);}to{transform: translateX(0px);}}
</style>

多元素过渡

<template><div><button @click="isShow=!isShow">显示/隐藏</button><transition-group name="hello" :appear="true"><h1 v-show="isShow" class="come" key="1">你好啊!</h1><h1 v-show="isShow" class="come" key="2">蓝朽</h1></transition-group></div>
</template><script>
export default {name:'Test2',data() {return {isShow:true}},
}
</script><style scoped>h1{background-color: orange;}/* 利用过渡实现 *//*进入的起点,离开的终点*/.hello-enter,.hello-leave-to{transform: translateX(-100%);}.hello-enter-active,.hello-leave-active{transition: 1s linear;}/*进入的终点,离开的起点*/.hello-enter-to,.hello-leave{transform: translateX(0);}</style>

使用第三方动画

<template><div><button @click="isShow=!isShow">显示/隐藏</button><transition-group name="animate__animated animate__bounce" enter-active-class="animate__swing"leave-active-class="animate__backOutUp"appear><h1 v-show="isShow" class="come" key="1">你好啊!</h1><h1 v-show="isShow" class="come" key="2">蓝朽</h1></transition-group></div>
</template><script>
import 'animate.css'
export default {name:'Test3',data() {return {isShow:true}},
}
</script><style scoped>
h1{background-color: orange;}</style>

http://www.ppmy.cn/news/480330.html

相关文章

win10计算机怎样双屏,有什么办法让window10双屏显示_教你一招让window10双屏的方法...

win10电脑运行多个程序会不知不觉打开多个不同类型的窗口&#xff0c;窗口多了总要时不时的来回频繁切换&#xff0c;总感觉很麻烦。如果不想频繁切换&#xff0c;我们可以让window10双屏显示&#xff0c;而且win10系统双屏显示设置步骤并不困难&#xff0c;下面小编就为大家演…

Linux vi 双屏显示,如何设置双屏显示器

大家好&#xff0c;我是时间财富网智能客服时间君&#xff0c;上述问题将由我为大家进行解答。 以电脑为例&#xff0c;其设置双屏显示器的方法是&#xff1a; 1、首先要准备好必要的硬件设备&#xff0c;主机一台&#xff0c;显示器两个&#xff0c;vga线三根&#xff0c;分屏…

深入浅出实现Electron判断屏幕当前是否是双屏显示?

如果在win10中设置双屏显示如下配置: 开启了双屏后,我们可以通过以下两种方式实现双屏显示的判断: 使用nodejs的child_process方式实现信息读取。// 方式一: 使用 wmic 以及 exec读取显示器序列号数量判断是否多显示器const cmdStr = "WMIC /NameSpace:\\\\Root\\WMI …

双屏计算机主机是什么,双屏显示器怎么连接(台式机连接步骤教程) - 双屏显示器怎么设置_双屏显示器怎么连接_双屏显示器有什么用(电脑)...

双屏显示器怎么连接(台式机连接步骤教程) 1、根据你的电脑显卡的双接口情况连接好二台显示器。如接口不支持时将显卡的接口用转换接头进行转换后再连接。电脑开机如下图所示&#xff0c;你的显示器是不亮的。 2、硬件正确连接后&#xff0c;现在马上升级你的显卡程序(因大部分电…

java 双屏显示_程序员,你双屏了吗?

前一段时间&#xff0c;因为做自动化测试框架&#xff0c;调试的时候需要三个程序(Delphi/自动化测试客户端/测试目标系统)同时运行&#xff0c;非常不方便&#xff0c;因此申请一台可以双屏的系统。 刚开始以为这是一个很简单的事情&#xff0c;只需要加一个显卡&#xff0c;然…

安卓系统双屏异显_Android10模拟器上调试双屏异显

Android SDK 提供了Display类,实现在主屏幕之外的扩展屏幕上显示不同于主屏幕的UI,而扩展屏幕上的UI显示,实质上是显示了一个系统级别的Dialog,我们可以将自已的View加入到此Dialog中进行显示。 扩展屏可以有一个或超过一个,实际的应用中需要底层驱动的支持。在官方的模拟…

linux设置双屏拼接_Linux设置双屏显示,基于x环境

Linux用xrandr设置双屏显示 发布时间&#xff1a;2016年1月22日 22:25作者&#xff1a;杨仕航 分类标签&#xff1a; Linux&服务器阅读(8441)评论(0) 前段时间把笔记本改装成双屏小主机之后&#xff0c;涉及到显示输出问题。由于我的系统是CentOS Linux系统&#xff0c;对视…

win7 双屏 双工具栏_win7系统设置双屏的操作方法

电脑系统设置双屏的问题每个人都有不同的操作门路&#xff0c;小编在大量的搜集设置双屏的解法之后&#xff0c;总结出来一套比较简单的设置双屏的处理措施&#xff0c;就是按照1.将电脑的VGA接口和HDMI接口(也可以是DVI接口)各连接一个显示器&#xff0c;连接好后将两个显示器…