vue中动态绑定class
- 对象语法 :class ="{'active':false}"
- 数组语法 :class = "['abc',{'active':isactive}]"
v-on绑定事件
- 针对一个元素绑定多个事件可以采用对象:@="{click:clickBtn,mousemove:mousemoveBtn}"
- v-on在传递参数的时候要想传入事件对象可以使用$event,
- v-on中还有一些修饰符,比如@click.stop = ""阻止冒泡,@click.prevent阻止默认事件, @keyup.enter =
v-for中的key的作用
- 官方解释,key主要是用在vue的虚拟dom算法中,在新旧的node中的辨识Vnode(虚拟节点)
- 源码中的分析,如果没有传入key,则会调用patchUnkeyChildren这个方法,在这个方法中会传入新旧节点数组,并且获得新旧节点的长度,然后去,较小的那个一个,接下来就是遍历数组,然后调用patch方法,将新旧节点中的各项进行对比,如果内容不同则更新内容,接下来就是进行新旧节点长度的比较,如果旧节点长于新节点,则删除剩余节点,如果新节点长于旧节点则创建新的节点
计算属性
- 计算属性有缓存,多次使用计算属性,计算属性的运算只会执行一次,可以提高性能优化,
- 计算属性会随这数据的变化而发生变化,
- 传入对象或者函数,源码中会做一个判断,对象的话之后有set和get,函数的话只有get
侦听器 watch
- 主要是用来的监听data中的数据变化
- 只会侦听数据本身的改变,对于数据内部的改变监听不到,要想监听数据的内部的改变,需要深度监听就是添加deep:true
- 要想在刚进入页面的时间就执行一个监听,可以添加immediate:true
- 监听器的另一种用法,$watch('参数名',function(newValue,oldValue){},{deep:true})
created(){
this.$watch('firstName',(newValue,oldValue)=>{
console.log('newValue:',newValue,'oldValue:',oldValue)
},{
deep:true,
immediate:true
})
}
//监听obj中的name
'obj.name'(newValue){
console.log(newValue)
// return this.obj.name
},
//监听obj中的name,还可以深度监听
obj:{
handler:function(newInfo,olfInfo){
console.log('newInfo',newInfo)
},
deep:true, //深度监听
immediate:true,//立即执行
},
watch 和计算属性之间的区别
- 计算属性主要是对data中的数据进行一些转化,然后在渲染到html结构中
- watch主要监听data中的数据变化,然后进行一些逻辑处理,例如网络请求等
methods
- 在methods的方法中不能设置delete方法
v-model
- 基本原理:利用v-bind绑定value属性,然后再用v-on绑定input事件,在每一次获取到新的值的时候都赋值给绑定的属性
- v-model中的修饰符:lazy,主要的作用的就是在失去焦点的时候触发change事件,number,主要就是将绑定的值的变成数字类型, trim,主要就是去除首尾的空格
- 在组件中绑定 v-model,就相当于
<Header :modelValue='message' @update:model-value ='message = $event' ></Header>
一般写成
<Header v-model="message" ></Header>
一般在父组件中使用了v-model,那么子组件中应该
<button @click="send2">传递modelValue</button>
model:{
prop:'modelValue',
event:'update:modelValue'
},
props:{
modelValue:String,
}
methods:{
send(){
this.$emit('update:modelValue',value)
}
}
也可以在子组件中input中绑定
<input type="text" v-model="value">
不能直接modelValue,因为props中的值一般不直接修改
computed:{
value:{
set(val){
this.$emit('update:modelValue',val)
},
get(){
return this.modelValue
}
}
},
全局组件
var app = Vue.createApp(App);
//app.components(组件名,组件对象)
//全局组件,就是在任意一个组件模板中都可以使用
//组件的命名:1,。短横线分隔符,2.驼峰分割
app.component('component-a',{
template:'#component-a'
})
app.mount('#app')
局部组件
<template id="temp">
<div class="">{{message}}</div>
<component-b></component-b>
</template>
<template id="component-b">
<div>总有一个人的出现会让你原谅过去所有的不幸</div>
</template>
<script src="./JS/vue.js"></script>
<script>
var componentB = {
template:'#component-b'
}
const App = {
template:'#temp',
data(){
return {
message:"hello vue3"
}
},
methods: {
},
components:{
//组件名:组件对象
componentB
}
}
Vue.createApp(App).mount('#app')
webpack
- 开发版本(局部安装), 就是只在开发的时候使用 -D或者--save-dev 2. 生产阶段,就是用户在使用的时候也需要
- webpack打包命令,npx webpack, 也可以在package.json的文件中的script中加入一个脚本,执行webpack,
"build":"webpack"
- 指定入口文件,和出口文件.默认情况下,webpack会寻找当前文件下src文件下的index.js进行打包,如果没有index.js,就需要指定入口文件 npx webpack --entry ./src/main.js --output-path ./build 也可以在 脚本中定义如下,
"scripts": {
"build":"webpack --entry ./src/main.js --output-path ./build"
},
- 在配置文件中定义入口文件和出口文件,在文件下创建一个webpack.config.js文件,一般都叫wepback.config.js这个名字,如果换名字,需要在package.json进行配置,如:取名last.config.js 需要配置 "build":"webpack --config last.config.js"
const path = require('path')
module.exports = {
// 定义入口文件
entry:'./src/main.js',
//出口文件
output:{
//绝对路径
path:path.resolve(__dirname,'./build'),
//定位打包文件的名字
filename:'first.js'
}
}
loader
- loader的主要用于就是对模块源码进行解析,因为在加载某个模块的时候,wepback并不知道如何对其进行加载,这时候就需要安装相应的loader
css-loader
- 如何使用css-loader,有3种方式,(1)内联样式,(2)CLI方式(webpack5不在使用)(3)配置方式, (1)内联方式如下:import 'css-loader!../style/index.css' (3)配置方式如下在module.rules中进行配置,有三个参数:test,主要是用来匹配配置文件的,一般是正则表达式,loader:主要是使用哪些loader,use:主要是可以添加多个loader,并且可以配置参数options;
module:{
rules:[
{
//使用正则表达式,匹配到相应的文件
test:/\.css$/,
//使用哪种loader (语法糖)
// loader:'css-loader',
//完整写法;加载loader的顺序,是从下往上
use:[
'style-loader',
'css-loader'
]
//里面可添加参数
// use:[
// {loader:'css-loader',options:}
// ]
}
]
}
}
less-loader
主要就是针对一些less文件进行一些打包,该loader需要借助于,less-compiler这个插件 一般在安装less-loader的时候会自行安装上这个插件,具体的配置如下
{
test:/\.less$/,
use:[
'style-loader',
'css-loader',
'less-loader'
]
}
PostCss
主要就是通过js来进行一些样式的转化,比如加一些浏览器的前缀等,postcss-loader ,首先需要进行一个局部的安装,npm install postcss postcss-cli -D,然后安装插件autoprefixer, npm install autoprefixer -D,后面就是使用 npx postcss --use autoprefixer -o end.css(打包后的文件) ./src/css/style.css 5. postcss-loader 在module.rules中的配置
{
loader:'postcss-loader',
options:{
postcssOptions:{
plugins:[require('autoprefixer')]
}
}
}
可以在跟目录下创建一个postcss.config.js
file-loader(坑多,所以详细说下)
- file-loader主要就是针对import和require引入的资源进行一个打包,列如:文字,图片
- (坑1)我在安装最新版本5.7版本后,发现不安装file-loader也是可以对图片进行打包的, 而我在安装了file-loader以后发现,对同一个图片打包了2次了,查明原因是:在 webpack 5 中使用旧的 assets loader(如 file-loader/url-loader/raw-loader 等)和 asset 模块时,当你想停止当前assets模块的的处理,并再次启动处理,这可能会导致 asset 重复,你可以通过将 asset 模块的类型设置为 'javascript/auto' 来解决。 如下:
3.(坑2)就是在打包的时候出现图片路径的错误,最后的图片的路径都变成了[object module],
查明原因后是:file-loader在默认情况下是使用es语法,但是在新的file-loader中使用esModule语法,所有我们需要停止使用esModule语法,在参数中配置;esModule:false;
4. file-loader相关的配置,关于输出的路径,以及输出的图片名如下;
{
test:/\.(jpeg|jpg|png|gif)$/i,
use:{
loader:'file-loader',
options:{
esModule:false,
// 输出的路径文件名 outputPath可以直接写在name中 如 name:'img/[name]_[hash:10].[ext]'
outputPath: 'img',
// 输出的图片名 [name]保留原来的名字 [hash:length] 加入hash进行辨别,后面是长度
//[ext]保留原来的后缀
name:'[name]_[hash:10].[ext]'
}
},
type:'javascript/auto'
}
url-loader
- url-loader和file-loader的功能差不多,url-loader可以将小图片,打包成base64的URI, 配置如下,limit可以显示图片的大小
{
test:/\.(png|jpg|gif|jpeg)$/i,
use:[
{loader:'url-loader',
options:{
esModule:false,
limit:50 *1024,
name:'img/[name]_[hash:6].[ext]',
}
}
],
type:'javascript/auto'
}
assets module type (资源模块类型)
- 在webpack5之前可以我们加载一些资源需要一些loader,如果file-loader,url-loader,raw-loader,
- 在webpack5开始,我们可以使用资源模块类型(assets module type)在代替上面的loader,
- asset/resource 发送一个单独的文件并导出 URL。之前通过使用 file-loader 实现
- asset/inline 导出一个资源的 data URI。之前通过使用 url-loader 实现
- asset/source 导出资源的源代码。之前通过使用 raw-loader 实现
- 相关配置
//asset module type (资源模块类型)
{
test:/\.(jpg|jpeg|gif|png)$/i,
type:'asset',
generator:{
//这块和url-loader与file-loader不同的是后缀的前面不公添加点
filename:'img/[name]_[hash:4][ext]'
},
parser:{
dataUrlCondition:{
maxSize:50 *1024
}
}
}
对字体进行打包
- 使用file-loader一样可以对字体进行打包,具体配置如下
{
test:/\.(ttf|eot|woff|woff2)$/i,
use:[
{
loader:'file-loader',
options:{
name:'font/[name]_[hash:3].[ext]',
esModule:false
}
}
],
type:'javascript/auto'
}
- 使用模块资源类型对文字进行打包,配置如下
{
test:/\.(eot|woff|woff2|ttf)$/i,
type:'asset/resource',
generator:{
filename:'iconfont/[name]_[hash:3][ext]'
}
}
plugin
- (官网解释)loader主要是对特定的模块类型进行转化,而plugin则可以做更多的事情,比如打包优化,资源管理,环境变量的注入
CleanWebpackPlugin
- 在每次打包之前,都需要删除dist文件夹这样会非常的繁琐,clean-wepback-plugin插件可以在打包之前帮助我们删除dist文件夹
- 首先需要安装clean-webpack-plugin,npm install clean-webpack-plugin -D 安装开发时依赖
- 在webpack.config.js 中需要首先引入 clean-webpack-plugin, 并进行配置,如下
HtmlWebpackPlugin
- 首先需要安装插件
- 针对index.html进行打包,在dist的文件(dist)下生成index.html, 并且,index.html可以指定相应的模板,在topions中配置参数template,并且可以确定title的名字,具体配置如下
DefinePlugin
- 主要就是针对自定义模板的一个数据填充,创建配置的全局常量,例如设置BASE_URL,webpack内置的插件,不需要安装,具体配置如下
CopyWebpackPlugin
- 主要就是用来复制的,具体的配置如下,里面的参数from:主要设置从哪一个源开始复制,to:是复制到哪里,一般可以省略不写,ignore表示在复制的时候默认会忽视哪些文件
mode 和devtool
- 如果是开发阶段,就在mode中设置development,如果生产阶段,就是在发布上线的时候,那么就需要,设置成production,
- 在devtool默认是设置成eval,一般会source-map,作用是映射js,方便排查错误
babel
- babel就是一个工具链,针对于旧的环境或者旧的浏览器将ECMAscript2015版本以上的代码转化为向后兼容的javaScript
- babel是一个单独的工具,可以不和webpack等构建的工具一起使用,首先进行安装,npm install @babel/core @babel/cli -D
- 使用babel来处理我们的代码,npx babel src --out-dir dist ,src代表的是源文件,--out-dir表示指定输出的文件夹,--out-file表示的指定输出的文件
- 转化箭头函数,需要安装@babel/plugin-transform-arrow-functions,具体如下,处理的代码的时候,npx babel src --out-file test.js --plugins=@babel/plugin-transform-arrow-functions
-
转化块级作用域;安装@babel/plugin-transform-block-scoping,处理我们代码的时候:npx babel src --out-file test.js --plugins=@babel/plugin-transform-arrow-functions,@babel/plugin-transform-block-scoping
-
转化的内容过多,这时候一个一个设置很繁琐,这时候可以使用预设(preset) ,安装 @babel/preset-env,执行的命令如下,npx babel src --out-file test.js --presets=@babel/preset-env
-
babel的底层原理,babel其实就是一个编译器,将我们所写的源代码编译成浏览器可以识别的的代码,babel执行的阶段就是先解析我们的源代码,然后转化我们的源代码,最后生成目标代码
babel-loader
- 在安装babel-loader的时候,需要同时安装@babel/core
- 在配置的时候,需要添加指定的插件具体如下
{
test:/\.js$/,
use:[
{
loader:'babel-loader',
options:{
plugins:['@babel/plugin-transform-arrow-functions','@babel/plugin-transform-block-scoping']
}
}
]
}
- 也可以提供一个预设,preset,需要提前安装@babel/preset-env
{
test:/\.js$/,
use:[
{
loader:'babel-loader',
options:{
// 如果用[],将babel扩起来,可以,在该[],再添加一个对象,往里面添加属性
presets:[['@babel/preset-env']]
}
}
]
}
在vue中使用webpack
- 首先需要安装vue-loader,然后还需要安装@vue/cli-compiler-sfc 这个插件,具体的配置如下
const {VueLoaderPlugin} = require('vue-loader/dist/index')
{
test:/\.vue$/,
use:[
{
loader: 'vue-loader',
}
]
}
new VueLoaderPlugin(),
- vue打包后,不同版本解析,在webpack,rollup等构建工具中,默认使用vue.runtime.esm-bundler.js,如果想要解析template,就需要手动指定vue.esm-bundler.js;
热替换
vite
- 安装vite;npm install vite -D;
- vite是直接支持css的,也支持css预处理器less,需要安装less编译器,install less -D
- vite 也支持postcss的转换,需要安装postcss,以及对应的插件postcss-preset-env;并且需要在根目录下新建一个名为postcss.config.js的文件并进行配置
module.exports = {
'plugins':[
require('postcss-preset-env')
]
}
- vite对vue支持
vue3单文件组件支持:@vitejs/plugin-vue
vue3 JSX支持:@vitejs/plugin-vue-jsx
vue2 支持:underfin/vite-plugin-vue2
安装支持vue的插件: npm install @vitejs/plugin-vue-D 在vite.config.js中配置相关插件
import vue from '@vitejs/plugin-vue';
module.exports = {
plugins:[
vue()
]
}
- vite对项目进行打包 npx vite build;对打包的项目进行预览:npx vite preview
父子组件之间的传值
- 父组件传值給子组件使用 prop;
- 子组件传值给父组件使用 $emit;
- 针对于非父子组件之前的传值:provide,inject 在一些深度嵌套的组件,子组件想要获取父组件的部分内 容; p 在这种情况下,如果我们仍然将props沿着组件链逐级传递下去,就会非常的麻烦;这种情况下就可以使用provide和inject,无论层级结构有多深,父组件都可以作为其所有子组件的依赖提供者;p父组件有一个 provide 选项来提供数据; p子组件有一个 inject 选项来开始使用这些数据; 父标签通过provide来提供数据;子组件通过inject来获得数据
但是如果provide中提供的数据来自data,这是使用this,会报错,这是因为这个时候this指向script标签中的this,所以一般provide会写成一个函数形式,provide从data中获得的数据本身不具有响应式,需要加入computed