Vue.js入门到入土

Vue学习之旅

webpack

前端模块化,解决js兼容问题,项目打包等都需要webpack使用node创建前端工程

-D参数 在开发阶段使用的包

-S参数 在开发上线都需要的包

webpack配置文件编写:

1
2
3
module.exports={    //开发环境 
development | production mode:'development'
}

在package.json文件的scripts脚本加入(可以使用npm运行的脚本)

"dev" :"webpack"

npm run dev 后会发现一个dist文件夹,引入dist/main.js文件,即可

两种模式的区别

1
2
development    开发环境使用,打包速度快
production 上线的时候用,打包慢,但是压缩的文件更小

默认约定和改变

打包目录:./src/index.js

输出路径 ./dist/main.js

1
2
3
//指定处理的文件    
entry: path.join(__dirname,'./src/index.js'),
output:{ path:, filename: }

安装配置webpack插件

npm install webpack-dev-server@3.11.2 -D

更改配置文件“scripts” :”dev serve “

重新run发现报错更改webpack-cli版本为4.10.0

安装了webpack-dev-server后,生成的js文件是在内存中的,需要手动引入

html-webpack-plugin 配置完成不用手动进入src的index页面,打开8080就是首页

1
2
3
4
5
6
7
8
//导入HTML插件 
const HtmlPlugin=require('html-webpack-plugin');
const htmlPlugin=new HtmlPlugin({
template:'./src/index.html',
//指定原文件存放路径
filename:'./index.html'
//指定生成文件的存放路径 })
module.exports={ mode:'development', plugins :[htmlPlugin] //通过节点使插件生效 }

引入这个插件不需要再手动引入打包过的js文件

devServer节点

设置默认打开浏览器

1
2
3
4
5
6
`devServer:{        
open:true, //是否打开浏览器
host:'127.0.0.1', //主机地址
port: 80 //端口号

}`

loader

加载css等文件注意:

如果报错loader找不到先安装

1
npm install style-loader css-loader

配置文件

1
2
3
4
5
6
7
8
module:{
rules:[
{test:/\.css$/,use:[{ loader: 'style-loader' },
{ loader: 'css-loader' }]},

]
}

打包处理less文件

安装loadernpm i less-loader@10.0.1 less@4.1.1 -D

更改配置文件 图片loader加载需要安装url-loader file-loader

1
2
3
4
npm i url-loader@4.1.1 file-loader@6.2.0 -D

配置文件
{test:/\.gif|jpg|png$/,user:[{loader:'url-loader|limit=22229'}]}

配置build命令

1
"build" "webpack --mode production"

sourceMap

记录源代码代码的位置信息,以及打包的代码的位置信息更改配置文件中devtool的值即可在调试中输出准确的代码位置

Vue

特点

双向绑定:不操作DOM的前提下,自动把用户填写的数据同步到数据源

数据驱动视图:页面监听数据,数据发生改变重新渲染页面

MVVM架构

Model:数据源

View:当前页面所渲染的DOM结构

ViewModel :vue实例

使用步骤

1、导入vue.js脚本文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
```

<script src=" https://cdn.staticfile.org/vue/2.6.12/vue.min.js"></script>`

页面中声明一个被vue控制的DOM区域

`<div id="app">{{ message }}`

创建vm实例对象

``` vue
const vm=new Vue({
el:'#app', //控制区域
data:{ //数据源
message:'李四',
list:['1','2'],
}
});

内容渲染指令

v-text

渲染值到标签中,但是会覆盖原有内容

插值表达式

作用同上,但是不会覆盖原来的内容

v-html

渲染文本和HTML标签

属性绑定指令

1
2
3
4
5
6
注意:插值表达式不能用在属性节点中,只能用在内容节点
<input type="text" v-bind:placeholder="tips">
使用v-bind可以动态绑定属性,给那个属性绑定,就在哪个属性前面加上v-bind:,可以简写为:,例如:src
插值表达式和v-bind可以进行简单运算
<div>{{msg.split('').reverse()}}</div>

事件绑定

vue提供了v-on指令进行事件绑定

1
<button v-on:click="add">+1</button>   //:后面声明事件的类型

并且vue提供methods对象允许我们定义js方法

1
2
3
4
5
6
7
8
9
10
11
 methods:{
add:function(){
console.log('ok');
this.count++;
}
}
//简写
add(){
this.count++;
}

通过this访问数据源中的对象

因为this指向的是Vue对象,可以使用this代替vue实例访问数据源中的值

简写以及传参

1
<button @click="add(1)">+1</button>

$event事件绑定

1
2
3
4
5
6
7
//事件没有传递参数,则会有一个默认事件对象
add(e){
this.count++;
console.log(e);
console.log(e.target);
}
======控制台打印如下结果

但是如果方法传递了参数,就会覆盖这个事件对象可以通过vue内置对象,$event传入事件对象

事件修饰符

原生js中,我们可以通过事件的方法阻止事件默认行为和事件冒泡。在vue中提供的更加方便的实现:事件修饰符

1
2
@click.prevent     //.prevent就可以阻止默认行为

按键修饰符

1
2
<input type="text" @keyup.enter="append" placeholder="请输入">

双向绑定

双向数据绑定,vue提供v-model进行数据绑定,通过这个指令,用户在视图上面对数据的修改,可以被数据源感知到并更新,从而不用操作DOM。

v-bind:单向数据绑定,数据源改变会导致页面数据改变,但是反过来却不会

表单元素才能使用v-model指令,例如input,select,textareav-model修饰符

v-model会自动判断需要双向绑定的值,radio绑定的是checked属性,text则绑定value属性

条件渲染

vue提供条件渲染v-if和v-show进行动态控制组件的展示

v-if

动态移除元素或者创建元素

v-show

添加和移除display:none元素

v-else搭配v-if使用

列表渲染

vue提供v-for进行对列表的渲染,渲染到哪个元素给那个元素添加v-for格式形如

1
<tr v-for="index in list">

另外,v-for提供了一个可选参数,返回当前的索引

1
2
3
4
5
6
<tr v-for="(item,index) in list">
<td>{{index}}</td>
<td>{{item.name}}</td>
<td>{{item.age}}</td>
<td>{{item.sex}}</td>
</tr>

官方推荐使用v-for绑定一个key值,为每个对象的item值

1
<tr v-for="(item,index) in list" :key="item.id">

复习js删除

filter函数接受一个回调函数,返回的是过滤的条件

1
this.list=this.list.filter(item => return item.id !== id)

过滤器

只能在vue2.0中使用,常用于文本格式化

1
2
3
4
5
filters:{
format(val){
return new Date(val);
}
}

调用

1
{{val | format(val)}}
全局过滤器
1
2
3
Vue.filter('过滤器名', ()=>{
回调函数
})

使用过滤器全局格式化日期

可以使用dayjs插件快速格式化时间

注意这个过滤器要放在vue实例之前,否则不会生效

1
2
3
4
5
6
7
8
9
//定义全局过滤器,格式化时间
Vue.filter('dateformat',(time)=>{
//yyyy-MM-dd的日期格式
//使用dayjs格式化时间
const dstr= dayjs(time).format('YYYY-MM-DD');
console.log(dstr);
return dstr;

});

侦听器

监听数据的变化

1
2
3
4
5
6
watch:{
//监视谁,就把谁作为侦听器名字
username(newVal,oldVal){

}
}

对象形式的监听器

1
2
3
4
5
6
7
8
9
10
11
watch:{
username:{
handler(newVal,oldVal){

},
//是否立即触发
immediate:true,
//深度监听
deep:true
}
}

计算属性

1
2
3
4
5
computed:{
rgba(){

}
}

axios

用于发送网络请求

1
2
3
4
5
6
7
8
9
axios({
method:'',
url:'',
//get参数 ?username=''
params:{
},
//请求体参数,
data:{},
}).then((response)=>{}) //返回的是一个promise对象,可以调用then继续操作

response 对象中的data属性才是服务端返回的值方法返回promise,可以使用await修饰,

但是方法需要是async,async方法返回的是一个promise对象

1
2
3
4
5
6
7
8
9
const data= await axios({
method:'get',
//get参数 ?username=''
params:{
},
//请求体参数
data:{},
url:'https://www.escook.cn/api/finduser/'+'admin'
})

get

1
2
3
4
5
6
7
8
9
10
11
axios.get('url',{
params:{},
})
//具体事例
//axios get 和post
axios.get('https://api.uomg.com/api/rand.qinghua',{
params:{format:'json'}
}).then((res)=>{
console.log(res.data);
})

post

1
2
3
4
5
6
axios.post('url',{
username:'',
age:''
}).then(()=>{

})

挂载axios到Vue实例上

在main.js中通过原型挂载

1
2
3
//引入axios
import axios from 'axios'
Vue.prototype.$axios=axios

调用

1
this.$axios.post()

利用Cli安装Vue项目

1
2
npm i @vue/cli -g
vue create 项目名

自定义安装,选择最后一项

选择2.0版本的vue(主流)

选择less进行样式预处理

配置文件的创建,选择第一项创建项目,如果项目创建慢,设置为淘宝镜像

npm run serve 启动项目

空格是选择安装的插件,回车则是确定选择项

项目构成

assets:存放静态资源,图片,css等内容

components:存放可以重用的组件

App.vue项目的跟组件

main.js程序入口文件

1
2
3
4
5
6
import App from './App.vue'
new Vue({
render: h => h(App),
//安装的插件可以在这里使用
}).$mount('#app')
//这段代码表示,将App里面的内容渲染到index.html中

组件的data不能使用以前的对象写法,而是应该是一个函数,如下

1
2
3
4
5
data(){
return {

}
}

组件方法

1
2
3
4
5
methods:{
change(){
this.msg='芝士土拨鼠'
}
}

启用less

组件使用

使用import导入

1
2
//@指的是src目录
import Login from '@/components/Login.vue'

使用components节点注册

1
2
3
components:{
Login
}

以标签形式使用

1
<Login></Login>

全局注册组件

在main.js下面使用Vue.component(‘注册名称’,’组件名称’)

1
2
import Right from './components/Right.vue'
Vue.component('MyRight',Right)

组件之间的数据共享

props

父组件向子组件传值

1
2
3
4
5
6
//子组件定义props
props:['message']
在子组件中使用props
this.message
//父组件通过标签传值
<Son :message="哈哈哈"></Son>

默认值(使用默认值定义props)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
props:{
message:{
default:'hhh'
}
},
//type 值类型
props:{
message:{
default:'hhh',
//Number,Boolean,String Object, Array等类型
type:String
}
},
//require必选
props:{
message:{
default:'hhh',
type:String,
require:false
}
},

子传父

需要在子组件中定义事件

1
2
3
getName(){
this.$emit('numChange','传递的值')
}

父组件中

调用numChange方法

1
2
3
4
5
<NewSon @numChange="getNewName"></NewSon>
//将子组件传递过来的值接受并转存
getNewName(val){
this.name=val
}
兄弟传值

样式冲突

给属性添加scoped属性,默认会给组件的所有标签添加一个自定义属性,不会影响到其他组件的样式