# learn-vue **Repository Path**: dovuoy/learn-vue ## Basic Information - **Project Name**: learn-vue - **Description**: 学习vue的一些心得 - **Primary Language**: HTML - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2022-07-13 - **Last Updated**: 2022-10-28 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ## 工程化 ### Webpack项目初始化 创建项目目录webpackProj,在项目目录里面执行如下脚本: ```shell npm init -y ``` 在项目目录里面创建src源代码目录,在src目录里面依次创建index.html和index.js文件,运行如下命令安装jQuery ```shell npm install jquery -S ``` -S 等同于 --save 在index.js中代码如下: ```js import $ from 'jquery' $(function () { console.log('???') }) ``` 此时访问index.html,报 Cannot use import statement outside a module错误 安装webpack ```shell npm install webpack@5.42.1 webpack-cli@4.9.2 -D ``` -D 等同于 --save-dev 在根目录下创建webpack.config.js配置文件,代码如下: ```js //导入node.js中专门操作路径的模块 const path = require("path") // 使用node.js语法 向外导出一个webpack配置对象 module.exports = { //代表webpack运行模式,有 development 和 production 两个选项, // 特点:dev打包快,不压缩;prod打包慢,压缩,正好符合生产要求体积小的需求 mode: "production", //entry 指定入口文件,默认是src下的index.js文件,__dirname代表当前配置文件的目录 entry: path.join(__dirname, './src/index2.js'), //output 打包输出配置 output: { path: path.join(__dirname,'dist01'), filename: "bundle.js" } } ``` 在package.json文件里面的scripts节点中创建dev命令: ```js "dev": "webpack" //scripts节点下的脚本,可以通过npm run 执行,比如:npm run dev ``` 在控制台执行 ``` npm run dev ``` 生成dist文件夹,在index中引入dist文件夹中的main.js 访问index.html,import $ from 'jquery' 类似语法就生效了 ### 项目开发热部署 安装webpack-dev-server插件 ```shell npm install webpack-dev-server@3.11.2 -D ``` 修改package.json中的dev值: ```js "scripts": { "dev": "webpack serve" } ``` 再次运行npm run dev报错: ```shell Unable to load '@webpack-cli/serve' command ``` 安装webpack-cli ```shell npm i webpack-cli -D ``` 修改html页面引用内存中的bundle.js ```html ``` 访问:http://localhost:8080/src/ ### 不访问src 安装html-webpack-plugin插件 ```shell npm i html-webpack-plugin@5.3.2 -D ``` 在webpack.config.js配置: ```js //1、导入html-webpack-plugin插件,得到这个插件的构造函数 const HtmlPlugin = require('html-webpack-plugin') //2、new 构造函数,插件插件对象 const htmlPlugin = new HtmlPlugin({ template:'./src/index.html',//要复制的文件 filename:'./index.html'//目标文件 }) // 使用node.js语法 向外导出一个webpack配置对象 module.exports = { //3、注册插件 plugins: [ htmlPlugin ] } ``` 此时直接访问:http://localhost:8080 出现页面 此时在index.html中移除 访问页面依然有效,是因为html-webpack-plugin插件自动加入了bundle.js ### 指定ip端口打开浏览器 在webpack.config.js配置: ```js module.exports = { //开发服务配置 devServer: { open: true, host: '127.0.0.1', port: '6980' } } ``` ### 加载资源 在webpack中,一切皆是模块,都可以通过ES6语法导入和使用 #### 加载css 在src目录下创建css目录,在css目录中创建index.css样式文件 在src/index2.js文件中添加如下代码: ```js import './css/index.css' ``` 此时项目运行报错,提示需要一个合适的加载器来加载这个文件 安装style-loader和css-loader加载器: ```sh npm i style-loader@3.0.0 css-loader@5.2.6 -D ``` 在webpack.config.js中配置: ```js module.exports = { module: { rules: [ {test: /\.css$/, use: ['style-loader', 'css-loader']} ] } } ``` 此时通过浏览器发现使用import导入的css样式文件生效 #### 加载less 在src目录下创建css目录,在css目录中创建index.less样式文件 在src/index2.js文件中添加如下代码: ```js import './css/index.less' ``` 安装less-loader和css-loader加载器: ```js npm i less-loader@10.0.1 less@4.1.1 -D ``` 在webpack.config.js中配置: ```js module.exports = { module: { rules: [ {test: /\.less$/, use: ['style-loader', 'css-loader', 'less-loader']} ] } } ``` 运行项目,发现导入的less样式生效 #### 加载图片 base64图片优缺点 | 优点 | 缺点 | | ------------------------------ | ------------------------ | | 不用发起多次网络请求,一步到位 | 转成base64后体积会大一点 | 在src目录下创建img目录,在img目录下放入一个test.jpg的图片 在index.html文件中加入图片标签: ```html ``` 在index2.js文件中加入代码: ```js import testimg from './img/test.jpg' $(function () { $('.imgBox').attr('src',testimg) }) ``` 安装url-loader和file-loader加载器: ```sh npm i url-loader@4.1.1 file-loader@6.2.0 -D ``` 在webpack.config.js中配置: ```js module.exports = { module: { rules: [ {test: /\.jpg|png|gif$/, use:'url-loader'} ] } } ``` 运行项目,在浏览器发现导入的图片 控制图片超过多大时不转base64配置: ```js module.exports = { module: { rules: [ {test: /\.jpg|png|gif$/, use:'url-loader?limit=11735'}//大于limit值时不转base64 ] } } ``` ### 高级语法处理 #### 装饰器语法 在index2.js中添加如下代码: ```js //定义一个装饰器 function info(target) { //添加一个静态属性info target.info = 'xxxx info..' } //使用装饰器 @info class Person{} console.info(Person.info) ``` 安装babel插件: ```sh npm i babel-loader@8.2.2 @babel/core@7.14.6 @babel/plugin-proposal-decorators@7.14.5 -D ``` 在webpack.config.js文件中配置: ```js module.exports = { module: { rules: [ {test: /\.js$/, use:'babel-loader',exclude:'/node_modules/'} ] } } ``` 创建babel.config.js配置文件,使用插件注册代码如下: ```js module.exports = { "plugins": [ ["@babel/plugin-proposal-decorators", {"legacy": true}] ] } ``` 找插件配置地址:https://babeljs.io/docs/en/babel-plugin-proposal-decorators 运行项目,打开浏览器f12就会发现打印的静态属性值 ### 打包发布 在package.json文件中的scripts节点增加命令: ```js { "scripts": { "build": "webpack --mode production" } } ``` 运行打包命令: ```sh npm run build ``` 生成指定的打包输出目录,不配置默认是dist目录,访问包目录中的index.html文件 打包配置js文件放到js目录,图片放在images目录,在webpack.config.js中配置: ```js module.exports = { output: { filename: "js/bundle.js"//指定打包js目录 }, module: { rules: [ //处理图片文件的loader,<=limit值时才转base64,outputPath指定图片打包输出目录 {test: /\.jpg|png|gif$/, use:'url-loader?limit=11734&outputPath=images'} ] } } ``` 打包时自动删除之前的打包输出目录,安装插件clean-webpack-plugin: ```sh npm i -D clean-webpack-plugin ``` 在webpack.config.js中配置: ```js //左边的{}代表结构赋值 const {CleanWebpackPlugin} = require('clean-webpack-plugin'); module.exports = { //插件注册 plugins: [ new CleanWebpackPlugin(), ] } ``` 此时运行npm run build命令,会自动删除之前的打包输出目录。 ### 常见问题 解决报错行号和源码不匹配的问题,在webpack.config.js中配置: ```js module.exports = { //为安全考虑,生产不要使用source-map,折中方案是使用nosources-source-map // devtool:'eval-source-map',//显示报错文件名行号源码 devtool:'nosources-source-map',//只显示报错文件名和行号 } ``` 避免使用../../的路径,使用@代表./src/路径,在webpack.config.js中配置: ```js module.exports = { resolve:{ alias:{ '@':path.join(__dirname,'./src/') } } } ``` ## vue2 ### vue2项目初始化 安装vue2 ``` cnpm install -g vue-cli ``` 初始化vue项目 ``` vue init webpack vue2proj --offline > Use cached template at ~\.vue-templates\webpack ? Project name vue2proj ? Project description A Vue.js project ? Author yhongyin ? Vue build runtime ? Install vue-router? Yes ? Use ESLint to lint your code? No ? Set up unit tests No ? Setup e2e tests with Nightwatch? No ? Should we run `npm install` for you after the project has been created? (recommended) npm vue-cli · Generated "vue2proj". ``` --offline 离线安装,需要下载webpack-develop.zip解压后改名为webpack放在用户目录中的.vue-templates目录下 运行初始化的项目: ``` cd vue2proj npm run dev ``` ### vue-router路由 安装: ``` npm install vue-router --save ``` 路由模式 1. hash,路径上带有#号 2. history,正常路径 配置路由模式,在src/router/index.js文件中配置: ```js export default new Router({ mode: "history", //设置路由模式 routes }) ``` router-link属性 1. tag 设置链接显示类型,默认是a标签 2. replace 加了之后没法回到上一页 3. active-class 设置链接激活的class active-class全局设置,在src/router/index.js文件中配置: ```javascript ... export default new Router({ linkActiveClass:"active",//路由链接激活class统一设置之后自定义的全部失效 routes }) ``` ### element-ui的使用 安装element-ui ```sh npm i element-ui -S ``` 在main.js中加入 ``` import ElementUI from 'element-ui' import 'element-ui/lib/theme-chalk/index.css' Vue.use(ElementUI) ``` [Element文档](https://element.eleme.cn/#/zh-CN/component/quickstart) 快速工程化:[Cooking](https://github.com/elemefe/cooking) [element-starter](https://github.com/ElementUI/element-starter) [Vue2.0 新手入门 — 从环境搭建到发布](https://www.runoob.com/w3cnote/vue2-start-coding.html) ### 插槽 有插槽的组件: HasSlot.vue ```html ``` ScopeSlot.vue ```html ``` ScopeSlot2.vue ```html ``` 使用插槽: TestSlot.vue ```html ``` ### vuex 安装vuex: ```sh npm i vuex@3.6.2 ``` 见代码:vue2proj/src/views/testVuex/TestVuex.vue ### Promise 见代码:vue2proj/src/views/promise/TestPromise.vue ### axios 安装axios ```sh npm install axios --save ``` 见代码:[TestAxios.vue](vue2proj/src/views/axios/TestAxios.vue) ![image-20221028143354502](assets/README/image-20221028143354502.png) ### sass 使用淘宝镜像 ``` npm config set sass_binary_site=https://npm.taobao.org/mirrors/node-sass ``` ## 官网示例 ### 声明式渲染 ```html Hello Vue 声明式渲染
{{message}}
悬停看提示信息
``` ### 条件与循环 ```html 条件与循环

显示

  1. {{todo.text}}
``` ### 处理用户输入 ```html 处理用户输入

{{message}}

{{message}}

``` ### 组件化应用构建 ```html 组件化应用构建
``` ### 实例数据与方法 ```html 数据与方法

{{msg}}

{{foo}}

``` ### 实列生命周期钩子 ```html 实例生命周期钩子

{{msg}}

{{msg}}

``` ### 语法-插值 ```html 插值
Message: {{msg}}

{{rawHtml}} 绑定属性id

{{ num + 1 }}

{{ ok ? 'Yes':'No'}}

{{ msg.split('').reverse().join('') }}

绑定id属性
``` ### 语法-指令 ```html 指令

被看到。。

链接

动态绑定属性

{{msg}}

{{msg}}

``` ### 语法-缩写 ```html 缩写
链接
链接2


``` ### 计算属性 ```html 计算属性

Msg:{{ msg }}

Reverse Msg:{{ reverseMsg }}

方法反转Msg:{{ reverseMsgMethod() }}

监听名字:{{fullName}}

计算名字:{{fullName}}

计算set和get方法:{{fullName}}

``` ### 监听器 ```html 侦听器
问yes还是no:

解答:{{answer}}

``` ### 绑定class ```html 绑定 HTML Class

绑定class

class绑定一个对象

class绑定一个计算属性

class 绑定一个数组

三元表达式控制class

绑定class数组中用对象语法

``` ### 绑定内嵌样式 ```html 绑定内联样式

绑定内联样式

绑定内联样式对象

使用计算对象

使用数组语法

自动添加前缀

多重值

``` ### 条件渲染 v-if ```html v-if
很棒..
不是很棒
if控制模块

显示a

显示b

显示c

未知页面

``` ### 条件渲染 v-show ```html v-show

显示我??

``` ### 列表渲染 v-for ```html v-for ``` ### 列表渲染-过滤排序 ```html 过滤、排序

计算属性

{{ num + ',' }}

使用方法

{{ num + ',' }}
``` ### 在组件上使用 v-for ```html 在组件上使用 v-for

以下是添加新闻板块

``` ### 监听事件 ```html 监听事件

数量:{{num}}



``` ### 事件修饰符 ```html 事件修饰符

点击继续传播,出现冒泡

.stop 阻止点击继续传播,父级div上的点击事件失效


.prevent 阻止默认事件的发生

百度

.capture 捕获冒泡,会被最先触发

.self 避免冒泡影响,只有点击自身才触发

.once 只触发一次

.passive 不阻止事件的默认行为

使用.passive 可以提高性能,让浏览器不用再去判断有没有调用event.preventDefault()

.native 用于自定义的组件上,在根节点上使用

``` ### 按键修饰符 ```html 按键修饰符

按回车键触发提交方法

名字:

按键抬起触发

使用按键名,比如page down


vue的示例按键名:
.enter
.tab
.delete (捕获“删除”和“退格”键)
.esc
.space
.up
.down
.left
.right

使用按键码,比如回车键,已经废弃,新浏览器可能不支持

自定义按键码,13 <回车键br>
``` ### 系统修饰符 ```html 系统修饰键
使用组合键触发事件
常用搭配组合键:Ctrl、Alt、Shift、Meta(Win系统为开始键)
Ctrl + C 组合

按Ctrl键点击

.exact修饰符
问题:按下Ctrl与Shift和Alt任意组合再点击按钮A,都会触发

只有按下Ctrl再点击按钮B才会触发

没有按下Ctrl、Shift和Alt任意键时或任意组合键时点击按钮C才会触发
鼠标按钮修饰符



``` ### 表单 ```html 表单输入绑定基础用法

v-model双向绑定数据

输入框:

msg:{{msg}}

使用v-model,元素的默认值都会替换成Vue实列的数据值
多行文本框:

{{textMsg}}

复选框:

{{checked}}

多个复选框:

{{names}}

单选按钮:

{{sex}}

选择框:

{{area}}

多选框:

{{areas}}

值绑定

输入框:

{{name}}

文本域:

{{content}}

单选按钮:

{{gender}}

选择框数据初始化及数据绑定;
单选择框:

{{book}}

复选框:

{{hobbies}}

多选择框:

{{depts}}

修饰符

.lazy 输入完成,光标离开输入框数据才同步

{{msg}}

.number 转数字

{{count}}

.trim 去首尾空格

{{msg2}}

``` ### 组件示例及复用 ```html 组件基本示例

组件基本示例


组件除了没有el属性外,其他属性及方法跟Vue属性一样

组件的复用



每使用一次组件都会创建一个组件实例,每个实例维护着自己的数据
``` ### 组件通过 Prop 向子组件传递数据 ```html 通过 Prop 向子组件传递数据
``` ### 组件单个根元素 ```html 单个根元素
``` ### 监听子组件事件 ```html 监听子组件事件

组件上使用v-model

``` ### 组件-插槽 ```html 使用插槽
I am sorry!
```