vue语法整理【入门/复习】

vue指令

1、{{}}插值表达式和v-text

  • 相同: 都可以渲染数据;都可以在里面写js表达式。
  • 不同:
    (1)插值表达式存在内容闪烁问题。因为在网速较差情况下,插值表达是会先渲染{{msg}},待文件请求下来后再转换为具体的msg内容。v-text是等文件请求下来后直接进行渲染。
    (2)v-text会替换掉标签中的内容
<div v-text="msg">123</div>
// 这里只会显示msg的内容而不会显示123
  • 解决插值表达式闪烁问题,可以使用v-cloak
<div v-cloak>{{ msg }}</div>

[v-clock] {
display: none;
}

2、v-html

  • 如果要渲染的内容中包含html代码片段时,用v-html。

3、v-bind

  • 为元素的属性绑定数据,一般绑定data里面的数据。简写:
  • v-bind是单向数据流,从data同步到view。比如绑定data里面的msg后,修改msg会改变v-bind绑定元素的值,但修改元素的值不会影响msg的值。
  • 如果想要实现表达式的拼接,被拼接的字符串一定要被引号包裹起来。

4、v-on

  • 为元素绑定事件,绑定事件的处理函数必须写到methods中,简写@
  • 在methods中如果想要访问data中的数据,只能通过this.xxx来访问。如果数据在methods需要被共享,多个函数会用到,就定义到data中。

5、v-model双向数据绑定

  • 除了v-model其他都是单向数据流绑定。
  • 只能应用在表单元素中,因为表单元素才会和用户进行交互。(input text radio checkbox textarea select option button )

6、事件修饰符

  • .stop:阻止冒泡,给内层元素
    用法示例:@click.stop
    -.prevent:阻止默认事件
    -.capture:添加事件监听器时使用事件捕获机制,即和冒泡相反,从外往里执行,给外层元素添加。
    -.self:只当事件在该元素本身触发时触发回调
    -.once:事件只触发一次

7、v-for循环数组

-循环list里面的数据生成li。注意key的值必须具有唯一性,可以为number和string。key的值不要每次写成index,因为在vue中index不一定是唯一的。

<ul>
  <li v-for="(item, index) in list" :key="index">{{ item.name }}</li>
</ul>

data: {
 list: [
   {id: 0, name: 'xm'},
   {id: 1, name: 'xh'}
 ]
}
  • 还可以循环对象 v-for=(val,key) in obj ,val是属性值,key是属性名

8、v-if和v-show

-v-if有更高的切换消耗,v-show有更高的初始渲染消耗。如果需要频繁切换使用v-show,它是给元素添加display:none;属性。

9、findIndex方法

-数组的findIndex方法可以查找对应项的索引值,接收一个回调函数,有三个参数item,i,arr。

10、过滤器

  • 作用:为数据添油加醋。比如后端传了价格20,我要展示是¥20还是$20
  • 定义一个全局过滤器
Vue.filter(“过滤器将来被调用的名称”,“过滤器的处理函数”)’
Vue.filter(formData, function(){
  return '123'
 }
  
  // 在要使用过滤器的地方使用|管道符,表示使用后面的formData来处理item.ctime,过滤器的第一个参数是管道符前面的值item.ctime
  <div>{[ item.ctime | formData }}</div>
  • 过滤器只能用在插值表达式和v-bind中。
  • 定义私有过滤器即局部过滤器在vue实例里面定义
<div>{[ price | myprice('$') }}</div>


var vm = new Vue({
  el :'#app',
  data: {
      price:10
  },
  methods: {},
  filters: {
     myprice:function(price, param){
         return param + price 
}
  }
}

11、自定义指令

  • 比如给输入框自定义聚焦指令。
// 注册一个全局自定义指令 `v-focus`
Vue.directive('focus', {
  // 指令第一次绑定到元素时调用,el是被绑定指令的那个元素,这里是input元素
  bind: function (el) {},
  // 当被绑定的元素插入到 DOM 中时……
  inserted: function (el) {
    // 聚焦元素,这是js中dom原生方法
    el.focus()
  }
})
// 可以在模板中任何元素上使用新的 v-focus
<input v-focus>
// 该指令和data平级
directives: {
  focus: {
    // 指令的定义
    inserted: function (el) {
      el.focus()
    }
  }
}

12、生命周期函数

  • 在运行到beforeCreate函数时,data上的数据还没初始化好,methods中的方法也未初始化好。
  • 在运行到created函数时,data上的数据和methods中的方法已初始化好,可以访问。
  • 在这个阶段中,vue正在编译模板页面。当这个阶段执行完毕后,我们在浏览器的内存中,已经有了编译好的页面结构。但是这个编译好的页面结构只存在浏览器内存中,还未渲染到页面上。此时页面空白。
  • 当模板页面被编译好后,执行beforeMount函数,表示即将挂载。此时html代码结构已经在内存中创建好了,还未挂载到页面中。在这个函数中,DOM元素是原始的插值表达式之类的vue代码。
  • mounted函数,表示页面已经完成了渲染,标志创建阶段结束。如果要引用一些第三方插件来操作DOM元素,在此函数中
    上面是创建阶段,以下是运行阶段
  • beforeUpdate函数阶段,页面内容还是旧数据,但是data里面的数据是新数据。
  • updated函数阶段,数据已经更新。
  • beforeDestory函数时,vm实例还是可用状态,此时还没有开始销毁。
  • destory函数中,实例vm已经被销毁不可用。
  • 总结:创建阶段的生命周期函数,一个实例一辈子只执行一次。
    运行阶段的生命周期函数,一个实例可以由data的改变与否,执行零次或一次。
    销毁阶段的生命周期函数,一个实例一辈子只执行一次。
  • 在new Vue的时候,进行了以下步骤:
    (1)先初始化data和methods。
    (2)根据数据,在内存中渲染DOM树。
    (3)将创建好的DOM树挂载到页面显示给用户。此时创建阶段结束。
    (4)根据data中数据的改变,有选择的重新渲染内存中的DOM树。
    (5)把重新渲染的DOM树再次挂载到页面上。

13、async和await

  • 异步请求。await写在要修饰的函数前,async写在要修饰函数最近的父函数上。使用它们可以不用写.then就能得到数据。
async getInfo () {
  const result  = await axios.get('url')
  console.log(result)
}
// 还可以把axios挂载到vue构造函数的原型上。
Vue.prototype.$http = axios
// 然后通过this.$http调用
async getInfo () {
  const result  = await this.$http.get('url')
  console.log(result)
}
  • axios只支持post和get请求,不支持jsonp。如果涉及到跨域,最好在服务器接口启用cors。

14、定义全局组件的三种方式

  • 第一种方式:
    (1)先调用Vue.extend()得到组件的构造函数
const com1 = Vue.extend({
  template: '<h1>这是创建的第一个全局组件</h1>'
})

(2)通过Vue.component('组件的名称', 组件的构造函数)注册组件

Vue.component('mycom1', com1)

(3)把注册好的全局组件名称,以标签形式引入到页面中即可

<mycom1></mycom1>
  • 定义全局组件的第二种方式:
Vue.component('mycom2', {
	template: '<h2></h2>'
})
// 在页面上引入
<mycom2></mycom2>

注意:template中不能直接写文本,必须用标签包裹起来;如果想要放入多个元素,必须有一个根元素。

  • 定义全局组件的第三种方式:
<template id="templ">
  <div>
    <h3>
    第三个全局组件
    <//h3>
  </div>
</template>

Vue.component('mycom3', {
	template: '#templ'
})

// 在页面上引入
<mycom3></mycom3>

15、为什么组件中的data是function
因为这样做的话,每当我们在页面引用一次组件,必然会先调用这个data function,从而得到当前组件私有的数据对象。

16、父组件通过属性绑定向子组件传值

  • 父组件向子组件传递普通数据和对象
    如果要向子组件传递data中的数据,用属性绑定的形式v-bind
// 父组件将data里面的parentMsg传给子组件com1
// 在子组件上通过v-bind绑定值,msg是自定义的属性名
<com1 :msg="parentMsg"></com1>

// 子组件要在pops中接收这个值才能使用,接收的属性名称必须和父组件传递过来的自定义属性名称保持一致。props与data平级
// 在Vue中只有props是数组,其他的带有s后缀的属性都是对象
pops: ['msg']

// 子组件直接通过{{ msg }}使用
<div>{{ msg }} </div>
  • 父组件向子组件传递方法
    如果要向子组件传递methods中的方法,用方法绑定的形式v-on,子组件用$emit接收。
 // 在父组件中用@传递方法给子组件,方法名自定义,这里为func
 <com1 @func="show"></com1>
 // 父组件的show方法定义在methods中
 methods: {
   show () {
     console.log('我是父组件的show方法‘)
   }
 }
 //子组件在methods中通过$emit来接收func
 methods: {
   onClick () {
     this.$emit('func')
   }
 }
 // 此时点击绑定了onClick方法的子组件就能调用父组件的func方法
 <div @click="onClick"></div>

17、子组件向父组件传值

本质上还是调用了父组件向子组件传值的方法,只不过子组件在调用的时候把数据当做参数传给这个方法了。

将子组件中data里面的msg传递给父组件。在上面的 this.$emit(‘func’,this.msg)。父组件可以在func中接收msg。
show (msg) { console.log(msg) }

18、在Vue中$refs的使用

(1)获取页面上的元素
在要获取的元素上加ref属性<input ref="mycom" />
在methods中可以通过$refs获取

methods: {
  getIpt () {
    console.log(this.$refs.innerHTML) // this身上有$refs属性
  ]
}

(2)获取页面上的组件
因为有这个功能,所以可以通过ref来获取页面上的子组件

// 父组件页面上的子组件
<com1 ref="mycom"></com1>
// 子组件中的方法
show () {
  console.log('这是子组件的方法‘)’
}
// 父组件可以拿到子组件的show方法,也可以拿到子组件data的值
this.$refs.mycom.show()

19、vue中data和props的区别

  • data 在组件中,要被定义成一个function,并且返回一个对象。
  • props 在组建中,要被定义成数组,数组的值都是字符串名,表示父组件传递过来的数据
  • props的数据,不要直接拿来修改。如果想要修改,必须在data上重新定义一个属性,然后把属性的值从this.props拿过来。参考https://blog.csdn.net/qq_40623646/article/details/96327227
  • data上的数据是组件私有的,可读可写。props的数据是外界传递过来的,可读不可写。

20、vue-router路由使用

(1)导入vue-router组件
(2)创建对应组件。如login和register组件
(3)创建路由对象

const router = new Vuerouter({
  routes: [
    {path:'/login', component: login},
    {path:'/register', component: register}
  ]
})

(4)给vue实例vm制定router属性

const vm = new Router({
  el: '#app',
  data()[},
  router: router // 把路由对象通过vm的router属性挂载到vm上
})

(5)展示路由组件

<div id="app">
  <router-link to="/login'>登录</router-link> // 默认渲染为a标签
   <router-link to="/lregister'>注册</router-link>
  // 路由的坑,用来把匹配到的组件呈现在这个坑中。默认不会被渲染为任何元素
  <router-view />
</div>
  • 修改路由选中高亮。直接在router-link-active类里面添加样式。
  • redirect属性实现重定向
  routes: [
     {path:'/', redirect: login}, // 如果请求路径为/,重定向到login
    {path:'/login', component: login},
    {path:'/register', component: register}
  ]
  • 在路由中获取query形式传递的参数$route.query
  • 在路由中获取params形式传递的参数$route.params
  • query必须用path来引入,params要用name来引入。
  • query相当于get请求,url中会看到请求参数,params相当于post请求,url中不会看到请求参数。
  • 在路由中使用props获取参数
// 在要获取的route中加上porps:true
  routes: [
    {path:'/login/:id/:name', component: login,props: true},
    {path:'/register', component: register}
  ]
// 在对应的login组件的props中接收参数
props:['id', 'name']

-使用路由规则的children属性实现路由和组件的嵌套
如login是account的子路由

  routes: [
    {path:'/account', component: account, children: [
         {path:'login', component: login} // children属性创建的路由规则path前面不要带/
    ]}
  ]

21、watch的用法

  • 表示监听数据的变化。适合监听单个的虚拟的数据改变。‘键是要监听的数据’:数据变化时候的处理函数(最新的值,以前的值)
const vm = new Router({
  el: '#app',
  data(){
    return: {
      firstname: ''
    }
  },
  router,
  watch: {
    'firstname': function(newval, oldval){
      console.log(newval + oldval)
    }
  }
})
  • 使用watch监听URL地址的改变(在watch中可以监听vm上所有属性的改变)
    根据 $ route.path的不同,可以监听url的改变
    页面的刷新不会触发$route.path的改变
const vm = new Router({
  el: '#app',
  data(){
    return: {
     msg
    }
  },
  router,
  watch: {
    '$route.path': function(newval){
      console.log(newval) // newval就是新的url的路径
    }
  }
})
  • 对于复杂数据类型,如object array,需要深度监听
  •   'firstname': 
          deep: 'true',
          handler:function(newval, oldval){
        console.log(newval + oldval)
      }
    } ```
    

22、computed计算属性的使用

  • 只要计算属性的function中所依赖的任何值发生变化,则会触发计算属性重新求值。
  • 计算属性的值,如果被第一次计算后,没有发生过变化,则会把第一次的值缓存起来,供后续使用。
  • 计算属性里面有两个方法,get和set。get表示外界要调用的function的值,set表示外界为这个function重新赋值。默认是getter方法,不需要setter方法时直接写:
  • computed: { fullname: function() { return 要返回的值 } }
    需要setter方法时如下写:
 // 这里fullname表示computed要计算修改的数据。
 computed: {
   fullname: function() {
     get () { },
     set () { }
   }
 }

在这里插入图片描述

  • watch、computed、methods之间的对比
    (1)computed属性结果会被缓存,除非依赖的响应式属性变化才会重新计算。主要当做属性来使用。
    (2)methods方法表示一个具体的操作,主要书写业务逻辑。
    (3)watch一个对象,键是需要观察的表达式,值是对应回调函数。主要用来监听某些特定数据变化,从而进行具体的业务逻辑操作。可以看做是computed和methods的结合体。

23、webpack

(1)什么是webpack

  • webpack是前端项目的构建工具,如果想要提高项目的维护性和可控制性,选择webpack进行构建。
  • webpack非常适合与单页面应用程序结合使用,如vue,react,angular。
    (2)项目中使用webpack的好处
  • 能够处理静态资源的依赖关系。
  • 能够优化项目代码,比如:压缩合并文件;把图片转为base64编码格式。
  • 能够把高级语法转为低级语法。
  • 能够转换一些模板文件:.vue转为.js
    (3)安装webpack
  • 全局安装:npm i webpack -g
  • 在项目中安装: npm i webpack -D
    (4)在项目中使用webpack打包文件,并实现webpack的实时打包构建。使用html-webpack-plugin插件在内存中生成HTML文件。可以实现修改main.js和index.html中的代码保存后实时更新。
  • 在项目中新建配置文件webpack.config.js
  • 在配置文件中向外暴露一个配置对象,供webpack执行的时候读取
  • 安装html-webpack-plugin插件cnpm i html-webpack-plugin -D。作用:能根据给定的页面路径,在内存中生成一个一模一样的页面,自动把打包好的文件注入一个script标签。
const path = require('path')
const htmlWebpackPlugin = require('html-webpack-plugin') // 导入的是一个构造函数
module.exports = {
  entry: path.join(__dirname, './src/main.js'), // 指定要处理那个文件
  output: { // 指定输出文件的存放路径
    path: path.join(__dirname, './dist'),
    filename: 'bundle.js'
  },
   plugins: [ // 插件的数组
    new htmlWebpackPlugin({ // 创建一个把HTML首页托管到内存中的插件
      template: path.join(_dirname, './src/index.html'),
      filename: 'index.html'
    })
  ]
}
  • 本地安装webpack-dev-server实现实时打包构建效果,注意它依赖于webpack。cnpm i webpack webpack-dev-server -D
  • 打开package.js,找到scripts节点,在其中新增一个脚本命令
"scripts": {
    "dev": "webpack-dev-server --open --port 3000 --host 127.0.0.1 --hot" // --open表示自动打开页面,--port 3000表示指定端口号为3000, --host 127.0.0.1表示IP地址, --hot热更新,提高代码运行效率。都可以不加
  }
  • 只要在终端中运行npm run dev命令去执行dev脚本,启动webpack-dev-server这个实时构建编译的服务器。
  • 注意:webpack-dev-server打包出来的bundle.js并没有存放到实际的物理磁盘中,而是托管到了内存中!托管的路径是根目录,所以在引用的时候script标签营应该这样写<script src="/bundle.js"></script>
  • 如果中间报错,很可能是webpackwebpack-dev-server版本不兼容。先npm uninstall再重新安装指定版本。"html-webpack-plugin": "^2.30.1","webpack": "^3.8.0", "webpack-dev-server": "^2.9.7"版本可用。

24、export和export default

  • 在模块中,使用export default向外暴露成员,只能有唯一一个export default。
  • 使用export default向外暴露的成员对象,可以使用任何的合法变量名来接收。
  • export default和export可以同时使用。
  • 使用import 变量名from ‘标识符’这种形式导出得到的变量,默认只能拿到export default导出的成员。拿不到export导出的成员。
  • 使用export导出的成员,只能用import {成员名} from ‘标识符’ 来进行接收。
  • export导出成员没有次数限制,同时导出的成员必须按照导出的名称来接收,如果想要起别名,使用as关键字 import {c, d as dd} from '标识符’

25、ES6特性总结

  • let const
  • 箭头函数
  • Promise
  • 解构赋值
  • 默认形参
  • 函数扩展 function(x1,x2,x3)可以写成function(…arg)
  • 模板字符串 `${name}’
  • 字符串的拓展 .startsWith .endsWith padStart padEnd
  • async await
  • import 变量名 from ‘标识符’ export default export
  • class关键字

26、class关键字

  • class中constructor的使用
    用class定义的Per和上面的Person函数是一样的。每当new Per()的时候,必然会优先调用Per上的constructor构造函数。只有new出来的Person和Per实例才能访问到name和age。
    在class的{ }作用域中,只能写constructor函数、静态属性、静态方法、实例方法
    在class类中必须有一个constructor,如果你没有显示定义,则系统会默认提供一个看不见的constructor
    在这里插入图片描述
  • 在class类中定义静态属性静态方法和实例属性实例方法
    静态属性:通过类直接点出来的属性
    动态属性:通过类的实例点出来的属性
    第一种方式用原来构造函数的方法,不利于阅读:
    在这里插入图片描述
    第二种方式使用class来定义:、
    在这里插入图片描述
    在这里插入图片描述
  • 使用class实现面向对象编程
    什么叫面向对象:面向对象就是封装,极致的封装就是面向对象。就是把一些功能性的代码封装到具体的类中,如果需要什么功能就new什么类,这样既提高代码的复用性又提高了开发的效率和协作开发的体验。
    编程的发展历史是从面向过程(函数式编程)->面向对象(以对象的形式来组织代码)
    以下就是面向对象的类:在GDRen中name和age都已经在Person中定义了,只需要调用。eathobby是GDRen自己的特征挂载到自己身上。
    在这里插入图片描述
    在这里插入图片描述

27、Fetch API

  • 作用就是用来发送Ajax请求,目的是为了替代传统的XHR对象
    fetch(请求的url地址字符串)
    .then(function(response) {
    return response.json()
    }).then(result => {
    console.log(result)
    })

28、vuex

1、vuex是专为vue.js应用程序开发的状态管理模式。在vue项目中要处理各种各样的数据,但这些数据虽然多,从本质上划分为两类:组件内部私有的数据(组件之间不会共享的私有数据);组件之间共享的数据(父组件要共享给子组件的数据、子组件要共享给父组件的数据、兄弟组件之间传值)
2、当组件之间要共享数据的时候最好使用一个全局的数据存储对象来进行控制。
3、vuex要实现什么功能:在全局环境中,为所有组件之间共享数据。只要修改了全局的数据,所有引用了全局数据的组件也会同步更新数据。只有组件间共享的数据才有必要存储到vuex中。
4、使用vuex

  • 安装npm i vuex -S
  • 导入vuex import Vuex from 'vuex'
  • 把vuex安装到vue上 Vue.use(Vuex)
  • 创建store公共状态对象
    cons store = new Vuex.Store({ state:{ // 这个state中存储的数据就是我们要全局共享的数据 } })
  • 将创建的共享状态对象挂载到Vue实例中,这样所有的组件就可以直接从store中获取全局数据
    在这里插入图片描述
  • 如果想要在组件中访问全局的数据:
    this.$store.state.全局数据名称
    5、使用mapState映射state数据到组件中
  • 不使用this.$store.state.全局数据名称来访问全局的数据可以用mapState
  • 在组件中按需导入mapState import { mapState } from 'vuex'
  • 通过computed属性将state映射过来computed: mapState(["count"])
  • 在组件中直接使用count <div>{{ count }}</div>
    6、当computed里面还要写其他的计算属性,同时还要使用mapState时
    在这里插入图片描述
    7、修改state中的数据必须要调用mutations提供的方法
    在这里插入图片描述
  • 如果在组件中要调用mutations中的函数,可以通过this.$store.commit(‘方法名’)来调用或者使用mapMutations来映射方法到methods中
import { mapMutations } from 'vuex'

methods: {
  ...mapMutations(["方法名"]
}

8、使用getters包装数据

getters不会修改原数据,只是把数据按照我们的需求做了重新的组织和包装。
在这里插入图片描述

  • 使用方式1
    通过this.$store.getters.名称
  • 使用方式2
    通过mapGetters映射为计算属性
import { mapGetters } from 'vuex'
 computed: {
   ...mapGetters(['方法名'])
 }

9、actions

  • 注意:vuex官方虽然说不要在mutations中写异步函数操作,但是在mutations中定义了异步的方法也可以正常执行,只是vue-tools工具无法监视到数据的变化。
  • 在actions中可以定义一些行为,来提交对应的mutations方法。
  • 在actions中不能直接操作state,如果想修改state值,只能在actions中提交对应的mutations。
    在这里插入图片描述
  • 使用方式
    通过mapActions映射为计算属性
import { mapGetters } from 'vuex'
 methods: {
   ...mapActions(['方法名'])
 }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值