vue: 渐进式JavaScript 框架

Vue项目构建

npm install -g vue
vue init webpack-simple my-project
cd my-project
npm install
npm run dev

vue项目开发步骤

  • 根据原型稿拆分组件——》路由组件(pages)、复用组件(components)
  • 根据路由组件定好路由router/index.js
  • 看后端接口文档写好api/ajax、index请求好数据,有些时候后端没写好接口则需要自己mock数据
  • 确定好共享的状态数据,写好store
  • 分别用复用组件开发路由组件

Vue知识总结

Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层

模块化与组件化的区别:

  • 1.模块化是针对代码来说的,即抽离js代码进行复用
  • 2.组件化是针对Ui来说的,由组件就能很快组成一个页面

vue与react的比较

  • 1.Vue里使用.vue格式模板实现组件化,而react采用把html写进js即jsx
  • 2.vue是双向数据绑定,react是单向数据绑定,在通过state来管理

声明式渲染

<div id="app">
{{ message }}
</div>
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
})

条件与循环

<div id="app-3">
<p v-if="seen">现在你看到我了</p>
</div>
var app3 = new Vue({
el: '#app-3',
data: {
seen: true
}
})

处理用户输入

v-on 指令添加一个事件监听器,通过它调用在 Vue 实例中定义的方法

v-on:click = @click 事件

组件化应用构建

全局定义组件

// 定义名为 todo-item 的新组件
Vue.component('todo-item', {
template: '<li>这是个待办项</li>'
})
<ol>
<!-- 创建一个 todo-item 组件的实例 -->
<todo-item></todo-item>
</ol>

vue生命周期

)

vue指令

v-html绑定html

v-text绑定文本

v-bind:属性 = :属性 绑定属性

v-on:click = @click 事件

v-class

<ul  v-for="item in list1">
<li :class='{red: flag, blue: !flag}'>{{item}}</li>
</ul>

v-style

<div class="box" :style="{'width': boxWidth+'px'}">

</div>

获取ref定义的dom节点

<input type="text" ref="userInfo">
<div ref="box"></div>
<button @click="getValue()">点击</button>
export default {
data(){
return {
message: '这是一个根组件',
}
},
methods: {
getValue(){
console.log(this.$refs.userInfo);
this.$refs.box.style.background='red';
alert(this.$refs.userInfo.value);
}
}
}

修饰符

  • sync:在2.3.0+版本之后,vue又重新引进了.sync这个修饰符了,这个修饰符可以让子组件的数据带动父组件的数据改动。但是除了这个修饰符,我们还要在子组件里面添加一个watch 监测事件来,触发修改父组件的数据。

自定义属性

1.html里设置data-xx

2.把$event传给事件

3.事件利用e.srcElement.dataset.aid获取 或

e.srcElement.style.background='red';修改样式

<button data-aid='123' @click="eventFn($event)">事件对象</button>
export default {
data () {
return {
msg: '你好vue',
list:[]
}
},
methods:{
eventFn(e){
console.log(e);
// e.srcElement dom节点
e.srcElement.style.background='red';
console.log(e.srcElement.dataset.aid);//123 /*获取自定义属性的值*/
} }
}

vue父子组件通信

1、父组件可以使用 props 把数据传给子组件。

2、子组件可以使用 $emit 触发父组件的自定义事件。

vm.$emit( event, arg ) //触发当前实例上的事件

vm.$on( event, fn );//监听event事件后运行 fn;

例如:

子组件:

<template>
<div class="train-city">
<h3>父组件传给子组件的toCity:{{sendData}}</h3>
<br/><button @click='select(`大连`)'>点击此处将‘大连’发射给父组件</button>
</div>
</template>
<script>
export default {
name:'trainCity',
props:['sendData'], // 用来接收父组件传给子组件的数据
methods:{
select(val) {
let data = {
cityname: val
};
this.$emit('showCityName',data);//select事件触发后,自动触发showCityName事件
}
}
}
</script>

父组件:

<template>
<div>父组件的toCity{{toCity}}</div>
<train-city @showCityName="updateCity" :sendData="toCity"></train-city>
<template>
<script>
import TrainCity from "./train-city";
export default {
name:'index',
components: {TrainCity},
data () {
return {
toCity:"北京"
}
},
methods:{
updateCity(data){//触发子组件城市选择-选择城市的事件
this.toCity = data.cityname;//改变了父组件的值
console.log('toCity:'+this.toCity)
}
}
}
</script>

同级通信

<body>
<div id="app">
<huahua></huahua>
<shuandan></shuandan>
</div>
<script src="./vue.js"></script>
<script>
let Event = new Vue();
Vue.component('huahua', {
template: `<div>我说:<input v-model='i_said' @keyup='onChange'></div>`,
data: function(){
return {
i_said: ''
}
},
methods: {
onChange: function(){
Event.$emit('huahua-said-something', this.i_said);
}
}
});
Vue.component('shuandan', {
template: '<div>花花说:{{huahua_said}}</div>',
data: function(){
return {
huahua_said: ''
}
},
mounted: function(){
let _this = this;
console.log(_this);
Event.$on('huahua-said-something', function(data){
console.log('data', data);
//console.log('this', this);
_this.huahua_said = data;
})
}
})
let app = new Vue({
el: '#app'
})
</script>

vue中的注意点:

1.component中的data必须是函数

Vue.component('', {
template: '<div></div>',
data: function(){
return {
huahua_said: ''
}
}
})

2.为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一 key 属性。理想的 key 值是每项都有的且唯一的 id。

<div v-for="item in items" :key="item.id">
<!-- 内容 -->
</div>

vue组件库的使用。

element-ui使用局部引入使用

1.在组件里import { Table, TableColumn } from "element-ui";

2.components: {Table, TableColumn}

3.<Table></Table>、<table-column type="selection" width="55"></table-column>全局引入使用

1.在main中import { Input} from 'element-ui';

2.在组件中<el-input placeholder="请输入内容" prefix-icon="el-icon-search" v-model="input" @change="search" id="el-input"></el-input>

二者在使用时注意是否要加el-

增加eslint做代码规范

安装依赖

npm install eslint eslint-config-standard eslint-loader eslint-plugin-html eslint-plugin-import eslint-plugin-node eslint-plugin-promise eslint-plugin-standard -D

配置.eslintrc

{
"extends": "standard",
"plugins": [
"html"
],
"parser": "babel-eslint"
}

配置package.json的脚本:

"lint": "eslint --ext .js --ext .jsx --ext .vue client/",
"lint-fix": "eslint --fix --ext .js --ext .jsx --ext .vue client/",
"precommit": "npm run lint-fix"

执行命令

npm run lint
or
npm run lint-fix

webapck4升级

1.webpack相关的插件就是带有webpack的,以及loader插件(边升级报错,边修改);

2.有些API的修改或者废弃,需要修改配置

新增:

1、mode属性,在config中一定要写mode: process.env.NODE_ENV || 'production'

2、optimization属性

optimization: {
splitChunks: {
chunks: 'all'
},
runtimeChunk: true
}

废弃:

  • 1、webpack.NoEmitOnErrorsPlugin()
  • 2、webpack.optimize.CommonsChunkPlugin()

升级成webpack4过程遇到的坑

1.npm run dev后出现Path variable [contentHash] not implemented in this context: styles.[contentHash].css

解决方案:把[contentHash]换成 [chunkhash:8]

2.extract-text-webpack-plugin升级中警告它需要依赖webpack3,故决定试试@next,结果可以,

npm install extract-text-webpack-plugin@next,以后试试@next

单元测试(Unit Test)

用来对一个模块、一个函数或者一个类进行正确性检验的测试工作。

测试驱动开发: TDD-> Test-Driven Dovelopment

Karma(在node跑的测试框架)+Mocha

Mocha(测试框架) 不带断言库+Chai断言库

Vue遇到的坑

  • scpoed只对当前文件起作用。
  • for循环必须加key值,key值一般用item值而不用index,是为了虚拟dom的优化机制。

Vue犯错

  • router/index.js中的routes写错成routers,导致错误。

Vue组件库使用经验

element-ui使用

局部引入使用

1.在组件里import { Table, TableColumn } from "element-ui";

2. components: {Table, TableColumn}

3.<Table></Table><table-column type="selection" width="55"></table-column>

全局引入使用

1.在main中import { Input} from 'element-ui';

2.在组件中<el-input placeholder="请输入内容" prefix-icon="el-icon-search" v-model="input" @change="search" id="el-input"></el-input>

二者在使用时注意是否要加el-

方法methods、计算属性和侦听器computed、watch的区别

你可能已经注意到我们可以通过在表达式中调用方法来达到同样的效果:

<p>Reversed message: "{{ reversedMessage() }}"</p>
// 在组件中
methods: {
reversedMessage: function () {
return this.message.split('').reverse().join('')
}
}

我们可以将同一函数定义为一个方法而不是一个计算属性。两种方式的最终结果确实是完全相同的。然而,不同的是计算属性是基于它们的依赖进行缓存的。只在相关依赖发生改变时它们才会重新求值。这就意味着只要 message 还没有发生改变,多次访问 reversedMessage 计算属性会立即返回之前的计算结果,而不必再次执行函数。

这也同样意味着下面的计算属性将不再更新,因为 Date.now() 不是响应式依赖:

computed: {
now: function () {
return Date.now()
}
}

相比之下,每当触发重新渲染时,调用方法将总会再次执行函数。

我们为什么需要缓存?假设我们有一个性能开销比较大的计算属性 A,它需要遍历一个巨大的数组并做大量的计算。然后我们可能有其他的计算属性依赖于 A 。如果没有缓存,我们将不可避免的多次执行 A 的 getter!如果你不希望有缓存,请用方法来替代。

Vue 提供了一种更通用的方式来观察和响应 Vue 实例上的数据变动:侦听属性。当你有一些数据需要随着其它数据变动而变动时,你很容易滥用 watch——特别是如果你之前使用过 AngularJS。然而,通常更好的做法是使用计算属性而不是命令式的 watch 回调。细想一下这个例子:

<div id="demo">{{ fullName }}</div>
var vm = new Vue({
el: '#demo',
data: {
firstName: 'Foo',
lastName: 'Bar',
fullName: 'Foo Bar'
},
watch: {
firstName: function (val) {
this.fullName = val + ' ' + this.lastName
},
lastName: function (val) {
this.fullName = this.firstName + ' ' + val
}
}
})

上面代码是命令式且重复的。将它与计算属性的版本进行比较:

var vm = new Vue({
el: '#demo',
data: {
firstName: 'Foo',
lastName: 'Bar'
},
computed: {
fullName: function () {
return this.firstName + ' ' + this.lastName
}
}
})

引入外部库或者插件

  • 引入外部库

在main.js

import moment from 'moment';
Object.defineProperty(Vue.prototype, '$moment', { value: moment });

MyNewComponent.vue

export default {
created() {
console.log('The time is ' . this.$moment().format("HH:mm"));
}
}
  • 如何创建自己的Vue插件

    在main.js

import MyLibraryPlugin from 'my-library-plugin';
Vue.use(MyLibraryPlugin);
  • 如何写插件

首先,创建一个文件。本例中,我将引入一个Axios库的插件。我们就把这个文件命名为axios.js吧。

最关键的地方在于,我们需要暴露一个将Vue构造器作为第一个参数的install方法。

axios.js

export default {
install: function(Vue) {
// Do stuff
}
}

然后我们可以用之前的方式将库添加到Vue的原型对象上:

axios.js

import axios from 'axios';

export default {
install: function(Vue) {
Object.defineProperty(Vue.prototype, '$http', { value: axios });
}
}

接着我们只需要Vue实例的use方法就能将这个库引入整个项目了。我们像下面代码一样简单引入:

main.js

import AxiosPlugin from './axios.js';
Vue.use(AxiosPlugin); new Vue({
created() {
console.log(this.$http ? 'Axios works!' : 'Uh oh..');
}
})
  • 插件参数设置

插件的install方法还可以接受其他的可选参数。有些开发者可能不喜欢Axios实例对象的方法名$http,因为Vue resource插件的方法名也是这个。然后,让我们利用第二个参数来修改它。

axios.js

import axios from 'axios';

export default {
install: function(Vue, name = '$http') {
Object.defineProperty(Vue.prototype, name, { value: axios });
}
}

main.js

import AxiosPlugin from './axios.js';
Vue.use(AxiosPlugin, '$axios'); new Vue({
created() {
console.log(this.$axios ? 'Axios works!' : 'Uh oh..');
}
})

开发基于vue的组件库

参考: 如何开发一套基于Vue的组件库

vue知识总结的更多相关文章

  1. 2018 我要告诉你的 Vue 知识大全

    Vue ,React ,Angular 三大主流框架,最后我选择学习 Vue ,接触过 React ,自己感觉学习曲线有些陡峭,进而我选择了学习 Vue ,他的学习曲线平稳很多:不管选择什么框架,除了 ...

  2. 总结vue知识体系之实用技巧

    vue 作为目前前端三大框架之一,对于前端开发者可以说是必备技能.那么怎么系统地学习和掌握 vue 呢?为此,我做了简单的知识体系体系总结,不足之处请各位大佬多多包涵和指正,如果喜欢的可以点个小赞!本 ...

  3. vue知识总汇

    学前预备知识 ECMAScript简介和ES6的新增语法 Nodejs基础 webpack的介绍 babel简介 vue基础 vue基础

  4. Vue知识分享一

    最近想着把之前学的Vue的知识整理一下,方便在公司和同事一起分享.我想要按照下面几个方面去说一下,我对vue的学习理解. 一.什么是VUE vue.js是一个用来开发Web界面的前端库,是很轻量级的工 ...

  5. 前端Vue知识小白

    感觉是已好久没写博文了.今日难得有时间,便写一篇文章.此文章是关于前端知识的,我本身是后端,因工作或其他需要,便学习了前端Vue.此文章是在菜鸟教程上学习的.那么下面进入正文! 首先,Vue.js是一 ...

  6. 前端知识扫盲-VUE知识篇一(VUE核心知识)

    最近对整个前端的知识做了一次复盘,总结了一些知识点,分享给大家有助于加深印象. 想要更加理解透彻的同学,还需要大家自己去查阅资料或者翻看源码.后面会陆续的更新一些相关注知识点的文章. 文章只提出问题, ...

  7. Vue 知识复习(上)

    Vue Vue实例 创建实例: var vm = new Vue({ //code }) 数据与方法: 只有当实例被创建时 data 中存在的属性才是响应式的; Vm.b = 'h1' 是不会触发视图 ...

  8. Vue 知识整理—02-起步

    一:Vue 语法格式: vue vm = new Vue({ //选项 }) 二:Vue 实例: <div id="app"> <p>{{message}} ...

  9. Vue 知识整理—01-基础

    一:Vue是什么? Vue是一个JS框架. Vue.js是一套构建用户界面的渐进式框架. 库和框架的区别: ☞库:提供一些 API 工具函数,体现了封装的思想,需要我们主动调用: ☞框架:提供一套完整 ...

随机推荐

  1. [linux]主机访问虚拟机web服务(CentOS)

    目的为了实现主机和虚拟机的通信,访问虚拟机中架设的web服务.按理说通过虚拟机ip + web服务端口,即可在浏览器访问虚拟机的web服务.但是由于CentOS的防火墙问题,对应web端口无法访问.通 ...

  2. ajax 三种数据格式

    1.JSON(格式要正确,可以引jar包操作) servlet代码 package com.hsp.action; import java.io.IOException; import java.io ...

  3. HTML入门8

    今天开始接触HTML里面的多媒体和嵌入内容 前面只讲了文字,下面来讲能够让网页动起来,更加有趣的嵌入元素,包含多媒体,包含图像的不同方式,以及怎样嵌入视频. HTML中图片,下面将深入使用它,以及&l ...

  4. 201771010118《面向对象程序设计(java)》第三周学习总结

    第一部分:理论知识复习部分 第一章            回顾了Java的关键术语,再次熟悉了java程序设计的性能介绍.对Java语言的十多种特性又有了更深刻的理解. 第二章 eclipse开发环境 ...

  5. 问题:CMD安装mysql-server遇到找不到MSVCR120.dll问题(已解决)

    今天,我用CMD安装mysql服务器端遇到了找不到msvcr120.dll问题,所以我去网上下载这个dll,但是出现找不到入口,或者什么的.  我想了想,去下载运行时库(因为MSVCR是Microso ...

  6. dtNavMeshQuery::findLocalNeighbourhood m_tinyNodePool->getNode dtHashRef整数哈希 getPortalPoints dtOverlapPolyPoly2D

    dtNavMeshQuery::findLocalNeighbourhood(dtPolyRef startRef, const float* centerPos, const float radiu ...

  7. maven打包忽略静态资源解决办法,dispatchServlet拦截静态资源请求的解决办法

    问题: maven 打包时,有的文件打不进去target 解决: 因为maven打包默认打Java文件.在项目中的pom文件中加build标签 <build> <resources& ...

  8. 电子产品使用感受之----AirPods的一天使用体验分享

    2019.03.29 晚上8点50分更新: 3月28日我的新款AirPods终于到货了,作为一代产品使用2年的用户,终于可以说说这枚新品的一天使用感受了: 我们会从以下几个方面来进行阐述: 外观 技术 ...

  9. java_基础_abstract抽象关键字

    java中,当父类中的某些东西不确定时,可以用abstract关键字将此类变成抽象类(也就是说类并不完整,有些东西要等待子类去实现) 注意事项: 1.抽象类中的抽象方法不能有实体,格式如下 publi ...

  10. Gym 101606 - A/B/C/D/E/F/G/H/I/J/K/L - (Undone)

    链接:https://codeforces.com/gym/101606 A - Alien Sunset 暴力枚举小时即可. #include<bits/stdc++.h> using ...