DC's blog DC's blog
首页
  • 计算机基础
  • linux基础
  • mysql
  • git
  • 数据结构与算法
  • axure
  • english
  • docker
  • opp
  • oop
  • 网络并发编程
  • 不基础的py基础
  • 设计模式
  • html
  • css
  • javascript
  • jquery
  • UI
  • 第一次学vue
  • 第二次学vue
  • Django
  • drf
  • drf_re
  • 温故知新
  • flask
  • 前后端不分离

    • BBS
    • 订单系统
    • CRM
  • 前后端部分分离

    • pear-admin-flask
    • pear-admin-django
  • 前后端分离

    • 供应链系统
  • 理论基础
  • py数据分析包
  • 机器学习
  • 深度学习
  • 华中科大的网课
  • cursor
  • deepseek
  • 杂文
  • 罗老师语录
  • 关于我

    • me
  • 分类
  • 归档
GitHub (opens new window)

DC

愿我一生欢喜,不为世俗所及.
首页
  • 计算机基础
  • linux基础
  • mysql
  • git
  • 数据结构与算法
  • axure
  • english
  • docker
  • opp
  • oop
  • 网络并发编程
  • 不基础的py基础
  • 设计模式
  • html
  • css
  • javascript
  • jquery
  • UI
  • 第一次学vue
  • 第二次学vue
  • Django
  • drf
  • drf_re
  • 温故知新
  • flask
  • 前后端不分离

    • BBS
    • 订单系统
    • CRM
  • 前后端部分分离

    • pear-admin-flask
    • pear-admin-django
  • 前后端分离

    • 供应链系统
  • 理论基础
  • py数据分析包
  • 机器学习
  • 深度学习
  • 华中科大的网课
  • cursor
  • deepseek
  • 杂文
  • 罗老师语录
  • 关于我

    • me
  • 分类
  • 归档
GitHub (opens new window)
  • html

  • css

  • javascript

  • jquery

  • UI库

  • 第一次学vue

    • 基础语法(1)
    • 基础语法(2)
    • Vue生命期钩子
    • 基础语法(3)
    • Vue-cli
      • vue-cli
        • 搭建nodejs环境
        • 安装vue-cli
        • 创建vue项目
        • 方式一 cmd里
        • 方式二 浏览器里
        • 运行vue项目
        • 终端运行命令
        • 绿箭头
      • Vue项目目录
      • 如何运作的?
        • main.js与index.html
        • 组件的三部分
      • vue项目中组件通信
        • 示例代码
        • 代码逻辑
        • 执行结果
        • props配置项
      • es6导入导出
      • mixin混入
        • 最初的代码
        • 使用混入
        • 全局注册
        • 局部注册
      • 插槽的使用
      • 存储数据
      • vue3的变化
        • 创建vue3的项目
        • webstorm里
        • 使用vite
        • 组合式API
        • 生命周期
        • toRefs
    • 插件的使用(1)
    • 插件的使用(2)
    • 总结
  • 第二次学vue

  • 前端
  • 第一次学vue
DC
2023-11-29
目录
vue-cli
搭建nodejs环境
安装vue-cli
创建vue项目
方式一 cmd里
方式二 浏览器里
运行vue项目
终端运行命令
绿箭头
Vue项目目录
如何运作的?
main.js与index.html
组件的三部分
vue项目中组件通信
示例代码
代码逻辑
执行结果
props配置项
es6导入导出
mixin混入
最初的代码
使用混入
全局注册
局部注册
插槽的使用
存储数据
vue3的变化
创建vue3的项目
webstorm里
使用vite
组合式API
生命周期
toRefs

Vue-cli

# vue-cli

vue-cli脚手架 - 可以帮助我们快速搭建出Vue项目.

注意: vue2中,都是使用vue-cli ; vue3中,可以使用vue-cli搭建,但官方更推荐使用vite来搭建,因为它更快更小巧.

# 搭建nodejs环境

Vue-cli依赖一门后端解释性语言nodejs, So, 需要先安装解释器!!

下载nodejs的解释器地址: https://nodejs.org/en/download (LTS长期支持的版本,Current最新版本 - 选LTS)
一路点击下一步,无需额外的操作.
"""
This package has installed:
	•	Node.js v18.18.0 to /usr/local/bin/node
	•	npm v9.8.1 to /usr/local/bin/npm
Make sure that /usr/local/bin is in your $PATH.
""" Node相当于python,npm相当于pip!!

dengchuan@MacBook-Air ~ % node -v
v18.18.0
dengchuan@MacBook-Air ~ % node
Welcome to Node.js v18.18.0.
Type ".help" for more information.
> console.log("Hello World!")
Hello World!
undefined
> .exit
dengchuan@MacBook-Air ~ % npm -v
9.8.1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

有些时候给npm或node命令升级后可能会导致node和npm版本不对应. 解决办法, 重新搭建node环境!!

该网址可查看nodejs版本相对应的node版本 -- https://nodejs.org/en/download/releases/
  
若想更新node.js的版本到最新,mac需要这么做:
1.先查看本机node.js版本: node -v
2.清除node.js的cache: sudo npm cache clean -f
3.安装 n 工具,这个工具是专门用来管理node.js版本的, 别怀疑这个工具的名字,是他是他就是他,他的名字就是"n"
	sudo npm install -g n
4.安装最新版本的node.js
	sudo n stable
5.再次查看本机的node.js版本:
	node -v
  
若想更新npm的版本到最新,mac需要这么做:
1. sudo npm install npm@latest -g
2. 为了提高速度,你可以这样做:
   npm config set registry https://registry.npm.taobao.org
   npm install -g cnpm --registry=https://registry.npm.taobao.org
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

image-20231013191337400

# 安装vue-cli

直接通过 npm install -g @vue/cli 来安装脚手架很慢, 因为要访问国外的资源.
我们可以使用淘宝镜像定制的cnpm来替代npm, 达到加速的效果!!

执行命令:
  sudo npm install -g cnpm --registry=https://registry.npm.taobao.org
  执行完后,在终端上就有两个命令可用于安装第三方模块啦! 1> npm 安装速度慢 2> cnpm 安装速度快,使用它!!
  
执行命令:
  sudo cnpm install -g @vue/cli
  执行完后,vue-cli脚手架就安装好啦! 安装完脚手架后,就会有个vue命令!!

  Ps:安装指定版本的脚手架 sudo npm install -g @vue/cli@5.0.8
     卸载 sudo npm uninstall -g @vue/cli
     查看全局安装哪些包 npm list -g

""" 该命令执行成功,则证明vue-cli脚手脚安装成功!
dengchuan@MacBook-Air ~ % vue -V
@vue/cli 5.0.8
"""
注: 若安装cnpm和vue脚手架出错,清除缓存后重新安装!清楚缓存的命令: npm cache clean --force
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 创建vue项目

后续我们开发项目用vue3!! 示例中是选择vue2作为示范的, 无伤大雅, vue2上所有的写法都能在vue3上完美运行成功.

# 方式一 cmd里

通过vue create命令创建vue项目. 示例中选择的是vue2,当然我们可以选vue3.

# ★ 注意,新建的项目会创建在当前路径下 ; 注意,加上sudo!!
dengchuan@MacBook-Air Desktop % sudo vue create myfirstvue
?  Your connection to the default npm registry seems to be slow.
   Use https://registry.npmmirror.com for faster installation? Yes

# 键盘上下键移动选第三个,自定义,安装什么自己决定!选中后敲回车.
Vue CLI v5.0.8
? Please pick a preset: 
  Default ([Vue 3] babel, eslint) 
  Default ([Vue 2] babel, eslint) 
❯ Manually select features 

# 上下键移动,按空格选中与取消选中. 这里,我们选Balel、Router、Vuex这三个第三方组件! 敲击回车到下一步.
# Balel  高版本es语法转化 - 在vue项目中可以写高版本的es语法,它会自动转化成es5的语法,来兼容一些不支持es高版本语法的浏览器!
# Router 路由
# Vuex   状态管理器,简单理解:就是一个存放变量的地方.但浏览器关闭的话,该变量就没啦!
# ★ Router和vuex是写vue项目必用的!!
Vue CLI v5.0.8
? Please pick a preset: Manually select features
? Check the features needed for your project: (Press <space> to select, <a> to toggle all, <i> to invert selection, and <enter> to proceed)
❯◉ Babel
 ◯ TypeScript
 ◯ Progressive Web App (PWA) Support
 ◉ Router
 ◉ Vuex
 ◯ CSS Pre-processors
 ◯ Linter / Formatter
 ◯ Unit Testing
 ◯ E2E Testing
 
 
# 选择vue的版本,学习为主,此处先选2.x的版本, 3.x与2.x其实差不了多少.
Vue CLI v5.0.8
? Please pick a preset: Manually select features
? Check the features needed for your project: Babel, Router, Vuex
? Choose a version of Vue.js that you want to start the project with (Use arrow keys)
  3.x 
❯ 2.x 

# 包管理文件选择package.json -- 它类比于 Django项目中的reqirement.txt
Vue CLI v5.0.8
? Please pick a preset: Manually select features
? Check the features needed for your project: Babel, Router, Vuex
? Choose a version of Vue.js that you want to start the project with 2.x
? Use history mode for router? (Requires proper server setup for index fallback in production) Yes
? Where do you prefer placing config for Babel, ESLint, etc.? 
  In dedicated config files 
❯ In package.json 

# 它在问你,这些配置要保存吗?保存后用于下一次创建新项目时使用. 选择No就行
Vue CLI v5.0.8
? Please pick a preset: Manually select features
? Check the features needed for your project: Babel, Router, Vuex
? Choose a version of Vue.js that you want to start the project with 2.x
? Use history mode for router? (Requires proper server setup for index fallback in production) Yes
? Where do you prefer placing config for Babel, ESLint, etc.? In package.json
? Save this as a preset for future projects? (y/N) N


# 展示下方的结果,表明vue项目创建成功!
Vue CLI v5.0.8
✨  Creating project in /Users/dengchuan/Desktop/myfirstvue.
🗃  Initializing git repository...
⚙️  Installing CLI plugins. This might take a while...

added 846 packages in 14s
🚀  Invoking generators...
📦  Installing additional dependencies...

added 7 packages in 2s
⚓  Running completion hooks...

📄  Generating README.md...

🎉  Successfully created project myfirstvue.
👉  Get started with the following commands:

 $ cd myfirstvue
 $ npm run serve
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# 方式二 浏览器里

还可以通过 vue ui 命令图形化界面里创建项目. 示例中选择的是vue2,当然我们可以选vue3.

vue ui # -- 图形化界面里创建
   - 选择创建项目的路径
   - 创建新项目
     - 包管理器选择npm (不选也行默认就是npm)
   - 选择手动, 手动配置项目
     - 选择功能/第三方模块
       Babel              它会将项目中ES6,ES7等新语法转成ES5的语法,实现对低版本浏览器语法的兼容
       Router             路由 
       VueX               状态管理器,简单理解:就是一个存放变量的地方.但浏览器关闭的话,该变量就没啦!
     - 版本选择2.x
   - 保存新预设,随便写个名字,下次创建vue项目时,选它,就有此次创建项目时的这些配置.
1
2
3
4
5
6
7
8
9
10
11

# 运行vue项目

项目创建好后, 用编译器打开项目!

# 终端运行命令

方式一: 在编译器终端里允许命令,记得加上sudo!!不然权限不够,编译会失败的.

dengchuan@MacBook-Air myfirstvue % sudo npm run serve

> myfirstvue@0.1.0 serve
> vue-cli-service serve

 INFO  Starting development server...

 DONE  Compiled successfully in 1936ms                                                                          

  App running at:
  - Local:   http://localhost:8080/ 
  - Network: http://192.168.31.208:8080/

  Note that the development build is not optimized.
  To create a production build, run npm run build.


● 方式二: pycharm里还可以配置此命令,点击个按钮,快速启动. 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 绿箭头

方式二: 进行如下配置. 在webstorm中点击绿箭头就能快速上运行项目!!

image-20231008164057663

注意, 图中有npm和node的路径, 应确保正确的.


# Vue项目目录

以后写代码,都在src文件夹下写,其它地方一般不动.

具体文件中每一行代码什么意思, 参考文档: https://www.jianshu.com/p/19a7774248c3

myfirstvue                         # -- 项目名
├── node_modules                   # -- 当前vue项目的所有的依赖,小文件很多,可以删掉! -- 类似于py的虚拟环境.
                                   #    它人拿到删除了该文件夹的项目,它人只需要执行 npm install 命令即可再次拥有该文件夹.
                                   #    会将 package.json 文件里的所有依赖都给安装上.
├── public                         # -- 共用资源
│   ├── favicon.ico                #    网址小图标
│   └── index.html                 #    项目入口页面/vue项目默认首页.
                                   #    单页面开发(整个网站就这一个index,页面的变化都是组件的替换 英文简称spa)
├── src                            # -- ★ 书写代码的地方
│   ├── assets                     # -- 网站的静态文件和资源
│       └── logo.png 
│   ├── components                 # -- 一堆小组件(给组件用的组件 非页面组件)
│       └── HelloWorld.vue         #    自定义的组件
│   ├── router                     # -- vue-router相关,安装了该功能自动生成此文件夹
│       └── index.js 
│   ├── store                      # -- vuex相关,安装了该功能自动生成此文件夹
│       └── index.js
│   ├── views                      # -- 一堆大组件(是页面组件)
│       └── AboutView.vue
│       └── HomeView.vue
│   ├── App.vue                    # -- !!! 根组件  
│   └── main.js                    # -- ★ 非常重要,是整个项目的入口. 等同于Django的manage.py
├── .gitignore                     # -- git忽略文件
├── babel.config.js                # -- 语法检查. 咋们不用管它.
├── jsconfig.json                  # -- 无需关注
├── package.json                   # -- ★ 超级重要,项目配置依赖.不能删!! 等同于Django项目中的reqirement.txt
                                   #    后期node_modules文件夹删除后,该json文件中的依赖可使用npm install重新安装
├── package-lock.json              # -- 锁定依赖包.不能删. 意味某个模块会依赖其他模块,它们的版本需要对应.
                                   #    若删了,重新安装该模块时,它依赖的模块会安装最新的.可能会出现问题.
├── README.md                      # -- 项目介绍
└── vue.config.js                  # -- vue项目的配置文件,等同于Django项目的settings.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

若打开的项目在编译器里只读, 为该vue项目添加权限即可!!

dengchuan@MacBook-Air Desktop % sudo chmod -R 777 myfirstvue 
1

一些补充

简单来说,vue项目创建好后,运行项目,根据vue-cli脚手架自动生成的代码,大抵可知:
App.vue根组件会关联到index.html ; 
App.vue根组件通过路由关联AboutView.vue和HomeView.vue这两个页面组件 ;
在HomeView.vue这个页面组件中导入了HelloWorld.vue这个小组件!!


在index.html中有这么两行代码,它的意思是,若浏览器禁用网站的js功能,那么就会显示这段文字.
意味着,vue项目的正常运行的前提是浏览器必须得允许js功能的执行!
<noscript>
  <strong>
    We're sorry but <%= htmlWebpackPlugin.options.title %> 
    doesn't work properly without JavaScript enabled. Please enable it to continue.
  </strong>
</noscript>
  
我们说index.html单页面开发,组件的替换其实替换的是这个位置
<div id="app"></div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 如何运作的?

项目是如何运行起来的 / 各个文件是如何协同工作的,逻辑是什么?

# main.js与index.html

尽管对里面的代码不清不楚, 但也无伤大雅.. main.js文件一般不会动它!! 我们也不用深究里面的代码!!

main.js是项目入口文件, 经实验,创建的vue实例挂载的是index.html里id为app的div. 是不是感觉很amazing?
当初我看到时也百思不得其解, 查阅资料, 发现跟webpack有关..
参考的文档: https://blog.csdn.net/qq_36145914/article/details/86497123 (了解即可)

另外, render: h => h(App) 又是什么? 箭头函数, 此处的h指代的是createElement函数, 跟啥虚拟dom有关..
另外, .$mount('#app') 相当于 el: '#app',

image-20231009160804522

// 分别导入: Vue库、App组件、路由配置、状态管理器
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'

// 关闭生产模式下的错误提示信息
Vue.config.productionTip = false

/*
   new Vue({...})创建一个vue实例
   将路由配置、状态管理器以及App组件注入/渲染到vue实例中.
   .$mount('#app') 将Vue实例挂载到id为"app"的元素上.
*/
new Vue({
    router,
    store,
    render: h => h(App)
}).$mount('#app')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# 组件的三部分

我们重新写App.vue和HelloWorld.vue文件,便于我们理解执行逻辑!!
(因为默认里面写了路由这些相关的代码.我们暂且不需要掌握)

1> <template> 标签里是以前我们在反引号里写的html代码,同样的,特别强调,组件必须在一个标签里.eg:div标签.
2> <script> 标签里写js、导入以及export default
      export default {} 该对象里写之前学的data、methods、watch、computed、生命周期函数等!
3> <style> 标签里写样式.

注意: <style scoped> 表明, 写的样式只在当前组件有效!!
也就是说, 这样写, 父组件里用了子组件, 子组件是不会应用父组件里写的样式的!!

另外,注意: 父组件中导入子组件export default的对象接着对子组件进行注册
只不过, 该对象里不用写template:反引号 ,会自动关联子组件<template> 标签里的东西.

image-20231009180148504

特别注意!! 示例代码截图中,helloWorld_obj是一个对象; export default导出的也是一个对象!!

image-20231009181321404

Ps: test.html单独运行,或者 运行 当前的vue项目!! 运行结果都如上图截图所示!!
why? 你可以这样对比理解..

main.js里有vue实例,main.js与index.html相关联.  --  相当于test.html里写了个vue实例 (test.html对标index.html)
main.js里的vue实例挂载id为app的div             --  相当于test.html中的vue实例挂载index.html中挂载id为app的div
main.js里的vue实例中加载了根组件App.vue         --  相当于test.html中的vue实例里面写了一个名为App的局部组件
项目运行后,根组件App.vue会自动渲染到挂载点        --  相当于test.html中在挂载点写子组件标签

根组件App.vue里导入子组件HelloWorld.vue        -- 相当于名为App的局部组件里编写了一个名为HelloWorld的子组件
1
2
3
4
5
6

# vue项目中组件通信

自定义属性实现父传子 ; 自定义事件实现子传父.

# 示例代码

APP.vue

<template>
  <div id="father">
    {{ fullname }}
    <button @click="handleClick">点我名字变化!</button>
    <br>
    子传父: x: {{ x }}
    <hr>
    <HelloWorld :fullname="fullname" @myevent="handleReceive"></HelloWorld>
  </div>
</template>

<style>
#father {
  width: 300px;
  margin: auto;
  padding: 10px;
  border: 1px solid bisque;
}
</style>

<script>
import HelloWorld from "@/components/HelloWorld"
  
export default {
  name: 'App',
  data() {
    return {
      isActive: true,
      fullname: "lqz",
      x: "",
    }
  },
  methods: {
    handleClick() {
      this.isActive = !this.isActive
      this.fullname = this.isActive ? 'lqz' : '彭于晏'
    },
    handleReceive(x) {
      this.x = x
    }
  },
  components: {  // 注册组件,即在父组件中使用子组件!
    // 'HelloWorld': HelloWorld  // ★ 简写-可以简单的只写import导入时给小组件起的名字 HelloWorld
    HelloWorld
  }
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

HelloWorld.vue

<template>
  <div>
    父传子: {{ fullname }} <br>
    <input type="text" v-model="x">
    x: {{ x }} ; y: {{ y }}
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  props: ["fullname"],  // 父传子的变量fullname无需在data里申明,写在props中后直接用就行
  data() {
    return {x: 10, y: 20,}
  },
  methods: {
    handleSend() {
      this.$emit('myevent', this.x)
    }
  },
  watch: {
    x(val) {
      this.handleSend()
    }
  },
  created() {
    this.handleSend()
  }
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

# 代码逻辑

image-20231009205056948

# 执行结果

组件

有两个组件,APP.Vue和HelloWorld.vue 并且根组件APP里注册了HelloWorld组件
1> 父传子, 点击按钮, 显示的名字同步改变!!
2> 子传父, 先是在生命周期的created函数中就传了一次;
          后因为双向绑定+监听,当数据改变时,会重新传递!!
1
2
3
4

有个小细节: 根组件的 <template> 里的代码覆盖了index.html中 <div id="app"></div> 这里的代码!!

image-20231010132340518

# props配置项

三种使用方式

特别注意!! 父传子,经过实验. (示例代码中只是props的基本使用!!) <helloWorld fullname="true"></helloWorld> 传过去的fullname的值是true, 该true是String类型的数据!! <helloWorld :fullname="true"></helloWorld> 传过去的fullname的值是true, 该true是Boolean类型的数据!!

★★★ props的三种使用方式,任选其一即可! 注意哈,String,S是大写的!!
1- 基本使用
  props: ["fullname"]
2- 进行属性认证
  props: {
    fullname: String, // 意味着接受父组件传过来的fullname,必须是string类型的数据!!
  }
3- 限定类型、限定必传、限定默认值
  props: {
    fullname: {
      type: String,
      // false表明没有限定必传(即子组件标签上没有绑定名为fullname的属性)
      required: false,
      // 若没有传的话,其默认值为‘啦啦啦’
      default: "啦啦啦",
    }
  }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# es6导入导出

注意: 在vue项目中, 导入时, @符号表示src的路径! 导入时,文件的.vue后缀、.js后缀都可以省略!

下方的示例中使用的是默认导出, 还有命名导出等方式.. 具体的参考文档: https://segmentfault.com/a/1190000039957496
暂且记住一点, 命名导出的话, 导入时 import {导出时的命名,导出时的命名,..} from 路径 需要加大括号!!

示例的目录结构如下:

my
├── other
│   └── index.js
├── one.js
├── two.js
└── test.html
1
2
3
4
5
6

代码逻辑
注意代码截图中用 ★ 标注的注释!!

image-20231009224132526

运行结果

image-20231009224655471


# mixin混入

需求: 父组件App.vue里使用子组件HelloWorld.vue, 这两个组件里都有同一个点击事件, 点击事件关联的函数体代码都是一样的!!
点击弹出一个框, 框中显示的内容是各自组件里的数据..

mixin混入: 可以把多个组件共用的配置提取成一个混入对象!!

minx

# 最初的代码

浅红色标柱的代码是公共的/一样的, 可以提取出来!!

image-20231010214121449

# 使用混入

第一步: 提取公共的代码, 定义混入.. 此处, 我们在src目录下新建mixin文件夹, 在mixin文件夹下创建index.js文件.
第二步: 注册混入, 有两种方式, 选择其中一种方式即可.
1> 全局注册 - 在main.js文件中注册, 注册后所有组件都可以使用混入的内容.
2> 局部注册 - 在组件中注册后,该组件才可以使用混入的内容.

# 全局注册

下方截图主要观察 index.js 以及 main.js中 框起来的代码.

image-20231010212852736

PS: 若混入的index.js中有多个命名导出.. 那么全局注册这样处理. 举个例子:

import {hunhe,hunhe2} from '@/mixin'

Vue.mixin(hunhe)
Vue.mixin(hunhe2)
1
2
3
4
# 局部注册

以子组件HelloWorld.vue为例

关键代码就两行: import {myMixin} from "@/mixin"; mixins: [myMixin]

<template>
  <div>
    <button @click="handleShowName">点击弹窗</button>
  </div>
</template>

<script>
import {myMixin} from "@/mixin";

export default {
  name: 'HelloWorld',

  data() {
    return {
      name: "child_路飞"
    }
  },
  methods: {},
  mixins: [myMixin]
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

# 插槽的使用

默认插槽、具名插槽 (其实在前面已经讲解过了)

<template v-slot:插槽名字> 还可以简写 <template #插槽名字>

image-20231011164056918

页面展示效果如下:

image-20231011164129321


# 存储数据

sessionStorage - 临时存储, 浏览器关闭或关闭标签页 就没啦!
localStorage - 永久存储, 除非手动清理/浏览器存储空间满了!
cookie - 有个过期时间, 过期时间一到就没啦! + 发送请求时会自动携带它.

前端存数据的三个地方 - cookie、sessionStorage、localStorage.
在cookie中存储需要借助第三方插件vue-cookies 暂且略过.
★ 借助这三个东西, 也可以实现组件间的通信!!

sessionStorage.setItem('name', 'lqz')  // 设置值
sessionStorage.getItem('name')         // 取值
sessionStorage.removeItem('name')      // 删除值
sessionStorage.clear()                 // 清空sessionStorage中所有数据

localStorage.setItem('name', 'lqz')
localStorage.getItem('name')
localStorage.removeItem('name')
localStorage.clear('name')             // 清空localStorage中所有数据    
1
2
3
4
5
6
7
8
9

应用场景:
无需登陆就可以将商品加入购物车,关闭浏览器后,重新打开浏览器,发现刚加入购物车里的商品还在!
实现原理 - 前端将商品信息加到了localStorage中!!

222

App.vue

<template>
  <div id="father">
    <p>
      用户名: {{ username ? username : "还未获取" }}
    </p>
    <button @click="handleSave">点击</button>
    <p style="color: rgb(128,128,128)">
      1> 起初 - 用户名处显示 "还未获取" <br>
      2> 点击按钮 向sessionStorage中放数据 - 用户名处显示存入的数据 "lqz" <br>
      3> 5s后 缓存的数据消失 - 用户名处显示 "缓存数据消失" <br>
    </p>
  </div>
</template>

<style scoped>
#father {
  width: 550px;
  margin: auto;
  padding: 10px;
  border: 1px solid bisque;
}

h3 {
  background-color: bisque;
}
</style>

<script>
export default {
  name: 'App',
  data() {
    return {
      username: ''
    }
  },
  methods: {
    handleSave() {
      sessionStorage.setItem('name', 'lqz')
      this.username = sessionStorage.getItem('name')
      /* 注意点:
         setTimeout是异步的,它不会阻塞在这,时间到了会执行里面的回调函数
         这里用了箭头函数,确保该处的this指向是vue实例,而不是window对象.
      */
      setTimeout(() => {
        sessionStorage.removeItem('name')
        this.username = "缓存数据丢失."
      }, 5000)
    }
  },
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

# vue3的变化

前面的讲解都是基于vue2实现的, 我们后续开发项目用vue3, vue3是兼容vue2的!!

vue3变化参考文档: https://www.cnblogs.com/liuqingzheng/articles/16840372.html
★ 学的vue2的所有东西都可以直接写在vue3上, 完全支持!!

# 创建vue3的项目

# webstorm里

它会自动选择vue3创建!! 创建时是默认的配置, 是没有 Router和 Vuex的.. 不碍事,后面可以手动加入.

另外, 通过这种方式创建的项目, 快速启动的绿色按钮也不需要自己配置啦!!
但在我的mac上实践了下,会报错, 在项目根目录下运行这两行命令完美解决 rm -rf node_modules ; npm install

image-20231013194534515

# 使用vite
创建vue3的项目:
  - 使用vue-cli创建,跟vue-cli创建vue2项目基本一致
  - 使用vite创建
    step1: 创建工程 “利用vite新创建的工程是没有node_modules文件夹的”
           npm init vite-app vue3_1
    step2: 进入项目工程 cd vue3_1
    step3: 安装依赖 npm install “项目根目录下就会多出node_modules文件夹”
    step4: 运行,注意命令 ★ npm run dev  “会发现,运行的特别快!!之前用vue-cli创建的运行起来还需编译,现在编译都不需要”
1
2
3
4
5
6
7
8

image-20231013211237820

可以浅看下代码, 利用vite创建好项目后, 最开始就默认有的代码是如何实现这个页面的..
可以发现里面使用的vue2的语法, 都是学过的, so easy. 有效的证明了“vue3兼容vue2嘛!!”

image-20231013212219257

细心点, 可以发现, <template> 标签里的html代码无需特地放在 一个div标签里啦!!

# 组合式API

vue2使用的是配置项API , vue3中推荐使用组合式API!!

以后vue3不建议组件中使用data、methods.. 这种配置项API; 建议使用setup这种组合式API!!

111

<template>
  {{ name }}:{{ age }}:{{ nums }} <br>
  <button @click="age++">点击年龄加一</button>
  <button @click="handlerNumAdd">点击数字加一</button>
  <br>
  身高:{{ person.height }} 体重:{{ person.weight }}
  <button @click="handlerHeightAdd">点击身高加1cm</button>
  <br>
  出生地:{{ BirthPlace }}
  <button @click="handlerChangeCity">点击修改城市</button>
  <br>
  监听它:{{ temp }}
  <button @click="temp++">点击监听的变量加一</button>
</template>

<script>
import {ref, reactive, computed, watch} from 'vue'

export default {
  name: 'App',
  setup() {
    /* 定义变量
     * 相当于在vue2的配置项API data(){return {name:'lqz',age:18}}
     * */
    // 若不加ref,那么点击按钮,age变量的值会加1,但是页面上{{age}}不会变/不会响应式的改变.
    // 若不加reactive,那么点击按钮,person对象的height的值是会改变的,会加1,但是页面上{{person.height}}不会响应式的改变.
    const name = ref('lqz')
    const age = ref(18)
    const nums = ref(0)
    const person = reactive({
      height: 172,
      weight: 110,
    })

    /* 定义函数方法
     * 相当于在vue2的配置项API  methods:{handlerNumAdd() {}},
     * */
    function handlerNumAdd() {
      // 因为使用了ref,所以nums变量变成了ref对象!
      // 注意,若未使用ref const name = 'lqz' , name变量是常量是不能改变的!
      //     (内存地址不能变,若是复杂数据类型,比如对象,对象内存地址不变,但里面的属性是可以变的)
      // ★★★《基本数据类型》用ref包裹一下,使之变成响应式. 在模版中直接使用;在setup(){}中需要nums.value获取真正的值.
      // ★★★《数组、对象类型》用reactive包裹一下,使之变成响应式. 在模版中和setup(){}中都直接使用;
      console.log(nums, typeof nums)
      nums.value += 1
    }

    function handlerHeightAdd() {
      person.height += 1
    }

    // ★★★ 可以写多个计算,也可以写多个监听
    
    /* 定义计算属性
     * 相当于在vue2的配置项API  computed: {}
     * */
    const student = reactive({
      nation: "中国",
      city: "成都"
    })
    let BirthPlace = computed(() => {
      return student.nation + student.city
    })
    // function handlerChangeCity(){}
    let handlerChangeCity = () => {
      student.city = "北京"
    }

    /* 定义监听属性
     * 相当于在vue2的配置项API  watch: {}
     * */
    const temp = ref(1)
    watch(temp, (newValue, oldValue) => {
      console.log(newValue, oldValue)
    })

    // ★★★ setup中可以写变量,写函数等, 但只有return了,在模版中才可以使用!
    //     这使得不会像vue2里面一样全部动态渲染,vue3需要啥渲染啥.
    return {
      name,
      age,
      nums,
      handlerNumAdd,
      person,
      handlerHeightAdd,
      BirthPlace,
      handlerChangeCity,
      temp,
    }
  }
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92

# 生命周期

"[生命周期]"
- 在vue3里,若用vue2的配置项写法,生命周期的8个函数,有两个需要改一下名字
  beforeDestroy 改名为 beforeUnmount
  destroyed     改名为 unmounted
- 在vue3里,若使用vue3的组合式API写法 对应关系如下
  “但要注意,setup()一执行,就认为beforeCreate和created就执行完了.”
  “比如,在setup中写 import {onMounted} from 'vue';   onMounted(() => {})”
  beforeCreate  ===>     setup()
  created       ===>     setup()
  beforeMount   ===>     onBeforeMount
  mounted       ===>     onMounted
  beforeUpdate  ===>     onBeforeUpdate
  updated       ===>     onUpdated
  beforeUnmount ===>     onBeforeUnmount
  unmounted     ===>     onUnmounted 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# toRefs

对象解压, 就不必在模版中 对象.xx 取值啦!

image-20231013231513342

<template>
  身高:{{ person.height }} 体重:{{ person.weight }} <br>
  姓名:{{ name }} 年龄:{{ age }}
</template>

<script>
import {reactive, toRefs} from 'vue'

export default {
  name: 'App',
  setup() {
    const person = reactive({
      height: 172,
      weight: 110,
    })

    const fullName = reactive({
      name: "dc",
      age: 19,
    })


    // es6语法中的对象解压
    /* 下面的代码等同于
       return {
           person,
           name:fullName.name,
           age:fullName.age,
       }
    * */
    return {
      person,
      ...toRefs(fullName),
    }
  }
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

基础语法(3)
插件的使用(1)

← 基础语法(3) 插件的使用(1)→

最近更新
01
deepseek本地部署+知识库
02-17
02
实操-微信小程序
02-14
03
教学-cursor深度探讨
02-13
更多文章>
Theme by Vdoing | Copyright © 2023-2025 DC | One Piece
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式