关于vue(一)

321 阅读15分钟

脏检查:在angularjs作用域内定义的变量发生变化时,触发所有变量的循环检查, 当检查到数据变更时,则同步数据,直到所有数据稳定。当所有数据稳定后,还会执行一次额外的全量检查。 vue不兼容ie678 无法被shim兼容

Shim:指的是在一个旧的环境中模拟出一个新 API , 而且仅靠旧环境中已有的手段实现,以便所有的浏览器具有相同的行为。

//////////////////////////////////////////////////////////

v-model:会创建双向数据绑定,用在表单元素上

/////////////////////////////////////////////////////////////

v-bind指令 : :src="imgUrl" 或者 v-bind: 如果在属性中想要使用data中的数据,需要使用到v-bind指令 在vue中,把 {{}} 叫做插值表达式,作用是用于显示vue的data中的数据

//////////////////////////////////////////////////////////

插值表达式: 1. {{}}可以显示data中的数据 2. {{}}中可以出现任意的表达式

  注意点:
  1. 不能出现不存在的数据
  2. 不能出现语句

/////////////////////////////////////////////////////////////

  1. Vue是一个构造函数,首字母大写
  2. Vue必须在vue的管理范围内才能使用
  3. el能不设置为body和html

库与框架的区别: 一个库就是一系列方法的集合 我们主导逻辑 框架就是一套完整的技术解决方案 框架主导我们的逻辑

/////////////////////////////////////////////////////////////////

v-on:指令用于给元素注册事件 v-on:事件名="事件函数"

简写 @click="事件函数" @mouseenter

/////////////////////////////////////////////////////////////////

字符串翻转案例: 字符串.split('').reverse().join('')

split() 方法用于把一个字符串分割成字符串数组 reverse() 方法用于颠倒数组中元素的顺序 join() 方法用于把数组中的所有元素放入一个字符串

////////////////////////////////////////////////////////////////

@事件名="事件的函数名" 可以通过e获取到事件对象 @事件名="函数的调用" 如果函数写的是函数的调用的方式,显示的传递事件对象

///////////////////////////////////////////////////////

v-on 事件修饰符

@事件名.事件修饰符="事件函数" .prevent: 阻止浏览器默认行为 .stop:阻止冒泡 .capture: 在捕获阶段发生 事件流 .self: 只有自己才能触发 .once: 事件触发一次

///////////////////////////////////////////////////////////////

js加不加分号 看自己的公司

//////////////////////////////////////////////////////////////

v-text(设置当前标签的innerText(textContent)属性) v-html(设置当前标签的innerHTML属性, innerHTML:标签能生效 XSS攻击)

//////////////////////////////////////////////////////////////

v-show(控制当前元素的显示和隐藏, 通过display来控制元素的显示和隐藏) v-if(通过创建和删除元素来控制显示和隐藏) 对于需要频繁的显示和隐藏切换的,应该使用v-show指令 对于要么显示,要么隐藏的,应该使用v-if指令

//////////////////////////////////////////////////////////////

v-if v-else( v-else: 直接跟在v-if的后面,表示if和else情况) v-else-if

/////////////////////////////////////////////////////

v-for指令:用于遍历一个数组或者是一个对象 要重复渲染哪个标签,v-for就给哪个标签。 添加唯一标识 key v-for="item in list" 获取下标 v-for="(item, index) in list"

/////////////////////////////////////////////////////

就地复用: vue在数据发生改变的时候,页面会跟着进行更新 vue只会更新修改的那部分,性能非常高

/////////////////////////////////////////////////////

v-bind样式操作的增强: v-bind指令对于class/style属性,允许值不仅仅是一个字符串,还允许是个对象 :class="{box: true, bg: true}

/////////////////////////////////////////////////////

键盘修饰符: 键盘修饰符用法1: @事件名.键盘修饰符(数字) = "事件处理" 键盘修饰符用法2: @事件名.键盘修饰符的别名 = "事件处理" enter esc 键盘修饰符用法3: 自己起别名 Vue.config.keyCodes.huiche = 13

////////////////////////////////////////////////////

数组新增的方法:forEach map filter every some find findIndex

forEach: 会让所有的元素都执行一次function 参数1: item 当前遍历的元素 参数2: index: 当前遍历元素的下标 参数3: 当前数组 arr.forEach(function(item, index){ console.log(111) }) arr.forEach(item => console.log(item))

map: 功能和forEach很像, map会返回一个新的数组, 这个数组的值是每个function的返回值, map:映射 可以由一个数组 得到一个新的数组 var arr = [1,2,3,4] // 1, 4, 9, 16 var newArr = arr.map(item => item * item)

filter: 过滤, 功能和map很像, 也会得到一个新的数组,作用是过滤, 保留满足条件的那些元素
function要返回true的元素 var arr = [3000, 5000, 10000, 15000, 1500] var newArr = arr.filter(item => item <= 6000)

some: 某些 some方法返回的是布尔值, 只有数组中某个元素满足了条件, 整个结果就是true, 如果所有都是false, 结果就是false var arr = [1, 2, 4, 6, 8] var flag = arr.some(item => item%2 === 1)

some: 某些 some方法返回的是布尔值, 只有数组中某个元素满足了条件, 整个结果就是true,如果所有都是false,结果就是false var arr = [1, 2, 4, 6, 8] var flag = arr.some(item => item%2 === 1)

every: 结果也是返回布尔值,
要求所有的元素都返回true,结果才是true var arr = [0, 3, 4, 6, 8] var flag = arr.every(item => item % 2 === 0)

find : 返回的第一个满足条件的元素 var result = arr.find(item => item%2 === 1)

findIndex: 返回第一个满足条件的元素的下标 var result = arr.findIndex(item => item%2 === 1)

////////////////////////////////////////////////////////////////////////

计数属性的使用: 计算后才能得到的属性,相当于data中的属性 计算属性写法: 对应值,应该是一个函数,可以在函数中书写计算的逻辑,计算属性最终的结果是函数的返回值

  1. 计算属性是一个属性,写法上是一个函数,因为计算属性需要有逻辑,计算属性对应的是这个函数返回的结果
  2. 计算属性这个值会发生改变,只要依赖的数据发生了改变,计算属性就会重新执行一遍,得到新的值, 如果你多次使用了这个计算属性,只会算一次

指令里面访问的都是data中的数据,不要当字符串 {{}}插值表达式中最好就写data中的一个属性,虽然可以写逻辑表达式,但是不太好后期维护

不能写箭头表达式,因为箭头内没有this指向

计数属性通过依赖项来计算值,依赖项变了也会导致重新求知

////////////////////////////////////////////////////////////////////////

监听属性: 监视某个数据的变化,只要数据发生了改变,对应的函数就会执行 监听名:function(value,oldValue){..........} 监听的默认属性只能监听简单类型,对于复杂类型只能监听到复杂类型的地址变化

深度监听/监听复杂类型的数据:(要用到watch的完整形态) 完整写法,不是一个函数,而是一个对象 监听名:{ handler:function(){...}, // 监听的函数 deep:true, // 是否深度监听 immediate: true //是否立即监听 (不是必须值) }

//////////////////////////////////////////////////////////////////////

3个不常用的指令:

v-cloak: cloak: 斗篷 披风...解决插值表达式闪烁的问题 当vue在渲染完成的时候,自动移除掉v-cloak属性 插值表达式闪烁这个问题,只会出现通过script标签引入vue的这种情况 后期我们开发vue,而是在单位件组件,.vue结合webpack

v-pre: 提高性能:明确知道某一个段落不需要被vue渲染 作用:当前元素会被vue跳过,vue就不会渲染这个元素

v-once: 当前元素只会渲染一次,后续数据发生改变,不会重新渲染

//////////////////////////////////////////////////////////////////////

vue的生命周期: vue是一个框架,整体的vue的逻辑vue已经定好了

Vue的初始化: 1 new Vue() 2 初始化内部的事件,生命周期开始了 3 把data中所有的数据都通过Object.defineProperty都定义到vm身上 重要: vm身上就有数据了 4 确定是否有el参数, 有-->继续往下走 没有-->等到vm.$mount调用后-->继续往下走 5 确定vue需要渲染的模板,判断是否有template属性 有--->需要渲染template 没有-->就把el的outHTML当成template 6 结合数据以及模板进行渲染,把渲染后的结构把el替换

Vue更新阶段: 1 等vue身上的数据发生改变 2 重新渲染页面中的内容(循环)

Vue销毁阶段: 1 等vm.$destroy()方法调用 2 卸载所有事件监听 3 vue的数据发生变化已经不会引起页面发生改变

//////////////////////////////////////////////////////////////////////

vue钩子函数的说明: 直接写在vue实例中

创建构造函数之前后 beforeCreate(){......} created(){.....} (通常在这里用ajax)

el替换之前后 (可用于操作dom) beforeMount(){...} mounted(){...}

数据更新之前后 beforeUpdate() Updated()

销毁数据前后: beforeDestroy(){...} destroyed(){...}

////////////////////////////////////////////////////////////////////////////////

mock数据: 造假数据 联调

先在cmd中下载 1 npm i -g json-server (这个要与http-server 做区分 他们不是一个东西)

启动: 2 json-server只需要一个json文件 3 json-server data.json //(其实也就是文件名) 4 点击resources的地址栏

功能: 1 可以直接在地址栏+: /id值 回车 得到想要搜索的id条 =>http://localhost:3000/todo/1 2 分页效果:在地址栏中+: ?_page=查看第几页&_limit=一页限制几条信息 =>http://localhost:3000/todo?_page=2&_limit=2 3 匹配你想匹配的字段+: ?q=字段 =>http://localhost:3000/todo?q=%E6%B8%B8

测试json-server生成的增删改查接口 rest风格接口 查: get 增: post 删: delete 改: put / patch

查询:  http://localhost:3000/todos      请求方式: get
删除    http://localhost:3000/todos/id   请求方式: delete
新增    http://localhost:3000/todos      请求方式 post  参数: name  completed
修改    http://localhost:3000/todos/id      请求方式 put   参数: name  completed

////////////////////////////////////////////////////////////////////////////////

axios: 用来发送ajax请求:通过.then获取成功的结果,通过.catch获取失败的结果 axios({ // 请求方式 method: 'get', // 请求地址 url: 'http://localhost:3000/todos1' }).then(function(res) { // 服务器返回的数据: res.dat中 console.log(res.data) }).catch(function(err) { console.log(err) })

例子: // 修改 axios({ method: 'put', url: 'http://localhost:3000/todos/6', data: { name: '笑嘻嘻', completed: true } }).then(res => { console.log(res.data) })

////////////////////////////////////////////////////////////////////////////////

过滤器:

  1. 定义一个过滤器, 在vue中,默认是没有过滤器 参数1:过滤器的名字 参数2: 过滤的逻辑 参数:需要过滤的内容 函数必须要有返回值, 表示过滤后的结果

  2. 过滤器在插值表达式中进行使用,表示对插值表达式的内容进行过滤(格式化) 使用方法 {{ 数据 | 过滤器的名字 }} linux:管道符

Vue.filter('myFilter',function(input))

例子:

{{msg | filter}}

Vue.filter('filter', input => { return input + '!!!' })

input是一个必须有的形参,代表的是传入的数据,也就是这里的msg

在使用过滤器的时候,可以直接写过滤器的名字,也可以写成调用的方式: 例子: html:

{{ n1 | numFilter(2) }}

script: Vue.filter('numFilter',(input,num)=>{ num = num || 2 return input.toFixed(num) }) input:传进去的n1值 num: 参数()里的值 toFixed(n): 保留n位小数 const vm = new Vue({ el: '#app', data: { n1: 22.22, n2: 33.3333, n3: 44.444444 } })

///////////////////////////////////////////////////////////

过滤时间: 引入moment.json vue.js

{{time | timeFilter('YYYY年MM月DD日')}}

Vue.filter('timeFilter', (input, format) => { format = format || 'YYYY-MM-DD HH:mm:ss' // moment() 当前时间 // moment(input) 格式化指定的时间 // 指定时间的格式 return moment(input).format(format) }) 还有一个Vue的实例,提供time值

/////////////////////////////////////////////////////////////////

过滤器: 全局过滤器:全局过滤器在所有的vue实例中都能使用 Vue.filter('aa', input => {...})

局部过滤器,只有在当前vue实例中才能使用,通常写在vm中,是一个对象,和data相同等级

//////////////////////////////////////////////////////////////

es6新增:

  1. let const
  2. 箭头函数
  3. find findIndex
  4. 字符串startsWith endsWith includes
  5. 对象的简写
    1. 对象的属性名和值名字相同的时候,可以省略一个
    2. 对象中的方法可以省略 sayHi:function(){...} === sayHi(){...}
  6. 函数参数的默认值 -->默认参数可以写在()里 function add (n1 = 0, n2 = 0) { // 函数参数的默认值 // n1 = n1 || 0 // n2 = n2 || 0 console.log(n1 + n2) }
  7. 模板字符串 在ES6中,允许使用 反引号 来定义一个字符串
  8. 允许换行
  9. 拼串中允许使用插值 ${}

///////////////////////////////////////////////////////////

vue响应式数据说明: vue的响应式数据, 被Object.defineProperty劫持过的数据

  1. 原则: 需要使用的数据,一定要现在data中进行声明
  2. 出现问题:给vm中的数据动态增加一个属性,这个属性不是响应式的 问题原因: vue监听不到数组长度下标和普通对象的增加和删除 变异方法(原数组会发生改变的方法),vue能监听到
  3. 解决方法:set方法可以给vm动态的增加一个属性,响应式的Vue.set===vm.set方法可以给vm动态的增加一个属性,响应式的 Vue.set === vm.set
    只要是vm的方法,添加开头开头 mount $destroy

////////////////////////////////////////////////////////////

vue异步更新说明: vue中的数据如果发生了改变,页面中的内容就会跟着发生改变。 vue中的数据如果发生了改变,页面的内容不是立即改变,这个操作是异步的。

数据操作完想要拿到dom元素的话要用nextTick(在dom重新渲染完之后执行) (效果有点像开了个延时器)

//////////////////////////////////////////////////////////////////////

组件: 我们可以把组件理解为是一个自定义的html标签,有自己的内容,样式和功能

  1. 定义组件 component:组件 参数1: 组件的名字 参数2: 组件的配置项 必须指定一个template属性,必须要给它一个范围 html:
js: Vue.component('name',{ template:'

你好啊,我是name组件

' }) const vm = new Vue({ el:'#app' })

组件是一个可以复用的vue实例,你可以把vm实例也当成一个组件 组件都有一个名字 vue实例中能够使用的配置项,在组件中也能用 data methods filters computed watch 组件中不会指定el,但是会指定template, template必须要指定一个根元素

  1. 组件不用指定el,但是要指定template
  2. 组件中的data必须是一个函数, 这个函数还需要返回一个对象 这样每个实例都能返回一个独立的对象

//////////////////////////////////////////////////////////////////

组件是一个独立的vue实例,数据也是相互独立的,组件之间的数据是无法共享的

/////////////////////////////////////////////////////////////////

组件通讯:父到子

如何形成父子组件: 需要在父组件的template中使用子组件才能形成父子关系

父组件给子组件的身上添加一个自定义的属性: 1 父组件在子组件的身上增加一个自定义的属性 2 在子组件中使用props属性进行接收即可 props和data一样,也是给组件提供数据 data:提供的是自己的数据 props:接收到父组件传递过来的数据

例子:

{{msg}}

//父传给子的值

引入步骤:按先引入组件后引入根vm

步骤: 1 父组件在子组件身上增加一个自定义属性即可 2 子组件通过props属性来接收父组件传递过来的数据,接收名字一定要和 自定义的属性名一致

/////////////////////////////////////////////////////////////////////

组件通讯:子到父

1 父组件提供一个方法(带有参数,可以把值传进来) 2 父组件给子组件注册一个自定义的事件(把方法传给子组件@随便起一个事件名="父组件中的事件名")(给子组件传递一个函数) 3 子组件中定义一个方法,$emit('随便起一个事件名',this.data中的属性,this.data的属性......) 子组件把需要传递给父组件的值当成参数传递过去 4 在子组件中的模板中 注册事件调用子组件中的方法 5 当子组件事件被触发后,参数会被传到父组件内 5 组建中data的存放 都是通过函数 + return

//////////////////////////////////////////////////////////////

单向数据流: 父组件给子组件传值 子组件使用props接收 特点:只要父组件的数据发生了更新, 通过props接收的这些子组件的数据也会跟着就更新 props是只读的,不允许修改

父级prop的更新会向下流到子组件中,但是反过来则不行 每次父组件发生更新的时候,子组件中所有的prop都将会发为最新的值, 所以不应该在一个子组件内部改变prop,不然控制台会发生警告

子组件修改props的话,最好不要修改简单类型以及复杂类型的地址,因为会报错

////////////////////////////////////////////////////

组件通讯:非父子关系 A(传信息者) 传消息给 B(接收信息) 1 B 提供一个方法 getMsg(){...} 2 B给bus注册一个事件 const bus = new Vue()

mounted
bus.$on('sb',this.getMsg)

3 A去触发bus的对应的事件 bus.$emit('sb',this.msg)

4 A可以把msg传递给B

注意: 1 A和B要上同一辆bus 2 A触发的事件的名字和B注册的名字要一致

bus其实就是一个空的vue实例

vm.emit触发事件vm.emit 触发事件 vm.off 移除事件 vm.$on 监听当前实例的自定义事件

自己的比喻: 1 a想传值给b 2 a触发了sb事件后,将值带上车 (emit)3b监听到sb事件被触发后(emit) 3 b监听到sb事件被触发后(on),触发自身的方法

///////////////////////////////////////////////////////////

组件: 全局定义的组件,所有的实例都可以使用 定义局部组件, 只有当前实例中能用

////////////////////////////////////////////////////////////////

插槽: 插槽,在定义组件的时候,如果希望内容是通过组件传进来,需要指定 如果定义的组件内部没有slot(插槽),传给组件的内容是会被抛弃 如果没有name属性,默认插槽--->内容默认替换默认插槽

具名插槽: 模板:

html中: 具名插槽--->内容替换具有相同名字的插槽

////////////////////////////////////////////

SPA: 单页面应用程序:只有一张web页面应用,加载单个页面并在用户与应用程序交互时动态更新页面的web应用程序 通过哈希值的不同请求不同的内容(hashchange)

优点: 1 减少请求体积,加快页面响应速度,降低对服务器的压力 2 提高用户体验

缺点:不利于seo

原生: 是通过监听哈希值的改变实现的 window.addEventListener('hashichange',function(){...})

我的首页 ---># 页面不跳转 location.hash 获取 当前页面的哈希值

/////////////////////////////////////////////////////////////////////////

vue全家桶之一-----vue.router 路由 (实现单页面) 路由规则: 根据给的不同url 给你映射到 不同的页面中去 一个指路的功能

而 vue的router:
根据不同的锚点值,给你映射到不同的组件去

ue router的功能:构建 单页面应用程序
页面只有一个,组件可以有很多个

步骤:
 引包 : 引入   vue.js    vue-router.js
 定义一些组件 Vue.component 全局注册一个组件 组件名首字母一般大写 1个属性
                 Vue.components('music', {
                   template;`
                   <div> 这是一个组件 </div>
                   `
                 })
   ===> 
 const  Home = { template:`....`}
 创建一个 vueRouter对象-----路由对象  2个属性
                             // 指定路由的规则  path:/home  Home
 const router = new VueRouter({routes:[{path:'路径',component:Home},{...},{...}]})
 把路由对象 和  vm实例绑定
 const vm = new Vue({el:'#app',router:router})
 const vm = new Vue({el:'#app',router})
 指定路由的出口,根据地址可以匹配搭配对应的组件,通过组件渲染的内容会替换出口
 <router-view></router-view>
 路由的入口 相当于a  用于点击更换不同的组件
 <router-link to="路径">XX</router-link>

Vue中this.router.push(参数)实现页面跳转:https://blog.csdn.net/qq37548296/article/details/90446430我们在执行点击按钮跳转页面之前还会执行一系列方法,这时可以使用this.router.push(参数) 实现页面跳转: https://blog.csdn.net/qq_37548296/article/details/90446430 我们在执行点击按钮跳转页面之前还会执行一系列方法,这时可以使用 this.router.push(location) 来修改 url,完成跳转。 push 后面可以是对象,也可以是字符串,还可以是命名的路由 // 字符串 this.router.push(/home/first)//对象this.router.push('/home/first') // 对象 this.router.push({ path: '/home/first' }) // 命名的路由 this.$router.push({ name: 'home', params: { userId: wise }})

页面 跳转 并 传递参数 的方法: 1 params 由于动态路由也是传递params的,所以在 this.$router.push() 方法中path不能和params一起使用,否则params将无效。 需要用name来指定页面 及 通过路由配置的name属性访问 patams传参 ,路径不能使用path 只能使用name,不然获取不到传的数据

/* router.js 文件*/ import Vue from "vue"; import Router from "vue-router"; import MediaSecond from "@/views/EnterprisePage/MediaMatrix/second"; //资讯列表

Vue.use(Router);
export default new Router({
  routes: [ /* 进行路由配置 */
    {
        name: "MediaSecond",
        path: "/MediaSecond",
        component: MediaSecond
    },
  ]

})

/* 通过name获取页面,传递params:*/ this.$router.push({ name: 'MediaSecond',params:{artistName:artistName,imgUrl:imgUrl,type:2} })

/* 在目标页面通过this.route.params获取参数:/if(this.route.params获取参数:*/ if (this.route.params.type == 2) { this.type = apis.getAtistDetails; } else { this.type = apis.getMessageList; }

2 query 传参 ////////////////////////////////////////////////////////////////////////////////

webpack :静态模块打包器(一起打包) gulp(比较小的项目,基于任务)

npm安装包的说明:
npm i 包名 --save
npm i 包名 -S
npm i 包名
把这个包名保存到dependencies中, 项目的依赖
(例如jq,项目依赖的安装包,所以下载jq的时候用的是npm i jquery)

npm i -g 包名 
全局安装,他和项目没有关系,全局安装在c盘安装了一个命令

npm i 包名 --save-dev
npm i 包名 -D
把这个包保存到 devDependencies中,  开发阶段的项目依赖,
项目上线后就不需要用了(例如webpack只有开发的时候才用到,所以下载
webpack的时候用的是npm i webpack -D)


npm scripts:配置脚本,就是配置命令的别名
例如 package中配置:
"cc": "npm install jquery"
"start": "node app.js"
则运行命令符的时候:npm run cc   /  npm start

其中,配置的别名中 start/stop 在运行时可以省略run  ->:npm start

///////////////////////////////////////////////////////////

webpack 使用步骤:

1 安装依赖包 npm i webpack webpack-cli -D
npm 下载东西比较慢  因为是串行下载 

yarn 下载的话会比较快

2 在scripts中配置别名 "build":"webpack"
 再配置 对哪个 文件进行打包 :例如 "webpack js/main.js -o dist/bundle.js"

3 运行打包命令  npm run build

只用引入一个bundle.js

webpack支持nodejs模块化

在main.js中引入需要引入的文件:
const $ = require('jquery')   --> node js 的模块化
require('./aa')
....
再执行  npm run build

4 通过mode参数可以设置打包的模式 (production/development)
production:默认是这个,表示是压缩的
development:表示是开发阶段,不是压缩的
例如修改设置:
"build":"webpack js/main.js -o dist/bundle.js --model=development"

webpack的配置文件:
webpack.config.js (名字固定)
作用:配置webpack的配置,当我们运行webpack的命令,自动在根目录
查找 webpack.config.js 文件
module.exports = { 
                  entry:path.join(__dirname,'目录','文件'),   
                  output:{path:path.join(__dirname,'dist'),
                  filename:'bundle.js'},  mode:'打包模式' 
                  }

///////////////////////////////////////////////////////////////

反正还有很多很多。。。 跳过。。。 es6的模块化: 导入文件: 精确导入: import { 需要导入的东西,一定要和导出的名字相同 } from './js/tool' export {num ,fn}-----》精确导出(精确导出, 一般会把导出写到最后:)

默认导出: import xxx from './js/tool' export default sayHi // es6模块化允许一个默认最多有一个默认导出 // 默认导出不需要指定名字

/////////////////////////////////////////////////////////////////////

单文件组件: