一、环境搭建

1、安装nodejs

#下载地址
https://nodejs.org/dist/v20.9.0/node-v20.9.0-x64.msi

2、配置环境变量

上面下载完安装包后自行安装,安装完成后安装下图操作添加环境变量

前端开发学习 (一) 搭建Vue基础环境_vue.js

#查看版本
node --version
v20.9.0

#
npm --version
10.1.0

 3、配置npm加速源

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

上面这个适用于我们自己电脑上公网拉包,还有一种情况是在公司内部使用nexus搭建的私有仓库拉包,配置如下

npm config set registry http:/xxx/nexus3/repository/npm-public

4、npm安装vue/cli

npm install -g @vue/cli@latest

#这里安装vue/cli 而不是vue是因为我们后续主要是依赖修改.vue文件来实现项目的
#而不是在html文件中的js部分引入vue.js文件
#如果非要在html中使用,需要安装vue,这样会在本地生成vue.js文件
#不过最好还是用vue/cli,在外网区域可以直接通过url引入vue.js在html中编辑
#<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>

5、创建vue项目

#创建项目 (default 3 回车)
vue create my-vue-app    #第一次创建要下很多东西有点慢

返回

(venv) PS C:\Users\Administrator\IdeaProjects\test> vue create my-vue-app


Vue CLI v5.0.8
? Please pick a preset: Default ([Vue 3] babel, eslint) 


Vue CLI v5.0.8
✨  Creating project in C:\Users\Administrator\IdeaProjects\test\my-vue-app.                                                                                                        
⚙️  Installing CLI plugins. This might take a while...


added 866 packages in 3m
�🚀  Invoking generators...                                                                                                                                                        
�📦  Installing additional dependencies...                                                                                                                                         


added 103 packages in 2m
⚓  Running completion hooks... 

�📄  Generating README.md..
 
�📦  Successfully created project my-vue-app.                                                                                                                                      
�👉  Get started with the following commands:                                                                                                                                      

 $ cd my-vue-app
 $ npm run serve

6、项目目录结构分析

前端开发学习 (一) 搭建Vue基础环境_Vue_02

目录或文件名称

用途

node_modules

项目依赖的模块,当需要拉取其他模板时需要切换到该目录同级目录下拉取

public

该目录是存放静态文件的,在打包的时候直接复制到项目中。在项目根目录中放置一个 index.html 文件,作为整个应用的入口文件

src

项目主目录,所有vue、js、css文件都放在这里,包含如下文件


src/main.js        应用的入口文件,Vue 实例的创建和根组件的挂载都会在这里进行。

src/components  存放 Vue 组件文件的目录。

src/assets         存放静态资源文件的目录,如图片、字体等。

src/views           存放路由组件文件的目录,通常用于组织不同路由对应的页面组件。

src/api              存放与后端 API 交互的文件,比如封装了 Axios 或其他 HTTP 客户端的 API 调用文件。

src/store           存放 Vuex 相关的文件,用于状态管理。

src/router         存放 Vue Router 相关的文件,用于配置路由。

.gitignore

告诉 Git 哪些文件或目录不需要纳入版本控制。比如构建产物、临时文件、依赖库等通常不会纳入版本控制,通过 .gitignore 文件可以忽略它们

babel.config.js

配置 Babel 编译工具的配置文件。Babel 是用于将现代 JavaScript 代码转换为向后兼容的 JavaScript 代码的工具。在 babel.config.js 中,可以配置转译规则、插件、预设等,以便使用最新的 JavaScript 特性而不用担心兼容性问题

package.json

Node.js 项目的配置文件,它定义了项目的元信息(如名称、版本、作者等)以及项目依赖的 Node.js 模块。此外,它也包含了项目的脚本命令,比如启动开发服务器、构建项目等。通常可以通过npm install命令根据package.json文件中的依赖自动安装项目所需的依赖

package-lock.json

锁定安装时的精确版本的依赖关系的。它会记录下当前状态下所有依赖包的精确版本号,以确保在不同的机器上安装相同的依赖包时得到的结果是一致的

7、启动vue项目

cd my-vue-app
npm run serve

前端开发学习 (一) 搭建Vue基础环境_学习_03

8、访问测试

http://127.0.0.1:8080/

前端开发学习 (一) 搭建Vue基础环境_vue.js_04

上面的页面是我们默认vue项目的主页

9、 开启vue ui管理页面

#Vue3支持通过图形化界面来创建和管理项目。在DOS命令行窗口下操作
vue ui

访问

http://localhost:8001/project/select

前端开发学习 (一) 搭建Vue基础环境_html_05

10、构建项目

npm run build

返回

(venv) PS C:\Users\Administrator\IdeaProjects\test\my-vue-app> npm run build

> my-vue-app@0.1.0 build
> vue-cli-service build

All browser targets in the browserslist configuration have supported ES module. 
Therefore we don't build two separate bundles for differential loading.         


|  Building for production... 

 DONE  Compiled successfully in 8322ms                                                                                                                                      14:18:39

  File                                 Size                                                                 Gzipped

  dist\js\chunk-vendors.3e315568.js    74.62 KiB                                                            27.93 KiB
  dist\js\app.19846393.js              13.07 KiB                                                            8.41 KiB
  dist\css\app.2cf79ad6.css            0.33 KiB                                                             0.23 KiB

  Images and other types of assets omitted.
  Build at: 2023-11-15T06:18:39.453Z - Hash: 1216dad53f80cba6 - Time: 8322ms

 DONE  Build complete. The dist directory is ready to be deployed.
 INFO  Check out deployment instructions at https://cli.vuejs.org/guide/deployment.html

前端开发学习 (一) 搭建Vue基础环境_学习_06

可以看到public目录下的静态文件直接拷贝到项目中去,关于src在编译中的一个实现过程如下

1、JavaScript 代码编译 
       #任何使用了新的 JavaScript 特性或者语法的代码会被 Babel 转译成
       #向后兼容的版本,这样可以确保你的代码在更多的浏览器环境下能够运行

2、CSS 处理
       #通常会对 CSS 文件进行压缩、打包、前缀添加等处理,以优化样式文件的加载和运行性能

3、静态资源的处理
      #例如图片、字体等静态资源可能会被压缩、转码或者进行其他优化处理
      #以减小文件大小并提高加载速度。

4、打包和代码分割
      #构建过程会将项目中的代码打包成一个或多个生产环境可用的 JavaScript 文件
      #通常也会对代码进行分割以便实现按需加载。

5、环境变量注入
      #在构建过程中,可以根据环境变量注入不同的配置选项
      #比如开发环境和生产环境可以有不同的配置。

二、vue 理论知识

MVVM是一种前端架构模式,通过将视图、模型和视图模型分离,实现了数据与视图的自动同步和交互的双向绑定,而在Vue中,MVVM模式是将我们页面中处理消息的逻辑,比如调用后端api或者计算处理的逻辑,与视图页面显示进行分离,并通过ViewModel来协调二者之间的交互

前端开发学习 (一) 搭建Vue基础环境_vue.js_07

1、Model(模型)
    #表示应用程序的数据和业务逻辑,比如去访问后端api获取数据、处理数据、持久化等

2、View(视图)
    #代表应用程序的用户界面, 它通常由HTML和CSS构成
    #并与ViewModel进行绑定, 以反映数据的状态和变化

3、ViewModel(视图模型)
    #视图模型是连接 视图和模型 的中间人, 它通过数据绑定机制将视图与模型进行绑定
    #即视图中的元素可以直接与ViewModel中的属性和方法进行关联
    #ViewModel通常包含处理视图事件和逻辑、更新数据状态以及与后端API进行通信的操作

也就是说,模型是处理数据的,视图是显示页面的,视图模型是将数据绑定到页面上实现动态变更的

三、vue系统指令

关于数据处理(js) 和视图(html) 其实我们前面学过了很多了,而下面主要做的是怎么通过视图模型将他们两者之间做一个绑定

1、字符绑定--插值表达式

在数据绑定中存在着一种叫插值表达式(Mustache)的方法,他是通过在html中定义两个花括号实现,我们说这俩花括号后面统一称为Mustache 标签

span>Message: {{ msg }}</span>

这里Mustache标签内定义的msg 是用于我们后续在定义视图模型时声明的一个变量,他会根据我们模型视图中的data 中msg的变更而变更,我们下面做一个演示

my-vue-app/public/index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
</head>

<body>
<div id="div1">
  <span>Message: {{ msg }}</span>
</div>
</body>

<script>

  var myVue = new Vue({
    el: '#div1',      
    data: {         
      msg: 'smyhvae'   

    }
  });
</script>
</html>

配置说明

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <!--1、导入Vue的包-->
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
</head>

<body>
<!--这里我们在主体区域body中定义了一个div, 这个div中的数据是会显示在页面上的
而显示在页面中的区域,就是MVVM前端框架模式中的 View 视图区域-->
<div id="div1">
  <span>Message: {{ msg }}</span>
</div>
</body>

<script>
  //2、创建一个vue实例,这个new Vue创建的实例也就是我们上面说的View Module(视图模型)
  var myVue = new Vue({
    el: '#div1',      //这里设置了el: #div1 表示由vue对象去接管上面的div1区域了
                      //后面我们的数据就是往这个div1区域写入

    data: {         //data就是MVVM中的 module,就是我们数据真正处理的位置

      msg: 'smyhvae'   //在模型中进行了数据处理,我们给msg变量设置了一个smyhvae的值
                       //在页面打开后这个组件会将smyhvae值写入给msg
                       //而上面{{msg}} 只是将变量值展示出来

    }
  });
</script>
</html>

前端开发学习 (一) 搭建Vue基础环境_学习_08

通过上面的方法我们将视图中的值和模型中的值,通过视图模型绑定到了一起,当我们修改模型中的值时,数据会自动同步到页面, 我们按下F12 在控制台输入下面的语句

myVue.$data.msg = 'haha'

前端开发学习 (一) 搭建Vue基础环境_前端_09

2、v-cloak保持和元素关联

     v-cloak指令和CSS 规则一起用的时候,能够解决差值表达式闪烁的问题,通常是和插值表达式相辅相成的,即, 可以隐藏未编译的标签直到实例准备完毕


       比如说第一个例子中的msg 变量,他是页面打开后慢慢赋值后加载出来的,在网速很慢的情况下,一开始会直接显示{{msg}}这个内容,等网络加载完成了,才会显示smyhave,针对这个问题可以通过v-cloak隐藏{{name}}这个内容,当加载完毕后,再显示出来

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>

  <style>
    /*2、在样式表里设置:只要是有 v-cloak 属性的标签,我都让它隐藏。
    直到 Vue实例化完毕以后,v-cloak 会自动消失,那么对应的css样式就会失去作用
    最终将span中的内容呈现给用户 */
    [v-cloak] {
      display: none;
    }
  </style>
</head>

<body>
<div id="div1">
  <!-- 1、给 span 标签添加 v-cloak 属性 -->
  <span v-cloak>Message: {{ msg }}</span>
</div>
</body>

<script>

  var myVue = new Vue({
    el: '#div1',
    data: {
      msg: 'smyhvae'

    }
  });
</script>
</html>

 3、v-text 变量渲染到指定元素

<body>
<div id="div1">
  <!-- 直接以元素形式写入到span中,以数值形式展示出来 -->
  <span v-text="msg"></span>
</div>
</body>

前端开发学习 (一) 搭建Vue基础环境_Vue_10

关于差值表达式和v-text的区别 ,看上去两者的效果是一致的,但还有些许不同,两者配置如下

<!-- 差值表达式 -->
  <span>content:{{name}}</span>

  <!-- v-text -->
  <span v-text="name">/span>

案例说明

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
</head>

<body>
<div id="div1">

  <!-- 差值表达式 -->
  <p>content:++++++{{msg}}------</p>

  <!-- v-text -->
  <p v-text="msg">------++++++</p>
</div>
</body>

<script>

  var myVue = new Vue({
    el: '#div1',
    data: {
      msg: 'smyhvae'

    }
  });
</script>
</html>

前端开发学习 (一) 搭建Vue基础环境_前端_11

可以看到两者的区别如下:

1、v-test不存在插值表达式中闪烁的问题

2、插值表达式只会替换当前{{msg}}位置的值,不会修改范围内所有的值

3、而v-test则会将整个元素的内容清空,覆盖上新的内容

4、v-html解析html配置

v-test 是打印纯文本信息,而v-html则是会被解析成html元素,但使用v-html渲染数据可能会非常危险,因为它很容易导致 XSS(跨站脚本) 攻击,使用的时候请谨慎,能够使用{{}}或者v-text实现的不要使用v-html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
</head>

<body>
<div id="div1">
<!--  添加text和html的msg区分-->
  <p v-text="msg"></p>
  <p v-html="msg"></p>
</div>
</body>

<script>

  var myVue = new Vue({
    el: '#div1',
    data: {
      // 修改返回信息为html格式
      msg: '<h1>我是一个大大的h1标题</h1>'

    }
  });
</script>
</html>

 

前端开发学习 (一) 搭建Vue基础环境_Vue_12

5、v-bind属性绑定

前面的插值表达式如果说是绑定了内容和文本的关系,那么v-bind就是绑定了内容和元素的关系,当我们使用v-bind绑定元素的时候需要根据他的数据类型进行绑定,比如我们要绑定图片或者超链接等等都可以使用v-bind,举个例子

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
</head>

<body>
<div id="div1">
  <!--  添加text和html的msg区分-->
  <!-- value里的值只是简单的字符串 -->
  <input type="text" value="name">

  <!-- 加上 v-bind 之后,value里的值是 Vue 里的变量 -->
  <input type="text" v-bind:value="name">

  <!-- 超链接后面的path是 Vue 里面的变量 -->
  <a v-bind="{href:'http://www.baidu.com/'+path}">超链接</a>




</div>
</body>

<script>

  var myVue = new Vue({
    el: '#div1',
    data: {
      name: 'smyhvae',
      path: `2.html`,


    },
  });
</script>
</html>

三、练习

我们通过上面学习的方法,来做一个文本滚动的效果,思路如下

1、每次点击按钮后, 拿到msg字符串,然后调用字符串的`substring`来进行字符串的截取操作
    把第一个字符截取出来,放到最后一个位置即可,这就实现了滚动的效果。

2、为了实现文字自动连续滚动的效果,需要把步骤1中点击按钮的操作,放到定时器中去。

1、添加按键滚动效果

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
</head>

<body>
<div id="div1">
<!--  动态显示文本-->
  <p>{{msg}}</p>

<!--  添加按钮 当点击按钮时触发@click 指定的函数startMethod-->
  <input type="button" value="开始" @click="startMethod">




</div>
</body>

<script>

  var myVue = new Vue({
    el: '#div1',
    data: {
      // 添加要滚动更新的数据 赋值给msg
      msg: '怒发冲冠,凭阑处、潇潇雨歇。抬望眼,仰天长啸,壮怀激烈。三十功名尘与土,八千里路云和月',
    },
    //在data字段下面添加method  表示定义函数的区域
    methods: {
      //添加函数,
      startMethod: function () {
        //通过this获取调用函数的变量msg,通过substring获取字符串信息
        // (0,1) 表示索引从0到1,也就是第一个字符
        var start = this.msg.substring(0, 1);

        //substring(1) 是截取从第一个字符串开始后面的索引字符
        var end = this.msg.substring(1);

        //重新拼接得到新的字符串,并赋值给 this.msg
        this.msg = end + start;
      }
    }
  });
</script>
</html>

在上面我们实现了一个基本的文字滚动效果,但是如果我们不一直点击他,也不会存在滚动,我们这里给他加一个定时器,让他反复执行

2、添加定时器持续滚动

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
</head>

<body>
<div id="div1">
  <p>{{msg}}</p>
  <input type="button" value="开始" @click="startMethod">




</div>
</body>

<script>

  var myVue = new Vue({
    el: '#div1',
    data: {
      msg: '怒发冲冠,凭阑处、潇潇雨歇。抬望眼,仰天长啸,壮怀激烈。三十功名尘与土,八千里路云和月',
    },
    //在data字段下面添加method  表示定义函数的区域
    methods: {
      //添加函数,
      startMethod: function () {
        var _this = this; //定义一个存有当前上下文的变量
        //这是因为,在js中嵌套函数内部的 this 不能像我们第一个案例中那么用
        //在下面嵌套函数中的this不同于外部函数(startMethod) 的this上下文,这里通过外部函数this赋予给_this,
        //就可以在内部函数setInterval中使用访问外部函数(startMethod)的上下文了

        //添加嵌套函数--定时器 (当点击按钮时滚动字符串)
        setInterval(function () {
          var start = _this.msg.substring(0, 1);
          var end = _this.msg.substring(1);
          //这里我们赋值的是外部函数startMethod上下文中的msg变量,相当于直接修改了data中的msg变量
          //页面上显示的数据会根据这个变化实时变更
          _this.msg = end + start;

          console.log(_this.msg);
        }, 400); //每400毫秒触发一次定时器
      }
    }
  });
</script>
</html>

3、优化持续滚动代码

上面的代码中,我们发现,如果在定时器中直接使用this,这个this指向的是window。为了解决这个问题,我们是通过_this来解决了这个问题,另外,我们还可以利用箭头函数来解决this指向的问题,因为箭头函数总的this指向,会继承外层函数的this指向

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
</head>

<body>
<div id="div1">
  <p>{{msg}}</p>
  <input type="button" value="开始" @click="startMethod">




</div>
</body>

<script>

  var myVue = new Vue({
    el: '#div1',
    data: {
      msg: '怒发冲冠,凭阑处、潇潇雨歇。抬望眼,仰天长啸,壮怀激烈。三十功名尘与土,八千里路云和月',
    },

    methods: {
      startMethod: function () {
        //( ) => { } 表示一个没有参数的箭头函数。箭头函数可以用于创建匿名函数
        //该函数没有自己的 this、arguments、super 或 new.target,它们继承了父级上下文的这些值。
        //具体到这段代码中,箭头函数被用作 setInterval 方法的回调函数
        // 使用箭头函数的好处是它会继承外部函数的 this 上下文,让内部函数中的 this 指向外部函数的 this
        setInterval(() => {
          var start = this.msg.substring(0, 1);
          var end = this.msg.substring(1);
          this.msg = end + start;
          console.log(this.msg);
        }, 400);
      },
    }
  });
</script>
</html>

4、添加滚动停止

我们还需要加一个按钮,点击按钮后,停止文字滚动,也就是停止定时器

并且把定时器的id放在全局的位置(放到data里)这样的话,开启定时器的方法和停止定时器的方法,都可以同时访问到这个定时器

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
</head>

<body>
<div id="div1">
  <p>{{msg}}</p>
  <input type="button" value="开始" @click="startMethod">

<!--  添加结束按钮-->
  <input type="button" value="结束" @click="stopMethod">



</div>
</body>

<script>

  var myVue = new Vue({
    el: '#div1',
    data: {
      msg: '怒发冲冠,凭阑处、潇潇雨歇。抬望眼,仰天长啸,壮怀激烈。三十功名尘与土,八千里路云和月',
      intervalId: null  //添加按钮变量
    },

    methods: {
      startMethod: function () {
        //将定时器函数封装到全局变量intervalId中, 后面方便交给结束函数使用
        //不论是setInterval(创建计时器) 和clearInterval(停止计时器) 都是js中的原生函数
        this.intervalId = setInterval(() => {

          var start = this.msg.substring(0, 1);
          var end = this.msg.substring(1);
          this.msg = end + start;
          console.log(this.msg);
        }, 400);
      },
      stopMethod: function () {
        //clearInterval 函数会将全局变量中的计时器停掉
        clearInterval(this.intervalId);
      }
    }
  });
</script>
</html>

5、自检定时器是否唯一

我们上面的能完成基本的文本滚动了, 但是存在一个问题,如果我们一开始就是连续点几次开始后,就无法通过结束去关闭滚动效果了,因为他生成了多个定时器,这里需要改进

1、我们需要在开启定时器之前先做一个判断, 如果定时器不为null那就不继续往下执行了
    (即不再开启新的定时器)防止开启了多个定时器

2、停止定时器的时候, 虽然定时器停止了但定时器并不为 null
   因此最后我们还需要手动将定时器设置为null才能恢复到最初始的状态。
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
</head>

<body>
<div id="div1">
  <p>{{msg}}</p>
  <input type="button" value="开始" @click="startMethod">

<!--  添加结束按钮-->
  <input type="button" value="结束" @click="stopMethod">



</div>
</body>

<script>

  var myVue = new Vue({
    el: '#div1',
    data: {
      msg: '怒发冲冠,凭阑处、潇潇雨歇。抬望眼,仰天长啸,壮怀激烈。三十功名尘与土,八千里路云和月',
      intervalId: null  //添加按钮变量
    },

    methods: {
      startMethod: function () {

        //判断按钮值是否为null
        if (this.intervalId != null) return;


        this.intervalId = setInterval(() => {
          var start = this.msg.substring(0, 1);
          var end = this.msg.substring(1);
          this.msg = end + start;
          console.log(this.msg);
        }, 400);
      },
      stopMethod: function () {
        clearInterval(this.intervalId);

        //停止后重新设置变量为null
        this.intervalId = null;
      }
    }
  });
</script>
</html>