简介
vue: 一套用于构建用户界面的渐进式框架。
如何渐进
可理解为分别对应:
- 非常简单的页面
- 比较大点的页面
- SPA(单页面应用)
- 数据管理 vuex
- 脚手架 vue-cli
单页应用
- 定义:
页 -> HTML,所以 单页 -> 只有一个HTML 文件
- 特点
- 页面中的交互是不刷新页面的
- 加载过的公共资源,无需重复加载(除了首页之外的页面,都通过异步组件方式注册)
特点
- 易用:会HTML,css,js即可上手。
- 灵活:不断繁荣的生态系统,可以在一个库和一套完整框架之间自如伸缩。
- 高效:20kb min+gzip运行大小,超快虚拟DOM,最省心的优化。
简单使用
// 引入cdn
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
<div id="app">
{{ a }}
</div>
<script>
const vm = new Vue({
el: '#app',
data: {
a: 10,
}
})
</script>
语法
v-bind 和 v-on
v-bind
绑定属性
v-bind == :
// 完整语法
<a v-bind:href="url">...</a>
// 缩写
<a :href="url">...</a>
v-on
事件监听
v-on == @
// 完整语法
<a v-on:click="doSomething">...</a>
// 缩写
<a @click="doSomething">...</a>
<div id="app">
<img :src='imgUrl' />
<button @:click='clickBtn()'></button>
</div>
<script>
data(){
return {
imgUrl: '...',
}
} ,
methods: {
clickBtn(){
// to do...
}
}
</script>
绑定class、style
- class 绑定
:class='[redClass,blueClass,...]';
:class='{redClass: true,blueClass: false,...}';
:class='[{redClass: true},blueClass]';
- style 绑定
:style="{width: widthClass,border: '1px solid red'}";
:style="[{width: widthClass},imgStyle]"
v-if 和 v-show
- 条件渲染:控制元素的显示与隐藏
注:如果不想要 div,v-if
可以用 template;v-show
则不能使用
- 区别
v-if
控制的 dom 的移除/添加。v-show
控制 dom 的样式显示/隐藏( display )- 频换的切换显示/隐藏 使用
v-show
;只判断一次时,使用v-if
v-for
- 列表渲染:基于一个数组来渲染一个列表
key 类型:number、string;唯一的;作用:可提高页面性能
arr: (item,index) in arr
<ul>
<li v-for="item in arr">{{ item }}</li>
// index 数组的索引
<li v-for="(item,index) in arr">{{ item }} -- {{ index }}</li>
</ul>
obj: (value,key,index) in obj
<ul>
<li v-for="value in obj">{{ value }}</li>
// value 属性名,key 属性值,index 索引
<li v-for="(value,key,index) in obj">{{ value }} -- {{ key }} -- {{ index }}</li>
</ul>
num: num in number
<p v-for="item in 10">{{ item }}</p> // 1 ... 10
str: str in string
<p v-for="str in 'fuj'">{{ str }}</p> // f u j
v-model
- 双向数据绑定:数据驱动视图,视图驱动数据
注:v-model
实际上就是 :value + @input
的语法糖。
// 视图驱动数据:改变视图中input的数据,使得p中的数据随之改变
<div id="app">
<input type="text" :value="value" @input='handleInput' />
<p>{{ value }}</p>
</div>
<script>
const vm = new Vue({
el: '#app',
data: {
value: 'fj', // 数据驱动视图:数据在视图中显示
},
methods: {
handleInput(e) {
this.value = e.target.value;
}
}
})
</script>
// checked: true/false
<input type="checkbox" v-model='checked' />
// checkList: [html,css]
<input type="checkbox" value="html" v-model="checkList" />
<input type="checkbox" value="css" v-model="checkList" />
// radioStr: 'html'/'css'
<input type="radio" value='html' v-model='radioStr' />
<input type="radio" value='css' v-model='radioStr' />
// selected: 'html'/'css'
<select v-model="selected">
<option value="html">html</option>
<option value="css">css</option>
</select>
计算属性watch 和 侦听器computed
vue中数据查找顺序:data、methods、computed
methods
:写一些逻辑的时候,触发一个事件的时候;函数封装的时候computed
: 要得到一个新的数据的时候watch
:当在某个数据改变要做某个事情的时候
<div id="app">
// methods
{{ desc() }}
// computed 注意此时 desc 不是写成 desc()
{{ desc }}
// watch
{{ desc }}
</div>
<script>
const vm = new Vue({
el: '#app',
data: {
name: 'fj',
age: '16',
},
methods: {
// 页面重新渲染,造成数据改变,无论执行否 desc,都会执行一次 desc。造成页面性能不好
desc() {
return `name: ${this.name},age: ${this.age}`;
}
},
computed: {
desc() {
return `name: ${this.name},age: ${this.age}`;
}
},
watch: { // 如果监听的内容多的话,用watch也不合适。
name() { // 想监听哪个数据,就把哪个数据作为函数写在里面
this.desc = `name: ${this.name},age: ${this.age}`;
}
},
})
</script>
生命周期
beforeCreate
:组件实例化之前执行的函数(可写一些加载的效果)created
:组件实例化完毕,但页面还未显示(一般在这里面写请求到的数据)监听data中数据。beforeMount
:组件挂载前,页面仍未显示,但虚拟DOM已经配置了mounted
:组件挂载后,此方法执行后,页面显示。监听页面DOM渲染完毕。beforeUpdate
:组件更新前,页面仍未更新,但虚拟DOM已经配置updated
:组件更新,此方法执行,页面显示更新后的。监听methods中方法执行后对DOM的改变beforeDestory
:组件销毁前destoryed
:组件销毁
第一次页面加载会触发的钩子:beforeCreate,created,beforeMount,mounted
请求数据 axios
// 安装 axios
cnpm i axios --save-dev
- 局部使用
// 所用页面
import axios from 'axios'
axios.get(url,{}).then(res=>{
// ...
})
- 全局使用
// main.js
import axios from 'axios'
Vue.prototype.$axios = axios
axios.defaults.baseURL = '...com'
...
// 页面中
this.$axios.posturl,{}).then(res=>{
// ...
})
脚手架 vue-cli
脚手架:自动的构建一个项目、使用 ES6 语法、打包和压缩 js 为一个文件、项目文件在环境中编译而不是浏览器…
// 查看 node 版本
node -v (node > 8.9)
// 如果之前已经安装过旧版本(非3.X)脚手架,需要先卸载旧版本
npm uninstall vue-cli -g
// 安装脚手架,用于生成项目
npm install -g @vue/cli
// 快速原型开发,编译.vue文件
npm install -g @vue/cli-service-global
// 运行 vue文件
vue serve App.vue(文件名)
// 查看 vue-cli 版本
vue -V
// 如果仍然需要使用旧版本的 vue init 功能,可以全局安装一个桥接工具
npm install -g @vue/cli-init
// 利用脚手架搭建项目
vue create vue-app
// 运行
npm run dev
// 打包
npm run build
// vsCode 安装插件名字:Vetur
// 安装时一些插件
babel: ES6转为ES5;
eslint: 规范代码风格;
TypeScript: 简称TS,写一些大型项目或者框架的时候用;
pwa: 初始进入网页耗费流量,再进就不耗费了,相当于缓存;
Router: 切换页面;
Vuex: 管理数据、状态的时候用到;
CSS Pre-..: css预处理语言:sass、less...;
// 目录结构
node_modules: 安装的包
public: 相当于根目录,可以放一些图片、json(绝对路径,不会经过webpack处理)
(接口未提供时,可以在这里面造些假数据,直接通过根目录就能访问)
.gitignore: 里面放不用上传到git的一些文件;
babel.config: 配置babel的;
package.json: 项目的信息;
package-lock.json: 依赖包文件里面包的一些信息;
README: 对项目的一些描述;
src/assets: 放置一些资源,图片、css(相对路径,经过webpack处理)
src/components: 放置一些组件;
src/App.vue: 主入口的一个组件
src/main.js:
经过webpack处理后会生成哈希类型,不会被缓存,会实时更新。
// main.js
import Vue from 'vue'; // 表示从包里面引入;
import App from './App.vue'; // 表示从页面引入;
Vue.config.productionTip = false; // 生产环境下没有命令行的警告;
new Vue({
render: h=>h(App), // 虚拟对象转换为真实对象
}).$mount('#app') // 函数实例化,并挂载在#app上
// 打包时根目录下新增:vue.config.js
module.exports = {
publicPath: process.env.NODE_ENV === 'production'
? './'
: '/'
}
// 在vue-cli.3.3版本后 baseUrl被废除了,因此这边要写成 publicPath。
其他
ref
- ref:DOM对象的引用是该对象,组件的引用是组件的实例对象;
- ref 同名时,后添加的会覆盖前面的,引用指向的最后一个元素;
- 在 v-for 时添加引用,引用的值类型时数组,数组里面一个个的dom对象/组件实例对象。
<div ref='box'>123</div>
console.log(this.$refs.box.innerHTML); // 123
$nextTick
vm.a = 20;
console.log(vm.a); // 20
// 更改数据是同步的,但是更改过后要去视图更新的操作是异步的。
// 此时页面也是20,但是下面打印10
console.log(vm.$el.innerHTML); // 10
// 等待dom执行后再执行。
vm.$nextTick
vm.$nextTick(()=>{
console.log(vm.$el.innerHTML); // 20
})
vm.$mount('#app'); == el: '#app';
框架和库的区别
- 库:将代码集合成一个 产品,供开发者去使用,开发者去调用库中的方法去实现自己的功能。(控制权在自己手里,想用库就用不想用就用原生)
例子:jQuery、zepto…
- 框架:为了解决一类问题而开发出来的产品,基于自身的特点向用户提供一套完整的解决方案。(控制权在框架手里,里面的规则方法要遵守)
例子:vue、react…