Vue2(Ⅲ)
4、 脚手架 Vue CLI
4.1、脚手架是什么
安装:
第一步:全局安装npm install -g @vue/cli
(如果安装不了,可以尝试以管理员身份运行cmd)
第二步:配置环境变量(配置 node_global \ node_modules 的环境变量)
第三步:测试是否安装成功vue --version
(需要先重启cmd)
Vue脚手架(Vue CLI:Vue Command Line Interface)是一种工具,它是一个官方提供的用于快速搭建Vue.js项目的 **命令行工具** 。Vue脚手架可以帮助开发者 **创建、管理和构建** Vue.js项目,提供了一系列的命令和选项, **简化** 了项目的 **配置和管理过程**
4.2、脚手架的主要功能
① 项目创建:可以使用Vue CLI快速初始化一个Vue.js项目,提供了一些预设模板供选择,包括基本模板、Webpack模板、Vue Router模板等
② 项目配置:Vue CLI提供了项目的配置文件,可以在项目创建之后根据需要对项目进行配置,例如配置Babel、ESLint、PostCSS等
③ 开发服务器:Vue CLI内置了开发服务器,可以在开发过程中实时预览项目,并支持热重载,使得开发过程更加高效
④ 构建项目:Vue CLI提供了项目的打包构建功能,可以将项目打包成生产环境所需的静态文件,包括压缩、优化等处理
⑤ 插件系统:Vue CLI支持插件系统,可以通过插件扩展Vue项目的功能,例如添加TypeScript支持、添加PWA支持等
总的来说,Vue脚手架帮助开发者快速搭建Vue.js项目,并提供了一些开发过程中常用的功能和工具,使得开发过程更加简单、高效
4.3、创建脚手架项目
第一步(创建项目):进入到项目文件夹想要存放的位置,例如我要存放在 D:\ Project \ VsCode 下,然后使用 vue create 项目名 进行创建
1:
cd D:\Project\VsCode
2:
vue create vuecli_test
接下来就能看到下面的对话,我们需要按一下键盘上的 ”↓“ 键,切换到 Vue2 (如果想要写Vue3的代码就选Vue3),然后回车
Tip:如果下载到一半,发现太慢了、出现各种错误、忘记配置镜像,可以进行以下操作
1、先把下载一半的文件删了
2、清理下载缓存:npm cache clean --force
3、更换国内镜像:
npm config set registry https://registry.npmjs.org
4、重新创建:
vue create vuecli_test
拓展
1、Babel:Babel是一个JavaScript编译器,主要用于将高版本的JavaScript代码转换成向后兼容的低版本代码,以确保代码可以在不同浏览器和环境中运行(例如可以将 ES6 转成 ES5)
2、ESLint:ESLint是一个JavaScript静态代码分析工具,可以根据预定义的规则或者自定义的规则对代码进行静态分析并给出警告或错误信息,它可以帮助开发者发现代码中的潜在问题,以确保代码格式的一致性、提高代码质量和可维护性
如果在cmd中看到如下信息,说明项目创建成功(注意两行蓝字)
第二步(开启服务器):接下来就是在Vue.js项目中启动开发服务器
进入到创建的项目中:
cd D:\Project\VsCode\vuecli_test
执行:
npm run serve
如果在cmd中看到如下信息,说明服务器开启成功(注意两行蓝字),Local是指自己在浏览器中访问服务器的地址,NetWork是指同个局域网下的其他主机想要访问该服务器的地址
第三步(访问服务器):在浏览器中输入http://localhost:8080/,如果看到下面的页面,说明可以成功访问到服务器(打开vue devtool可以看到这个项目Welcome to Your Vue.js App是HelloWorld组件的数据 – 自带的)
4.4、脚手架的文件结构
打开刚创建的额脚手架项目,可以看到如下的文件结构(可能版本不同的脚手架创建出来有细微、无伤大雅的出入)
vuecli_test/ # 项目根目录
├── node_modules/ # 依赖的npm包目录
├── public/ # 公共文件夹
│ ├── favicon.ico # 网站图标(VUE的logo)
│ └── index.html # 项目的主页面
├── src/ # 源代码目录
│ ├── assets/ # 静态资源目录,如图片、字体等
│ ├── components/ # 组件目录,存放Vue组件文件
│ ├── views/ # 视图目录,存放页面级组件文件
│ ├── App.vue # 根组件文件
│ └── main.js # 项目入口文件
├── .gitignore # Git忽略文件配置
├── babel.config.js # Babel的配置文件
├── jsconfig.json # JavaScript的配置文件
├── package-lock.json # 锁定npm包版本的文件
├── package.json # 项目的npm配置文件
├── README.md # 项目的说明文档
└── vue.config.js # Vue的配置文件
4.4.1 index.html代码分析
<!DOCTYPEhtml><htmllang=""><head><metacharset="utf-8"><!-- 针对IE浏览器的一个特殊配置,含义是让IE浏览器以最高的渲染级别渲染页面 --><metahttp-equiv="X-UA-Compatible"content="IE=edge"><!-- 开启移动端的理想视口 --><metaname="viewport"content="width=device-width,initial-scale=1.0"><!-- 配置页签的图标 --><linkrel="icon"href="<%= BASE_URL %>favicon.ico"><!-- 配置网页标签 其值就是去package.json中找name的值 --><title><%= htmlWebpackPlugin.options.title %></title></head><body><!-- 如果浏览器不支持js的话页面上就会出现这个提示 --><noscript><strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><!-- 容器 --><divid="app"></div></body></html>
4.4.2 main.js代码分析
首先我们可以看到main.js文件的初始化代码如下,与之前不同的是出现了render函数,那么它的作用是什么呢
// 从node_modules文件夹中导入vue库import Vue from'vue'import App from'./App.vue'
Vue.config.productionTip =falsenewVue({
el:'#app',// render函数render:h=>h(App),})
按我们之前的写法,应该将代码改为如下这样
// 从node_modules文件夹中导入vue库import Vue from'vue'import App from'./App.vue'
Vue.config.productionTip =falsenewVue({
el:'#app',// render函数// render: h => h(App),template:'<App></App>',comments:{
App}})
然而当我们运行时,会发现在浏览器的控制台中有如下报错
[Vue warn]: You are using the runtime-only build of Vue where the template compiler is not available. Either pre-compile the templates into render functions, or use the compiler-included build.
意思是“您正在使用一个运行时版本的vue(残缺的vue),您没有模板解析器,要么将需要编译的模板交给render函数、要么就使用带有模板解析器的vue(完整的vue)“,即脚手架中的vue其实是阉割版的、功能不全的vue
Q:对于模块化的语法 import Vue from ‘vue’ 是如何找到相应的js文件的呢
1、从 node_modules 文件夹中找到 vue 库
2、打开 vue 库中的 package.json 文件,这个文件会告诉我们这个库的一些相关配置,我们可以看到其中有一个配置是 “module”: “dist/vue.runtime.esm.js” ,即 vue/dist/vue.runtime.esm.js 这个文件将会作为我访问这个库的入口文件,因此我就不需要写 ”from node_modules/vue/dist/vue.runtime.esm.js“ ,因为 ‘node_modules/’ 是默认的, 'dist/vue.runtime.esm.js’是指明的库的package.json中指定的,因此只需要写from 'vue’即可
那么我们首先尝试一下第二种方法:引入完整版的vue,完整的 vue.js 存放的路径是 node_modules/vue/dist/vue.js ,因此引入的第一种方法是写全路径: import Vue from ‘vue/dist/vue.js’ ,第二种引入方式是修改package.json的module配置,现编写代码如下,再运行一下就发现模板可以成功解析了
// import Vue from 'vue'import Vue from'vue/dist/vue'//完整版的vueimport App from'./App.vue'
Vue.config.productionTip =falsenewVue({
el:'#app',// render: h => h(App),template:'<h1>你好</h1>',//现可以解析模板了comments:{
App
}})
总结:残缺版的vue不能为vue实例配置template,完整的vue才能为vue实例配置template
然而使用阉割版的 vue 其实还是挺有作用的,完整版的vue包括核心+模板解析器(大概占1/3,虽然大概就是100+KB…),而阉割版的vue只包括核心部分,当项目完成用webpack进行打包之后,.vue文件已经会被翻译成.js文件了,因此不再需要vue的模板解析器,如果将模板解析器打包到最终的项目中,是十分不合适的(毕竟最终的项目肯定越小越好),vue的模板解析器是给我们开发的时候使用的,为此我们有必要学习第一种方法:使用render函数
render函数(渲染函数)作为一个函数,接受一个参数,代表Vue的 createElement 函数。这个 render 函数通过调用 createElement 函数来创建虚拟DOM,并将真实DOM渲染到页面上,现我们编写如下代码,可以看到页面上将我们想要创建的标签显示出来了
import Vue from'vue'// import App from './App.vue'
Vue.config.productionTip =falsenewVue({
el:'#app',render(createElement){
// render的参数代表createElement函数,因此我们可以干脆把它命名为createElement// return createElement('标签名','内容')即是在页面上创建什么样的标签returncreateElement('h1','my name is Niki')}})
然而这样写跟 render: h => h(App) 这种写法还是长得有点区别的,但实际上是一样的,我们来看一下如何将render函数进行简写
import Vue from"vue";import App from"./App.vue";
Vue.config.productionTip =false;newVue({
el:"#app",// 1 原始// render(createElement){
// return createElement("h1", "my name is Niki");// }// 2 由于不需要使用到箭头函数,因此可以写成箭头函数的形式// render:(createElement)=>{
// return createElement("h1", "my name is Niki");// }// 3 由于只有一条返回语句,因此可以将大括号和return去掉,又由于参数只有一个,因此可以将括号去掉// render:createElement=>createElement("h1", "my name is Niki")// 4 还可以将render的参数写的简单一点,反正它代表的是createElement函数,于是简写为h// render: h => h("h1", "my name is Niki")// 5 createElement函数可以接收(标签,标签体),也可以接收(组件),因此有了最原始的的那种写法render:h=>h(App),});
经过上面的一步步变化,便可以得到render函数的简写方式了
4.5、脚手架默认配置
脚手架的配置依托webpack,因此理应在我们创建的项目中会有webpack.config.js文件,然而脚手架将 webpack 的相关配置给隐藏起来了,如果想要看具体的 webpack 配置,可以执行
vue inspect > output.js
命令,这个命令是用于将 webpack 的配置整理成一个output.js文件给我们进行查看
Tip
1、如果在VSCode的终端执行时报错,可以看看自己选择的终端是不是cmd的,如果是power shell的话切换成cmd即可
2、打开output,js文件会发现报错,因为webpack是一个对象,在js文件中总不能直接写一个对象吧,因此可以在对象前加一个 const config = 或者 export default 让它不报错
3、output,js的内容只是webpack配置的副本,只是原来的配置隐藏了于是我们把配置输出到这个文件中给我们自己看的,所以在这个文件中修改配置是没有用的
那么如何对默认的配置进行修改呢,在 参考文档 中指出我们可以在 vue.config,js 文件中进行个性化的配置,在这个文件里配置之后,将会与webpack.config.js中的配置进行一个合并 / 重写,从而达到个性化配置的目的
引用自文档:vue.config.js 是一个可选的配置文件,如果项目中存在这个文件(和 package.json 同级),那么它会被 @vue/cli-service 自动加载。你也可以使用 package.json 中的 vue 字段,但是注意这种写法需要你严格遵照 JSON 的格式来写
现打开 vue.config,js 文件,我们可以看到其使用的暴露方式是 module.exports ,这是 common.js 的语法,而不是 ES6 的语法,这是因为这个文件到时候是要传递给webpack进行处理的,而webpack又是基于node.js的,而node.js采用的模块化是common.js,因此这里要使用common.js的暴露语法
const{
defineConfig }=require('@vue/cli-service')
module.exports =defineConfig({
transpileDependencies:true})
例如现在想要修改项目的入口文件,我们可以查阅参考文档中的 pages 配置项并修改 vue.config,js 文件如下
const{
defineConfig }=require('@vue/cli-service')
module.exports =defineConfig({
transpileDependencies:true,pages:{
index:{
//入口文件 根目录下的src下的niki.jsentry:'src/niki.js'}}});
然后再将我们的入口文件从main.js改成niki.js,最后启动项目,可以发现运行成功了
Tip
1、如果在启动项目的过程中修改了 vue.config,js 文件,那么需要重启项目
再例如我们在现有的基础上编写代码的时候会发现,如果在代码中声明了一个变量、组件,但没使用的话会报错,虽然这理论上是无伤大雅的,这是因为脚手架开启了语法检查,不允许这种情况的出现,因此在开发的过程中如果想要允许这种情况的出现,我们可以在 vue.config,js 文件中配置如下,重启项目,我们会发现如果在代码中声明一些没有用到的变量、函数、组件的时候也不会出现烦人的报错了
const{
defineConfig }=require('@vue/cli-service')
module.exports =defineConfig({
transpileDependencies:true,pages:{
index:{
//入口文件 根目录下的src下的niki.jsentry:'src/niki.js'}},lintOnSave:false});
4.6、在控制台输出vm
当我们运行了项目之后,不同于以往,如果想要在控制台能够访问我们的vue实例,需要修改main.js文件如下
import Vue from"vue";import App from"./App.vue";
Vue.config.productionTip =false;const vm =newVue({
el:"#app",render:(h)=>h(App),});//将vm挂载到全局作用域中
window.vm = vm;
5、进阶篇
说明:接下来只会展示核心代码,大家可以依样画葫芦给搬到项目中去运行,完整代码及文件结构可以看 Panyue-genkiyo的github笔记
5.1、ref 标签属性 – 标记标识
ref 属性可以在 Vue 组件中**访问 DOM 元素或组件实例**。例如,你可以在模板中使用 ref 给 DOM 元素添加标识,然后在 Vue 实例中通过 $refs 属性来访问该元素
概要描述标识在标签中使用 ref=“xxx” 来标记访问在组件中使用 this.$refs.xxx 来访问
<!-- Test.vue --><template><div><!-- 使用 ref 属性做标记 --><div><inputtype="text"ref="acc"/></div><div><inputtype="password"ref="pwd"/></div><button@click="submit">submit</button></div></template><script>exportdefault{
methods:{
submit(){
// 通过 $refs 访问 inputField 元素,并将焦点设置到该元素上
console.log("账号:",this.$refs.acc.value);
console.log("密码:",this.$refs.pwd.value);},},};</script>
5.2、props 配置 – 父传子接
props 是用于在父组件和子组件之间传递数据的机制。它允许**父组件将数据传递给子组件**,并在子组件中使用这些数据
概要描述父传递在标签中使用 数据名=“xxx” / : 数据名=“xxx” 进行传递
不带冒号的传递的是纯字符串;带冒号的传递的是表达式
如果是想传递表达式、数字、函数等需要携带冒号子接收为子组件配置props进行接收,一共有三种方式子使用props的数据可以像data中的数据一样访问,即 this.xxx子组件中props和data存在同名属性控制台会报错,但可以正常使用,并且以props的为准props属性命名注意不能是vue底层已征用的属性名(比如key, ref等等)修改props数据可以正常修改,但是控制台会报错解决修改props数据会报错的问题可以将props数据存储在data中的一个属性内,以后使用data中的数据来代替使用props的数据,这样修改的时候就不会报错了
<!-- App.vue --><template><div><!-- age需要加个冒号,这样12才不会以字符串的形式传过去 --><Studentname="niki"gender="男":age="12"msg="vue学习中..."msg1="1===1":msg2="1===1"/></div></template><script>import Student from"@/components/Student";exportdefault{
name:"App",data(){
return{
};},components:{
Student,},};</script>
<!-- Student.vue --><template><divclass="demo"><!-- props与data有同名属性,以props为准,同时控制台会报错 --><h1>{
{ msg }}</h1><!-- 应该尽量避免修改props的数据,要修改的话,将该数据传给一个data属性,然后来操纵这个data属性 --><h2>姓名:{
{ myName }}</h2><h2>年龄: {
{ age }}</h2><h2>性别: {
{ gender }}</h2><button@click="updateName">修改名字</button><h2>msg1: {
{ msg1 }}</h2><h2>msg2: {
{ msg2 }}</h2></div></template><script>exportdefault{
name:"Student",data(){
return{
msg:'ABC',myName:this.name
}},methods:{
updateName(){
this.myName ='HYH';}},// 1、//简单声明接收// props: ['name', 'gender', 'age']//// 2、限制props中属性的类型 类型错误了会提示错误信息// props: {
// name: String,// gender: String,// age: Number// }//// 3、接收时不仅限制类型还加上默认值的指定并指定它的必须性props:{
name:{
type: String,//类型required:true//必要的},age:{
type: Number,default:99//默认值},gender:{
type: String,required:true},msg:{
type: String,require:false},msg1:{
type: String,require:false},msg2:{
type: Boolean,require:false}}}</script>
5.3、mixins 配置 – 组件共享
mixin 是一种 Vue 中的特性,它允许你在多个**组件之间共享**可复用的功能。mixin 本质上是一个普通的 JavaScript 对象,其中包含了一组组件选项(如 data、methods、computed、created 等),这些选项将会被合并到使用了 mixin 的组件中
概要描述定义一个 mixin 就是一个js对象,配置跟组件的配置差不多,将多个 mixin 定义在 mixin.js 中使用将 mixin 传入组件的 mixins 配置中mixin的数据与组件定义时data的数据同名采用组件定义时data的数据mixin的方法与组件定义时methods的方法同名采用组件定义时methods的方法组件定义时使用的钩子在mixin中也有使用都会调用,不过mixin中的钩子先执行
// mixin.jsexportconst mixin ={
methods:{
showComponentName(){
alert("这是"+this.$options.name +"组件");},},mounted(){
console.log(this.$options.name +"组件已挂载");},};exportconst shareData ={
data(){
return{
x:100,};},methods:{
showx(){
alert(this.x);},},};
<!-- App.vue --><template><div><Student/><hr/><School/></div></template><script>import Student from"@/components/Student";import School from"@/components/School";exportdefault{
name:"App",components:{
School,
Student,},}</script>
<!-- Student.vue --><template><div><h1>学生信息</h1><h3>name:{
{ name }}</h3><h3>gender:{
{ sex }}</h3><button@click="showComponentName">点我</button><button@click="showx">看看我的x是几</button></div></template><script>import{
mixin, shareData }from"@/mixin";exportdefault{
name:"Student",data(){
console.log(this);return{
name:"Niki",sex:"male",x:666,//如果混合中配置了与data(或者配置了相同的methods)相同的属性值,则以你的配置的属性为主(而不以mixin为主)};},mounted(){
console.log("自己的mounted比混入的mounted快");//但对于生命周期钩子是都会保存的(混合的钩子比你配置的钩子先跑)}
版权归原作者 贺一航【Niki】 所有, 如有侵权,请联系我们删除。