目录
Vue
个人博客地址:
渐进式 – JavaScript 框架
架构模式:MVVM (最初由微软提出,设计思想) Model View ViewModel
个人理解:M (数据处理逻辑)、V(视图显示, 视图层)、VM(M和V,模型和视图之间的数据同步,交互…)
官方规定组件里面的 data 必须是一个函数 function
在 Vue 实例中,获取 data 上的数据,通过
this.数据属性名
; 获取方法,通过this.方法名
,this
代表实例对象
基础
历史介绍
angular 框架 – 2009年诞生
react – 2013年开源,用户体验好,React是最流行的一个前端框架(React除了开发网站,还可以开发手机 App)
Vue — 2014年发布 — 用户体验好; vue.js是目前最火的一个前端框架
前端框架与库的区别
jQuery库 =》DOM(操作DOM)+请求 art-template库 =》模板引擎
框架 = 全方位功能齐全; 简易的 DOM 体验 + 发请求 + 模板引擎+ 路由功能
库就是一个小套餐,框架就是全家桶; 代码上的不同:
框架:初始化自身行为、编写代码、释放资源(框架帮我们运行代码)
发展历程
原生 js => (由于兼容性产生) Jquery之类的类库 => (由于频繁字符串拼接产生) 前端模板引擎 => (由于模板引擎渲染性能问题产生) 框架 Vue/React/Angular
框架和库
框架:完整的解决方案
库(plugin):只负责实现一个小功能
jQuery ---- Zepto(移动端开发的JavaScript 库)
EJS( 模板引擎 ) ---- art-template
Node中的MVC与前端中的MVVM之间区别
MVC (Model 负责数据 crud,View 视图层 ,Control 负责数据逻辑) ---- 后端分层开发概念
MVVM(M 数据的 crud, VM 调度者,V 视图层)— 是前端视图层概念
-
- Vue的MVVM实现原理
- Vue作为MVVM模式的实现库的2种技术
a. 模板解析
b. 数据绑定 - 模板解析: 实现初始化显示
a. 解析大括号表达式
b. 解析指令 - 数据绑定: 实现更新显示
a. 通过数据劫持实现
组件化和模块化不同
模块化:是从代码逻辑角度进行划分的, 方便代码分层开发,保证每个功能模块的职能单一;组件化:是从UI界面的角度进行划分的组件化,方便UI组件的重用
开始
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>vue_hello</title>
</head>
<body>
<div id="app"></div></body>
</html>
引包
<script src="js/vue.min.js"></script>
<script src="js/vue.min.js"></script>
启动
el :通过 元素id查找根元素
var vm = new Vue({
el: "#app",
template: "<span>hello Vue</span>"
})
通过 class类名查找根元素
var vm = new Vue({
el: ".app",
template: "<span>hello Vue</span>"
})
options 参数含义
目的地, 根元素 el;内容:template;数据 data(数据属性);数据驱动视图MVVM
el 的查找方式类似于 document.querySelector方式,支持id、class
插值表达式
{{表达式}} ; 对象(不要连续三个{{{name:‘Jack’}}})正确写法:
{{ {name:‘Jack’} }}
效果图如下:
效果图如下:
字符串 {{‘内容’}}
{{表达式?‘内容’:‘内容’}}
使用样式
使用class样式
数组
<h1 :class="['red', 'thin']">这是一个</h1>
数组中使用三元表达式
<h1 :class="['red', 'thin', isTrue ? 'className' : '']">这是一个</h1>
数组中嵌套对象
<h1 :class="['red', 'thin', {'className': isTrue}]">这是一个</h1>
直接使用对象
<h1 :class="{ 'red': true, 'thin': true }">这是一个</h1>(’‘引号可带可不带)
使用内联样式
直接使用对象
<h1 :style="{ color: 'red', 'font-size': '14px'}">我是h1</h1>
注意事项:类似于font-size: ;这样的样式需要使用引号包裹,否则会出现渲染失败的情况,不会报错
使用变量
<h1 :style="styleObj">我是h1</h1>
使用数组
<h1 :style="[styleObj, styleObj1]">我是h1</h1>
自定义按键修饰符
keyCodes 的使用
Vue.config.keyCodes = {
space: 32
};
<input type=“text” class=“form-control” v-model=“name” @keyup.space=“add”>
vue 1.x版本自定义键盘修饰符
了解即可:
Vue.directive(‘on’).keyCodes.f2 = 113;
Missing class properties transform
···
Missing class properties transform 问题是我在使用class 语法,npm run serve 本地跑起来遇到的一个错误
babel.config.js 里面有个@babel/preset-env, 因为它的顺序不在presets数组的第一项,导致代码解析class语法就报错了,我调整了一下位置,重新npm run serve就好了
module.exports = {
presets: [
[“@babel/preset-env”, {
modules: false,
}],
[‘@vue/app’, {
useBuiltIns: “entry”,//添加
}],
],
“plugins”: [[“component”,
{
“libraryName”: “mint-ui”,
“style”: true,
}
],
[“import”, {
“libraryName”: “vant”,
“libraryDirectory”: “es”,
“style”: true,
}]
]
}
···
.keyCode
.13
<input type=“text” class=“form-control” v-model=“name” @keyup.13=“add”>
.enter
<input type=“text” class=“form-control” v-model=“name” @keyup.enter=“add”>
.tab
.delete
捕获“删除”和“退格”键
.esc
.space
.up
.down
.left
.right
vue生命周期
从Vue实例创建、运行、到销毁期间,总是伴随着各种各样的事件,这些事件,统称为生命周期
生命周期钩子—生命周期函数—生命周期事件(三者是同一个)
创建期间生命周期函数
var vm=new Vue({
el:‘#app’,
data:{
msg: ‘lalgllagll单纯12458999单纯’
},
methods:{},
beforeCreate() {
// console.log(this.msg);
},
created() {
// console.log(this.msg);
},
beforeMount() {
// console.log(‘test’);
},
mounted() {
// console.log(document.querySelector(‘#app’).innerHTML);
},
beforeUpdate() {
},
updated() {
},
beforeDestroy() {
},
destroyed() {
}
});
-
beforeCreate(){}
这是我们遇到的第一个生命周期函数,表示实例完全被创建出来之前,会执行它
beforeCreate() {
// console.log(this.msg);
},-
demo
var vm=new Vue({
el:‘#app’,
data:{
msg: ‘lalgllagll单纯12458999单纯’
},
methods:{},
beforeCreate() {
// console.log(this.msg);
},
created() {
console.log(this.msg);
}
});
-
-
created() {}
数据初始化好了、
eg:发送ajax请求
-
beforeMount() {}
模板在内存中渲染完成
-
mounted(){}
从内存渲染到页面上
eg:操作页面上的DOM
运行期间的生命周期函数
data数据改变触发0次或多次
- beforeUpdate() {}
- updated() {}
销毁期间的生命周期函数
- beforeDestroy() {}
- destroyed() {}
activated() {}
被激活了
-
的使用
保持激活------防止重复渲染DOM
组件
deactivated() {}
被停用了
vue-ajax
vue-resource实现get/post/jsonp请求
axios--------
参考:https://github.com/pagekit/vue-resource/tree/develop/dist
this.$http
从全局方式发送请求
Vue.http.get(‘/someUrl’).then(res => {
console.log(res.body);
}, res => {
console.error('出错了!');
});
get请求
http://vue.studyit.io/api/getlunbo
this.$http.get
this.$http.get(‘/someUrl’).then(res => {
console.log(res.body);
}, res => {
console.error(‘出错了!’);
});
post请求
http://vue.studyit.io/api/post
手动发起的post请求,默认没有表单格式,application/x-www-form…
this.$http.post
this.$http.post(‘/’, {}, { emulateJSON: true }).then((success) => {
}, (error) => {
});
jsonp请求
http://vue.studyit.io/api/jsonp
this.$http.jsonp
this.$http.jsonp(‘/’).then(res => {
});
axios
http://www.kancloud.cn/yunye/axios/234845
axios是一个基于promise的HTTP库,可以在浏览器和node.js中使用
cnpm i axios -S
import axios from ‘axios’;
Vue.prototype.$axios = axios;
存在跨域问题
全局配置
Vue.http.options = {
root: ‘http://vue.studyit.io’,
emulateJSON: true
}
this.$http.get(‘api/demo’);(使用了全局配置,url需要使用相对路径,前面不能带/)
虚拟DOM—Vnote-diff算法
vue-webpack学习
cnpm i vue@2.5.2 -S
此vue安装包不全,不完整
方式一:
import Vue from ‘…/node_modules/vue/dist/vue.js’;
方式二:
在webpack.config.js中添加resolve属性:
resolve: {
alias: {//修改Vue被导入时候的包的路径
‘vue$’: ‘vue/dist/vue.js’
}
}
.vue文件
纯粹的组件,由三部分组成
-
template
登录组件
-
script
-
style
默认是全局样式,仅仅支持CSS样式
-
scoped
样式的scoped是通过css的属性选择器实现的
标签[属性选择器] {
}
-
webpack默认无法打包.vue文件,需要安装第三方loader
cnpm i vue-loader vue-template-compiler -D
vue-loader内部依赖于vue-template-compiler(编译程序)
-
package.json
{
“name”: “vue_05”,
“version”: “1.0.0”,
“description”: “”,
“main”: “webpack.config.js”,
“scripts”: {
“test”: “echo “Error: no test specified” && exit 1”,
“dev”: “webpack-dev-server --open --port 3000”
},
“author”: “”,
“license”: “ISC”,
“devDependencies”: {
“babel-core”: “^6.26.0”,
“babel-loader”: “^7.1.2”,
“babel-plugin-component”: “^1.1.1”,
“babel-plugin-transform-remove-strict-mode”: “^0.0.2”,
“babel-plugin-transform-runtime”: “^6.23.0”,
“babel-preset-env”: “^1.6.1”,
“babel-preset-stage-0”: “^6.24.1”,
“css-loader”: “^0.28.7”,
“html-webpack-plugin”: “^2.30.1”,
“node-sass”: “^4.13.1”,
“sass-loader”: “^6.0.6”,
“style-loader”: “^0.19.0”,
“url-loader”: “^0.6.2”,
“vue-loader”: “^14.2.4”,
“vue-template-compiler”: “^2.6.11”,
“webpack”: “^3.8.1”,
“webpack-dev-server”: “^2.9.3”
},
“dependencies”: {
“bootstrap”: “^3.4.1”,
“mint-ui”: “^2.2.13”,
“moment”: “^2.24.0”,
“vue”: “^2.6.11”,
“vue-preview”: “^1.1.3”,
“vue-resource”: “^1.5.1”,
“vue-router”: “^3.1.5”,
“vuex”: “^3.1.3”
}
}
vue-router安装
cnpm i vue-router -S
抽离路由模块
router.js
//路由模块
import VueRouter from ‘vue-router’;
import account from ‘./components/Account.vue’;
import goodsList from ‘./components/GoodsList.vue’;
import login from ‘./components/subcomponents/login.vue’;
import register from ‘./components/subcomponents/register.vue’;
var router = new VueRouter({
routes: [
{
path: ‘/account’,
component: account,
children: [
{ path: ‘login’, component: login },
{ path: ‘register’, component: register }
]
},
{ path: ‘/goodslist’, component: goodsList }
]
});
export default router;
借助babel-plugin-component实现按需导入
cnpm i babel-plugin-component -D
@babel/preset-env
vue-resource使用
cnpm i vue-resource -S
import VueResource from ‘vue-resource’;
Vue.use(VueResource);
vuex
为vue.js应用程序管理状态(数据)模式的
集中式存储管理、公共数据管理工具
Vuex是为了保存组件之间共享数据而诞生的
它是一个全局的共享数据存储区域,一个数据仓库
安装
cnpm i vuex -S
import Vuex from ‘vuex’;
Vue.use(Vuex);
var store = new Vuex.Store({
state: {
//类似data,访问方式:$store.state.变量
},
mutations: {
show() {
//类似methods,建议方法写在此处
}
}
});
var vm = new Vue({
el: ‘#app’,
store
});
固定结构
var store = new Vuex.Store({
state: {
变量调用:KaTeX parse error: Expected 'EOF', got '}' at position 19: …re.state.变量名称 }̲, mutations: {…store.commit(‘方法名称’);
}
},
getters: {
负责提供数据,
变量名称:(state)=> {
return 值;
}//调用:this.$store.getters.***
}
});
-
在mutations中传递参数
1.传递一个自定义参数
mutations: {
increment(state, arg1) {
//自定义参数arg1
}
}
2.mutations方法要求最多只能有两个参数,所以需要传递多个参数,可以通过将一个对象obj传递过去
mutations: {
increment(state, obj) {
//obj.key
//this.$store.commit(‘方法名’, 参数);
}
}
1. Vuex管理状态的机制
- 是什么: Vuex 是一个专为 Vue.js 应用程序开发的状态管理的vue插件
- 作用: 集中式管理vue多个组件共享的状态和从后台获取的数据
编程式导航
:通过代码的方式实现跳转
React与Vue
1) 相同点
- 都有组件化开发和Virtual DOM
- 都支持props进行父子组件间数据通信
- 都支持数据驱动视图, 不直接操作真实DOM, 更新状态数据界面就自动更新
- 都支持服务器端渲染
- 都有支持native的方案,React的React Native,Vue的Weex
1) 不同点
- 数据绑定: vue实现了数据的双向绑定,react数据流动是单向的
- 组件写法不一样, React推荐的做法是 JSX , 也就是把HTML和CSS全都写进JavaScript了,即’all in js’; Vue推荐的做法是webpack+vue-loader的单文件组件格式,即html,css,js写在同一个文件
- state对象在react应用中不可变的,需要使用setState方法更新状态;在vue中,state对象不是必须的,数据由data属性在vue对象中管理
- virtual DOM不一样,vue会跟踪每一个组件的依赖关系,不需要重新渲染整个组件树.而对于React而言,每当应用的状态被改变时,全部组件都会重新渲染,所以react中会需要shouldComponentUpdate这个生命周期函数方法来进行控制
- React严格上只针对MVC的view层,Vue则是MVVM模式
Redux
1. Redux管理状态的机制
1) 对Redux基本理解
- redux是一个独立专门用于做状态管理的JS库, 不是react插件库
- 它可以用在react, angular, vue等项目中, 但基本与react配合使用
- 作用: 集中式管理react应用中多个组件共享的状态和从后台获取的数据
1) Redux的工作原理
1) Redux使用扩展
- 使用react-redux简化redux的编码
- 使用redux-thunk实现redux的异步编程
- 使用Redux DevTools实现chrome中redux的调试
指令系统v-内容
以v-xxx表示
angular中以ng-xxx开头
指令中封装了一些Dom行为,结合属性作为暗号,操作绑定
v-text v-if(切换开销) v-else-if v-else v-show(渲染开销)
v-html v-for(优先级最高)
v-cloak
使用v-cloak能够解决插值表达式闪烁问题
{{ msg }}
//插值表达式{{ msg }}
[v-cloak] {
display: none;
}
v-text
-
v-text和插值表达式的区别
1.默认v-text是没有闪烁问题
2.v-text会覆盖元素中原本的内容,但是插值表达式只会替换自己的这个占位符,不会把整个元素的内容清空
v-html
v-bind使用
v-bind:class=“内容”—增加属性
–单向数据绑定
可以简写为 “ : ”;
<input type="button" value="按钮" :title="myTitle + '这里面可以拼接字符'">
-
v-bind:是Vue中,提供的用于绑定属性的指令
告诉浏览器属性值是一个变量
浏览器寻找变量对应的值v-bind:或:(两种不同的写法)可以书写合法的js表达式
方式1:
方式2:
-
v-bind只能实现数据的单向绑定,从M自动绑定到V
v-on
绑定事件,可以简写为“ @ ”;
v-on:input=‘change’
@click.native
-
Vue中提供了v-on:事件绑定机制
或者:
<input type=“button” value=“按钮” :title=“myTitle + ‘这里面可以拼接字符’” @click=“show”> -
事件修饰符
-
使用.stop阻止冒泡
<input type=“button” value=“戳他” @click.stop=“btnHandler”>
-
.stop和.self区别
.self只会阻止自身冒泡行为的触发,并不会真正阻止冒泡的行为
-
-
使用.prevent阻止默认行为
<a href=“http:www.baidu.com” @click.prevent=“linkHandler”>百度一下
-
给父级添加.capture使用捕获模式
父级到子级<div class=“inner” @click.capture=“divHandler”>
-
使用.self实现只有单击当前元素时候,才会触发事件处理函数
-
v-model
–双向数据绑定
只适用于有value的情况
-
唯一一个可以实现数据双向绑定的指令
v-model只能运用在表单元素中
v-for
1.普通数组
{{item}}
<p v-for="(item, i) in list">{{ i }} ------------- {{item}}</p>
2.复杂数组
[
{…},
{…}
]
3.对象
user: {
id: 1,
name: ‘zs’,
gender: ‘男’
}
{{ item }} — {{ key }}
-
迭代数字
{{ count }}
count从1开始 -
注意事项
v-for 循环,key属性只能使用number或者string
key必须使用v-bind绑定<p v-for="item in list" :key="item.id">
v-if和v-show
v-if的特点:每次都会重新删除或创建元素
v-show的特点:每次不会重新进行DOM的删除和创建操作,只是切换元素的显示属性
v-if
v-show
- v-if消耗切换性能
- v-show消耗初始渲染性能
自定义全局指令
Vue.directive(‘focus’, {//定义不带v-
bind: function (el) {
console.log(‘test1’);
},//还未渲染
inserted: function (el) {
console.log(‘test2’);
el.focus();
},//渲染到页面
updated: function () {
// console.log(‘test3’);
}
});
-
v-color
Vue.directive({
bind: function (el, color) {
el.style.color = color.value;
}
});
私有指令
directives: {
color: {
bind: function (el, color) {
el.style.color = color.value;
}
}
}
钩子函数简写
当inserted函数不需要执行相关代码操作,可以将bind和updated钩子函数简写:
Vue.directive(‘指令名称’, function (el, 参数){
执行操作
});
definedProperty ?
vue-动画
transition
使用过渡类名
这是一个h3
.v-enter ,
.v-leave-to {
opacity: 0;
transform: translateX(150px);
/transform: translate(300px, 0px);/
}
.v-enter-active ,
.v-leave-active {
transition: all .5s ease;
}
name的使用
.my-enter ,
.my-leave-to {
opacity: 0;
transform: translateY(150px);
/transform: translate(300px, 0px);/
}
.my-enter-active ,
.my-leave-active {
transition: all .5s ease;
}
这是一个h3
animate.css第三方动画库
这是一个h3
半场动画
<transition
@before-enter=“beforeEnter”
@enter=“enter”
@after-enter=“afterEnter”
@enter-cancelled=“enterCancelled”
>
methods:{
beforeEnter(el) {
el.style.transform = “translate(0, 0)”;
},
enter(el, done) {
el.offsetWidth
el.style.transform = “translate(150px, 450px)”;
el.style.transition = “all 1s ease”;
done();
//afterEnter的引用
},
afterEnter(el) {
this.flag = false;
},
enterCancelled(el) {
}
}
列表过渡
当过渡元素是v-for循环渲染出来的,需要使用transition-group包裹
- {{ item.id }} --- {{ item.name }}
.v-enter ,
.v-leave-to {
opacity: 0;
transform: translateY(80px);
}
.v-enter-active ,
.v-leave-active {
transition: all 1s ease;
}
-
demo
.v-leave-active {
position: absolute;
}
.v-move {
transform: all 1s ease;
} -
appear的使用
组件
组件的出现,就是为了去拆分vue实例的代码量,能够让我们以不同的组件,来划分不同的功能模块,将来需要什么功能,就去调用对应的组件即可
局部
-
私有
私有组件定义:
components: {
login: {
template: ‘我是h1
’
}
}或:
var vm=new Vue({
el:‘#app’,
data:{},
methods:{},
components: {
login: {
template: ‘#temp2’
}
}
});
全局
全局组件(公共组件)
Vue.component(‘Vbtn’,{
template:内容
});
Vue.component(‘mycom1’, {
data() {
return {
msg: ‘哈哈哈’
};
},
template: ‘
{{ msg }}
’});
或:
Vue.component(‘mycom1’, {
data: function () {
return {
msg: ‘123’
};
},
template: ‘
{{ msg }}
’});
—插头,
slot—name=’two‘
slot = ‘two’
-
通过Vue.extend({})来创建全局组件
1.组件模板对象创建
var com1 = Vue.extend({
template: ‘这是h3
’
});
2.定义组件
Vue.component(‘myCom1’, com1);
Vue.component(‘组件名称’, 组件模板对象);当组件名称是驼峰命名myCom1,使用方式是
或
名称不是驼峰命名mycom1,使用方式: -
方式二
Vue.component(‘myCom1’, Vue.extend({
template: ‘这是h3
’
}));或:
Vue.component(‘myCom1’, {
template: ‘这是h3
’
}); -
方式三
Vue.component(‘myCom1’, {
(在#app外定义)
template: ‘#temp’
});我是h4
组件切换
-
v-if和v-else使用
-
component的使用
它是一个占位符分,:is属性,可以用来指定要展示的组件的名称
</component>
Vue.component(‘login’, {
template: ‘登录组件
’
});
Vue.component(‘register’, {
template: ‘注册组件
’
}); -
组件切换动画
(先出后进)通过mode属性,设置组件切换时候的模式
父组件通信到子组件
子组件无法访问到父组件中data数据
父组件,子组件通过属性绑定(v-bind:)访问父组件数据
var vm=new Vue({
el:‘#app’,
data: {
msg: ‘哈哈哈’
},
methods:{},
components: {
com1: {
template: ‘
这是h1 — {{ parentmsg }}
’,props: [
‘parentmsg’
]
}
}
});
data() {}和props区别
1.data是子组件自身私有,可读可写
2.props是负责定义父组件传递过来的属性,属性值只读
props: {
serviceConfig: {
type: Object,
require: true, // 表示该属性是必要的
},
},
方法传递
使用事件绑定机制
<com1 @func=“show”>
components: {
com1: {
template: ‘<h1 @click=“myclick”>这是h1 —’,
methods: {
myclick() {
// console.log(‘test’);
this.$emit(‘func’);
}
}
}
}
emit—触发、调用
-
demo
var vm=new Vue({
el:‘#app’,
data: {
msg: ‘哈哈哈’,
sonfrommsg: null
},
methods:{
show(data) {
this.sonfrommsg = data;
}
},
components: {
com1: {
data() {
return {
sonmsg: ‘哈哈哈’
};
},
template: ‘<h1 @click=“myclick”>这是h1 —’,
methods: {
myclick() {
this.$emit(‘func’, this.sonmsg);
}
}
}
}
});
1) 通信种类
- 父组件向子组件通信
- 子组件向父组件通信
- 隔代组件间通信
- 兄弟组件间通信
1) 实现通信方式
- props
问题2:props 组件属性中key 的required 表示该属性需必传
props: {
// route object
item: {
type: Object,
required: true
},
- vue自定义事件
- 消息订阅与发布
- vuex
- slot
-
-
方式1: props
-
通过一般属性实现父向子通信
-
通过函数属性实现子向父通信
-
缺点: 隔代组件和兄弟组件间通信比较麻烦
-
-
-
方式2: vue自定义事件
-
vue内置实现, 可以代替函数类型的props
a. 绑定监听: <MyComp @eventName=“callback”
b. 触发(分发)事件: this.$emit(“eventName”, data) -
缺点: 只适合于子向父通信
-
-
-
方式3: 消息订阅与发布
-
需要引入消息订阅与发布的实现库, 如: pubsub-js
a. 订阅消息: PubSub.subscribe(‘msg’, (msg, data)=>{})
b. 发布消息: PubSub.publish(‘msg’, data) -
优点: 此方式可用于任意关系组件间通信
-
-
-
方式4: vuex
-
是什么: vuex是vue官方提供的集中式管理vue多组件共享状态数据的vue插件
-
优点: 对组件间关系没有限制, 且相比于pubsub库管理更集中, 更方便
-
-
方式5: slot
- 是什么: 专门用来实现父向子传递带数据的标签
a. 子组件
b. 父组件 - 注意: 通信的标签模板是在父组件中解析好后再传递给子组件的
- 是什么: 专门用来实现父向子传递带数据的标签
获取DOM元素和组件
ref-----reference(引用)
哈哈哈
console.log(this.$refs.myH3.innerText);
render渲染组件
var login = {
template: ‘
登录
’}
var vm = new Vue({
el: '#app',
data: {},
methods: {},
render(creEle) {//return结果会替换页面el指定的容器
return creEle(login);
}//creEle是一个方法,调用它,能够把指定的组件模板,渲染为html结构
});
路由
组件缓存
组件后端路由
对于普通网站,所有的超链接都是URL地址,所有的URL地址都对应服务器上对应的资源
前端路由
对于单页面应用程序来说,主要通过URL中的hash(#号)来实现不同页面之间的切换
hash:特点:http请求不包含hash
http://www.baidu.com/#/login
参考网站:https://router.vuejs.org/zh/guide/
vue-router基本使用
2.var routerObj = new VueRouter({
routes: [
//路由匹配规则
{ path: ‘/login’, component: login },//path–表示监听的路由链接地址,component–组件模板对象,如果匹配到前面的path,则显示对应的组件
{ path: ‘/register’, component: register }
]
});
3.var vm=new Vue({
el:‘#app’,
data: {},
methods: {},
router: routerObj //注册路由规则对象,负责监听URL地址变化
});
4.登录组件
注册组件
//组件占位符
-
router-link的使用
相当于超链接
-
redirect使用
重定向,修改hash值
var routerObj = new VueRouter({
routes: [
{ path: ‘/’, redirect: ‘/login’ },
{ path: ‘/login’, component: login },//path–表示监听的路由链接地址,component–组件模板对象,如果匹配到前面的path,则显示对应的组件
{ path: ‘/register’, component: register }
]//路由匹配规则
});
高亮显示
.router-link-active ,
.myactive {
color: red;
font-size: 80px;
font-style: italic;
font-weight: 800;
}
-
自定义类名
var routerObj = new VueRouter({
routes: [
{ path: ‘/’, redirect: ‘/login’ },
{ path: ‘/login’, component: login },//path–表示监听的路由链接地址,component–组件模板对象,如果匹配到前面的path,则显示对应的组件
{ path: ‘/register’, component: register }
],//路由匹配规则
linkActiveClass: ‘myactive’
//类名
});
路由添加动画
- transition
路由传参
-
方式一
登录
获取参数:
var login = {
data() {
return {}; }, created() { console.log(this.$route.query.id); }, template: '<h1>登录</h1>' };
-
方式二
登录
{ path: ‘/login/:id’, component: login },
var login = {
data() {
return {}; }, created() { }, template: '<h1>登录 --- {{ $route.params.id }} </h1>' };
-
方式三
路由嵌套
var router = new VueRouter({
routes: [
{ path: ‘/’, redirect: ‘/account’ },
{ path: ‘/account’,
component: account,
children: [//子路由
{ path: ‘login’, component: login },
{ path: ‘register’, component: register }
],
name: ‘路由名称’//用于编程式导航
}
]
});
编程式导航
1.router.push();
2.this.
r
o
u
t
e
r
.
p
u
s
h
(
′
/
h
o
m
e
′
)
;
3.
t
h
i
s
.
router.push('/home'); 3.this.
router.push(′/home′);3.this.router.push({ path: ‘/home’ });
4.this.
r
o
u
t
e
r
.
p
u
s
h
(
n
a
m
e
:
′
路由名
称
′
,
p
a
r
a
m
s
:
i
d
:
25
)
;
5.
t
h
i
s
.
router.push({ name: '路由名称', params: { id: 25 } }); 5.this.
router.push(name:′路由名称′,params:id:25);5.this.router.push({ path: ‘home’, query: { id: 25} });
-
this. r o u t e 和 t h i s . route和this. route和this.router区分
1.this. r o u t e 是路由参数对象,所有路由中的参数, p a r a m s , q u e r y 2. t h i s . route是路由参数对象,所有路由中的参数,params, query 2.this. route是路由参数对象,所有路由中的参数,params,query2.this.router是一个路由导航对象,用它实现路由的前进后退
-
back()
-
forward()
-
go(n)
命名视图–经典布局
var router = new VueRouter({
routes: [
{
path: ‘/’,
components: {
default: header,
left: leftBox,
main: mainBox
}
}
]
});
过滤器
filters: {
myCurrentcy:function(value){
return ‘¥’+value;
}
}
//调用过滤器
price | myCurrentcy—调用
过滤器
Vue.js允许你自定义过滤器,可被应用一些常见的文本格式化,过滤器可以用在两个地方:mustache插值和v-bind表达式。过滤器应该被添加在javascript表达式的尾部,由“管道”符(“ | ”)指示;
-
私有过滤器
过滤器调用:采用就近原则,如果私有过滤器和全局过滤器同名,优先调用私有过滤器
-
demo
filters: {
timeFormat: function (time, pattern=‘’) {
var tdate = new Date(time);
var y = tdate.getFullYear();
var m = tdate.getMonth() + 1;
var d = tdate.getDate();if (pattern.toLowerCase() === 'yyyy-mm-dd') { return `${ y }-${ m }-${ d }`; } else { var h = tdate.getHours() >= 10 ? tdate.getHours() : '0' + tdate.getHours(); var M = tdate.getMinutes() >= 10 ? tdate.getMinutes() : '0' + tdate.getMinutes(); var s = tdate.getSeconds() >= 10 ? tdate.getSeconds() : '0' + tdate.getSeconds(); return `${ y }-${ m }-${ d } ${ h }:${ M }:${ s }`; } } }
-
node中moment.js可以解决时间格式化问题
格式化时间cnpm i moment -S
import moment from ‘moment’;
moment(date).format(pattern);
-
全局过滤器
Vue.filter(数据名称, function(value){
return ;
});
-
demo
Vue.filter(‘msgFormat’, function (msg) {
return msg.replace(/单纯/g, ‘邪恶’);
});var vm=new Vue({ el:'#app', data:{ msg: 'lalgllagll单纯12458999单纯' }, methods:{} });
-
传参
{{ msg | msgFormat('哈哈哈谁') }}
Vue.filter(‘msgFormat’, function (msg, arg) {
return msg.replace(/单纯/g, arg);
}); -
多个过滤器
{{ msg | msgFormat('哈哈哈谁') | test }}
watch {}
监听单个属性
watch: {//msg表示需要监视的属性
msg(newV, oldV) {
if (newV === ‘aaa’) {
console.log(‘出来了’);
}
}
}
深度监视
监听复杂数据类型
watch: {
msg(newV, oldV) {
if (newV === ‘aaa’) {
console.log(‘出来了’);
}
},
stus: {
deep: true,
handler(newV, oldV) {
console.log(newV[0].name);
}
}
}
demo
watch: {
firstname(newV, oldV) {
this.fullname = this.firstname + ‘-’ + this.lastname;
},
lastname(newV, oldV) {
this.fullname = this.firstname + ‘-’ + this.lastname;
},
stus: {
deep: true,
handler(newV, oldV) {
}
}
}
‘$route.path’: function(newVal) {
路由参数对象
computed {}
监听多个属性
默认只有getter()
computed: {
getMusicSrc() {
return this.musics[this.currentIndex].songSrc;
},
fullname: {
get() {},
set() {}
},
自定义属性() {
return value;//应用{{ 自定义属性 }}
}
}
框架
elementUI
主要用于制作pc端桌面
饿了么-MintUI组件
import MintUI from ‘mint-ui’;//组件导入
import ‘mint-ui/lib/style.css’;//样式导入
Vue.use(MintUI);
(按需引入)推荐写法:
import { Cell, Checklist } from ‘mint-ui’;
Vue.component(Cell.name, Cell);
Vue.component(Checklist.name, Checklist);//Cell.name—可以是自定义名称
参考:mint-ui.github.io/#!/zh-cn
-
安装
vue 1.x--------------npm i mint-ui@1 -S
Vue2.x --------------npm install mint-ui -S
引入全部组件
import Vue from ‘vue’;
import Mint from ‘mint-ui’;
Vue.use(Mint); -
JS-Components
-
Toast组件使用
-
详细参数
Toast({
message: ‘叮当猫,哈哈哈’,
position: ‘bottom’,
duration: 5000,
iconClass: ‘glyphicon glyphicon-star’,
className: ‘mytoast’//自定义Toast的样式,自定义类名
}); -
demo
getList() {
let instance = this.show();
setTimeout(() => {
instance.close();
}, 3000);
},
show() {
return Toast({
message: ‘叮当猫,哈哈哈’,
position: ‘bottom’,
duration: 5000,
iconClass: ‘glyphicon glyphicon-star’,
className: ‘mytoast’
});
}
-
-
-
CSS-Components
-
按钮组件使用
登录
-
MUI
Bootstrap
MUI不同于Mint-UI,MUI只是开发出来的一套好用的代码片段,里面提供了配套的样式、配套的HTML代码段,类似于Bootstrap;而Mint-UI是真正的组件库,是使用Vue技术封装出来的,和VUE项目进行集成开发;
MUI和Bootstrap类似(他们任何项目都可以使用),Mint-UI只适用于Vue项目
参考地址:http://dev.dcloud.net.cn/mui/
http://dev.dcloud.net.cn/mui/ui/
-
图标icon
-
样式导入
import ‘bootstrap/dist/css/bootstrap.css’;
vue-preview
一个vue集成photoswipe图片预览插件
参考网站:github.com/LS1231/vue-preview
-
使用
1.cnpm i vue-preview -S
2.import VuePreview from ‘vue-preview’;
3.Vue.use(VuePreview);
4.
5…thumbs {
/deep/ .my-gallery{
display: flex;
flex-wrap:wrap;
figure{
width: 30%;
margin: 5px;
img{
width: 100%;
box-shadow: 0 0 8px #999;
border-radius: 5px;
}
}
}
}
vue3.0
composition api—组合式api
vue.global.js
setup(){}—入口
启动、创建(默认执行一次)
创建响应式数据
let state = Vue.reative({ name: ‘zs’ });
vue开源项目库汇总
https://segmentfault.com/p/1210000008583242/read?from=timeline
vue awesome
猫途鹰、Bing
VS-Code开发工具使用
自定义代码片段(快捷键)
1.文件=》 首选项=》用户代码片段
{
“vh”: {
“prefix”: “vh”, // 触发的关键字 输入vh按下tab键
“body”: [" ", “模板代码段”],
“description”: “描述”
}
}
代码编辑
代码行向左或向右缩进: Ctrl+[ 、 Ctrl+]
复制或剪切当前行/当前选中内容: Ctrl+C 、 Ctrl+V
代码格式化: Shift+Alt+F
向上或向下移动一行: Alt+Up 或 Alt+Down
向上或向下复制一行: Shift+Alt+Up 或 Shift+Alt+Down
在当前行下方插入一行: Ctrl+Enter
在当前行上方插入一行: Ctrl+Shift+Enter
删除当前行:
Ctrl + shift + k
光标
移动到行首: Home
移动到行尾: End
移动到文件结尾: Ctrl+End
移动到文件开头: Ctrl+Home
移动到定义处: F12
查看定义处缩略图(只看一眼而不跳转过去): Alt+F12
选择从光标到行尾的内容: Shift+End
选择从光标到行首的内容: Shift+Home
删除光标右侧的所有内容(当前行): Ctrl+Delete
扩展/缩小选取范围: Shift+Alt+Right 和 Shift+Alt+Left
多行编辑(列编辑): Alt+Shift+鼠标左键 或 Ctrl+Alt+Down/Up
同时选中所有匹配编辑(与当前行或选定内容匹配): Ctrl+Shift+L
下一个匹配的也被选中: Ctrl+D
回退上一个光标操作: Ctrl+U
撤销上一步操作: Ctrl+Z
手动保存: Ctrl+S
VS-Code相关扩展
Vetur----Vue tooling for VS Code
Bootstrap 3 Snippets
C/C++
Express
Material Icon Theme
View In Browser
Vue 2 Snippets