vue笔记
1.体验vue
-
导入vue
<script src='vue包路径'></script>
-
添加vue的控制区域
<div id='app'>{{msg}}</div>
-
实现vue
<script> var vm = new Vue({ el:'#app', data:{ msg:'hello world' }, methods:{ stop:function(){ //老写法 }, show(){ //新写法 } } }); </script>
2.文本操作
- v-clock 解决插值表达式闪烁问题
- v-text 没有闪烁问题,
<div v-text ="msg"></div>
- v-html插入值时可以解析html,
<div v-html="msg"></div>
- v-bind:绑定属性,可简写为:属性,
<input type='button' value='按钮' :title='msg'>
- v-on:事件绑定,可简写为@事件名,
<input type='button' value="按钮" @click='show'>
3.事件修饰符
- .stop防止冒泡,由里向外,
<div @click.stop="show">
- .prevent阻止默认行为,
<a href='' @click.prevent="show">
- .capture捕获事件,由外向里,
<div @click.capture='show'>
- .self只有点击当前元素才会出现调用方法,
<div @click.self='show'>
- .once只执行一次,
<div @click.once='show'>
4.数据双向绑定
- v-model,只适用于表单元素,代表value,
<input type='text' v-model='mag'></input>
<select v-model=''><select>
默认选择- 数据发生变化就会响应
5.类样式
<h1 :class="['thin','red']">
<h1 :class="['thin','red',flag?'active':'']">
<h1 :class="['thin','red' {'active':flag}]">
,flag是在vue的data中<h1 :class="classObj">
用vue标签定义的,如果出现变量则去vue中查找
6.标签内部样式
<div :style="[styleObj1,styleObj2 ]"></div>
7.循环
-
<p>{{list[0]}}</p>
-
<p v-for="(item,i) in list">{{i}}-----{{item}}</p> //list在data中存放方式list:[1,2,3,4]
-
<p v-for="(user,i) in list">{{user.id}} ----{{user.name}}</p>
-
list:[ {id:1,name:'tom'}, {id:2,name:'key'} ]
-
-
<p v-for="(val,key,i) in user">{{val}}</p>
user:{ id:1, name:'tom' }
-
<p v-for="count in 10">{{count}}</p>
-
key属性的使用,如果循环有问题必须加:key
<p v-for="item in list" :key="item.id"> <p>{{item.id}}</p> </p>
8.显示与隐藏
- v-if,删除获取添加元素
<p v-if="flag"></p>
- v-show,在元素中添加
display:none,<p v-show='flag'></p>
9.遍历list
-
some,循环找到符合条件的元素,然后处理
list.some((item,i)=>{ if(item.id === id){ //进行操作 return ture;//停止 } })
-
findIndex找到符合小件元素的index
list.findIndex(item=>{ if(item.id === id){ return true;//返回符合条件的index } })
-
filter,返回符合条件的项目数组
list.filter(item=>{ if(item.name.includes(keywords)){//includes判断是否包含 return item; } })
10.v-for里面使用函数,使用动态列表
<tr v-for="item in search(keywords)" :key="item.id">
<td>
<a href="" @click.prevent="del(item.id)">删除</a>
</td>
</tr>
11.过滤器
-
全局过滤器
<tr> <td>{{item.ctime|dateFormat()}}</td>//通过管道将内容传递给dateFormat,带括号表示可以传参 </tr> <script> Vue.filter('dateFormat',function(dataStr,pattern=""){ var dt = new Date(dataStr); var y = dt.getFullYear(); return `${y}`//没有理解 }) </script>
-
私有过滤器
var vm = new Vue({ el:"", data:{}, methods:{}, filters:{ dateFormat:function(dataStr,pattern=""){ var dt = new Date(dataStr); var y = dt.getFullYear(); return `${y}`//没有理解 } } });
12.自定义全局按键修饰符
<input type="text" v-model="name" @keyup.f2="add">//add是方法,按F2执行该方法
<script>
Vue.config.keyCodes.f2 = 113 //每个按键都有对应的数字,可以任意指定
</script>
13.定义指令,等同于为标签添加自定义私有属性
-
全局指令
<input type="text" v-focus v-fontweight="900">//理解何时加单引号,双引号 <script> Vue.directive('focus',{//增加样式时用它 bind:function(el){}, inserted:function(el){//增加javascript时用它 el.focus();//el表示DOM中的元素 }, updated:function(el){} }) </script>
-
私有指令
var vm = new Vue({ el:"", data:{}, methods:{}, filters:{}, directives:{ 'fontweight':{ bind:function(el,binding){ el.style.fontWeight = binding.value; } }, 'fontsize':function(el,binding){//同时给bind和update添加 el.style.fongSize = parseInt(binding.value)+"px"; } } });
14.生命周期
-
vue的整个生命周期
<script> var vm = new Vue({ el:"", data:{}. methods:{ beforeCreate(){},//对象被创建没有初始化,data和methods还没有被初始化 created(){},//data和methods被初始化完成,也是最早能够调用data和methods的地方 beforeMount(){},//模板形成并且已经保存在内存中没有挂在 mounted(){},//模板挂在到页面中 beforeUpdate(){},//数据更新了,但是页面还没有更新 updated(){} } }); </script>
15.向后台发请求,ajax
-
利用vue-resource实现请求操作
1.引入vue-resource库 <scritp src="./lib/vue.xx.js"></script>//先引入vue <script src="./lib/vue-resource.xx.js"></script> 2.在vue中发请求 <script> var vm = new Vue({ el:"", data:{}. methods:{ getInfo(){ this.$http.get('http://').then(function(result){ console.log(result.body); }) }, postInfo(){ this.$http.post('http://',{[数据]},{emulateJSON:true}).then(result=>{ console.log(result.body); }) }, jsonpInfo(){ this.$http.jsonp('http://').then(result=>{ console.log(result.body); }) } } }); </script>
16.动画
-
过度类名实现动画
//1.写css <style> .v-enter,.v-leave-to { opacity:0; transform:translateX(150px); } .v-enter-active,.v-leave-active { transition:all 0.8 ease; } </style> //2.将动画元素用transition包上 <input type="button" value='toggle' @click="flag=!flag"> <transition>//name属性可以指定不用属性不用v开头 <h3 v-if="flag">动画</h3>//flag在vue中赋值 </transition>
-
利用第三方库实现动画
//1.引入库 <style> <link rel='stylesheet' href="./lib/animate.css"> </style> //2.使用样式 <transition enter-active-class="bounceIn" leave-active-class="bounceOut" :duration={enter:200,leave:300}> <h3 v-if='flag' class="animated">这是一个H3</h3> </transition>
-
钩子函数,半场动画
1.利用transition包住动画元素 <transition @before-enter="beforeEnter" @enter="enter" @after-enter="afterEnter"> <div v-shwo="flag"></div> </transition> 2.在vue中实现这几个函数 <script> var vm = new Vue({ el:"", data:{ flag:false; }, methods:{ beforeEnter(el){ //el相当于dom中的元素 el.style.transform = 'translate(0,0)'; }, enter(el,done){ el.offsetWidth//必须有这句 el.style.transform="translate(150px,450px)"; el.style.transition="all 2s ease"; dong(); }, afterEnter(el){ this.flag = !this.false; } } }); </script>
17.组件
-
创建组件方式一
//1.引入组件 <div id="app"> <mycom1></mycom1> </div> //2.创建全局组件 <script> Vue.component('mycom1',Vue.extend({ template:'<h3>组件</h3>' })) var VM = new Vue({}) </script>
-
创建组件方式二
//1.引入组件 <div id="app"> <mycom1></mycom1> </div> //2.创建全局组件 <script> Vue.component('mycom1',{ template:'<h3>组件</h3>' }) var VM = new Vue({}) </script>
-
创建组件方式3
1.引入组件 <div id="app"> <mycom1></mycom1> </div> 2.创建组件的template <template id='tmp1'> <div>//必须用一个标签包住 <h4>大家好</h4> </div> </template> 2.创建全局组件 <script> Vue.component('mycom1',{ template:'#temp1' }) var VM = new Vue({}) </script>
-
私有组件
1.引入组件 <div id="app"> <login></login> </div> 2.创建组件的template <template id='tmp1'> <div>//必须用一个标签包住 <h4>大家好</h4> </div> </template> 2.创建全局组件 <script> var VM = new Vue({ el:'#app', data:{}, methods:{}, directives:{}, components:{ login:{ template:"#temp1"; } } }) </script>
-
组件中的data和methods
<script> Vue.component('mycoml',{ template:'<h1>{{msg}}</h1>', data:function(){//必须写成函数 return {//必须有返回值,并且返回值必须是对象 msg:'大家好' } } }) </script>
-
组件切换方式1
<login v-if="flag"></login> <register v-else="flage"></register>
-
组件切换方式2
//1. <component :is="comName"></component> //2. <script> Vue.component('login',{ template:'<h1>login</h1>' }); Vue.component('register',{ template:'<h1>register</h1>' }); var vm = new Vue({ el:'#app', data:{ comName = 'login' } }); </script>
-
父组件向子组件传值,通过属性绑定的方式
//1.父组件在引用子组件的时候,通过属性绑定的形式给子组件传值 <div id="app"> <com1 v-bind:parentmsg="msg"></com1> </div> //2.在子组件中使用父组件传过来的值 <script> var vm = new Vue({ el: '#app', data: { msg: '123 啊-父组件中的数据' }, methods: {}, components: { com1: { data() { return { title: '123', content: 'qqq' } }, template: '<h1 @click="change">这是子组件 --- {{ parentmsg }}</h1>', // 把父组件传递过来的 parentmsg 属性,先在 props 数组中,定义一下 props: ['parentmsg'], directives: {}, filters: {}, components: {}, methods: { change() { this.parentmsg = '被修改了' } } } } }); </script>
9.子组件给父组件传值,通过父组件将方法传递给子组件
<div id="app"> <com2 @func="show"></com2> </div> <template id="tmpl"> <div> <h1>这是 子组件</h1> <input type="button" value="子组件按钮" @click="myclick"> </div> </template> <script> var com2 = { template: '#tmpl', data() { return { sonmsg: { name: '小头儿子', age: 6 } } }, methods: { myclick() { this.$emit('func', this.sonmsg) } } } var vm = new Vue({ el: '#app', data: { datamsgFormSon: null }, methods: { show(data) { this.datamsgFormSon = data } }, components: { com2 } }); </script>
18.ref获取DOM元素
-
在标签中写入ref属性
<div id="app"> <input type="button" value="获取元素" @click="getElement" ref="mybtn"> <h3 id="myh3" ref="myh3">哈哈哈, 今天天气太好了!!!</h3> <hr> <login ref="mylogin"></login> </div>
-
通过ref获取标签和组件元素
<script> var login = { template: '<h1>登录组件</h1>', data() { return { msg: 'son msg' } }, methods: { show() { console.log('调用了子组件的方法') } } } // 创建 Vue 实例,得到 ViewModel var vm = new Vue({ el: '#app', data: {}, methods: { getElement() { console.log(document.getElementById('myh3').innerText) console.log(this.$refs.myh3.innerText) console.log(this.$refs.mylogin.msg) this.$refs.mylogin.show() } }, components: { login } }); </script>
19.路由
-
基本使用
1.安装路由模块 <script src="./lib/vue-router-3.0.1.js"></script> 2.创建路由对象 <script> var routerObj = new VueRouter({ routes: [ // 路由匹配规则 //参数1路径,参数2组件模板,必须是变量 { path: '/login', component: login }, { path: '/register', component: register } ], linkActiveClass: 'myactive'//路由激活后使用的类样式 }) </script> 3.在html中添加路由相关标签 //路由标签 <router-link to="/login" tag="span">登录</router-link> <router-link to="/register">注册</router-link> //给组件占位置的 <transition mode="out-in"> <router-view></router-view> </transition> 4.在vue中添加路由标签 <script> var vm = new Vue({ el: '#app', data: {}, methods: {}, router: routerObj }); </script>
-
路由地址中传递参数
- 方式一
1.在地址中加入参数 <router-link to="/login?id=10&name=zs">登录</router-link> <router-link to="/register">注册</router-link> 2.在组件模板中使用此参数 <script> var login = { template: '<h1>登录 {{ $route.query.id }} - {{ $route.query.name }}</h1>' } </script>
- 方式二
1.在地址中加入参数 <router-link to="/login/12/ls">登录</router-link> <router-link to="/register">注册</router-link> 2.在组件模板中使用此参数 <script> var login = { template: '<h1>登录 {{ $route.query.id }} - {{ $route.query.name }}</h1>', created(){ // 组件的生命周期钩子函数 console.log(this.$route.params.id) } } </script>
-
路由匹配规则嵌套
<script> var router = new VueRouter({ routes: [ { path: '/account', component: account, children: [//children里面的不要path不要带/ { path: 'login', component: login }, { path: 'register', component: register } ] } ] }) </script>
-
路由实现经典布局
1.标签 <div id="app"> <router-view></router-view> <div class="container"> <router-view name="left"></router-view> <router-view name="main"></router-view> </div> </div> 2.路由 <script> var router = new VueRouter({ routes: [ { path: '/', components: { 'default': header, 'left': leftBox, 'main': mainBox } } ] }) </script>
20.检测数据发生变化做出相应
-
通过keyup事件
1.html代码 <input type="text" v-model="firstname" @keyup="getFullname"> + <input type="text" v-model="lastname" @keyup="getFullname"> = <input type="text" v-model="fullname"> 2.vue代码 <script> var vm = new Vue({ el: '#app', data: { firstname: '', lastname: '', fullname: '' }, methods: { getFullname() { this.fullname = this.firstname + '-' + this.lastname } } }); </script>
-
通过watch实现
1.html代码 <input type="text" v-model="firstname"> + <input type="text" v-model="lastname"> = <input type="text" v-model="fullname"> 2.vue代码 <script> var vm = new Vue({ el: '#app', data: { firstname: '', lastname: '', fullname: '' }, methods: {}, watch: { // 使用这个 属性,可以监视 data 中指定数据的变化,然后触发这个 watch 中对应的 function 处理函数 'firstname': function (newVal, oldVal) { this.fullname = newVal + '-' + this.lastname }, 'lastname': function (newVal) { this.fullname = this.firstname + '-' + newVal } } }); </script>
-
通过computed实现
1.html代码 <input type="text" v-model="firstname"> + <input type="text" v-model="middlename"> + <input type="text" v-model="lastname"> = <input type="text" v-model="fullname"> 2.vue代码 <script> // 创建 Vue 实例,得到 ViewModel var vm = new Vue({ el: '#app', data: { firstname: '', lastname: '', middlename: '' }, methods: {}, computed: { 'fullname': function () { console.log('ok') return this.firstname + '-' + this.middlename + '-' + this.lastname } } }); </script>
-
上面方法的区别
computed
属性的结果会被缓存,除非依赖的响应式属性变化才会重新计算。主要当作属性来使用;methods
方法表示一个具体的操作,主要书写业务逻辑;watch
一个对象,键是需要观察的表达式,值是对应回调函数。主要用来监听某些特定数据的变化,从而进行某些具体的业务逻辑操作;可以看作是computed
和methods
的结合体;
21.使用webpack创建第一个项目
21.1创建的第一个项目
-
创建目录结构,然后通过命令
npm init -y
初始化目录- 目录结构一个dist目录,一个src目录,src中包含js,css,images,index.html,main.js
-
main.js是所有文件的入口
-
此文件中引入jQuery
1.写入jQuery内容 import $ from 'jquery' //es6写法,需要通过webpack将进行转化 $('#list li:even').css('backgroundColor','lightblue'); $('#list li:odd').css('backgroundColor','pink');
-
-
使用webpack进行打包
-
利用webpack将es6语法转换成低版本浏览器可以支持的语法,将main.js打包
webpack src/js/main.js -o dist/bundle.js
-
通过配置webpack.config.js,来简化打包命令
var path = require('path'); module.exports = { entry: path.resolve(__dirname, 'src/js/main.js'), // 项目入口文件 output: { // 配置输出选项 path: path.resolve(__dirname, 'dist'), // 配置输出的路径 filename: 'bundle.js' // 配置输出的文件名 } }
-
修改文件内容后,实时打包(webpack-dev-server)
npm i webpack-dev-server --save-dev//安装开发依赖 安装完成之后在package.json文件的scripts节点下新增"dev":"webpack-dev-server --open --port 3000 --contentBase src --hot" 同时将页面中的bundle.js路径进行修改,因为这个插件会在内存中给我们生成一个bundle.js文件 <script src="bundle.js"></script> 最后通过npm run dev来运行项目
-
由于–contentBase,指定目录比较繁琐,所有使用html-webpack-plugin插件
-
插件安装
npm i html-webpack-plugin --save-dev
安装到代发依赖(插件安装到开发依赖) -
修改webpack.config.js文件
var path = require('path'); var htmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { entry: path.resolve(__dirname, 'src/js/main.js'), // 项目入口文件 output: { // 配置输出选项 path: path.resolve(__dirname, 'dist'), // 配置输出的路径 filename: 'bundle.js' // 配置输出的文件名 }, plugins:[ // 添加plugins节点配置插件 new htmlWebpackPlugin({ template:path.resolve(__dirname, 'src/index.html'),//模板路径 filename:'index.html'//自动生成的HTML文件的名称 }) ] }
-
修改package.json文件中的script的内容,同时将参数配置到wenpack.config.js中(写在这两个地方的任意一处都可以)
-
修改package.json
"dev": "webpack-dev-server"
-
修改webpack.config.js内容
1.devServer:{ hot:true, open:true, port:4321 } 2.var webpack = require('webpack'); 3.在plugins中添加 new webpack.HotModuleReplacementPlugin()
-
-
去掉index.html中的script标签,因为html-webpack-plugin会给自动加上
-
-
-
webpack打包样式文件(默认webpack只能处理js文件)
-
webpack打包css文件
-
在main.js中引入文件,import ‘./css/index.css’
-
安装解析css的loader
npm i css-loader style-loader --save-dev
-
配置webpack.config.js文件
module: { // 用来配置第三方loader模块的 rules: [ // 文件的匹配规则 { test: /\.css$/, use: ['style-loader', 'css-loader'] }//处理css文件的规则 ] }
-
-
webpack打包less文件(步骤与css一样,除了下载的loader)
cnpm i less-loader less -save-dev
webpack.config.js的module中添加
{ test: /\.less$/, use: ['style-loader', 'css-loader', 'less-loader'] },
-
webpack处理sass文件
cnpm i sass-loader node-sass --save-dev
webpack.config.js的module中添加
{ test: /\.scss$/, use: ['style-loader', 'css-loader', 'sass-loader'] }
-
webpack打包图片文件
-
下载url-loader
npm i url-loader --save-dev
-
在webpack.config.js的module中添加
{ test: /\.(jpg|png|gif|bmp|jpeg)$/, use: 'url-loader?limit=7631&name=[hash:8]-[name].[ext]' }//当limit数值大于图片自身时显示base64编码,小于图片自身时显示图片地址
-
-
引入boostrap文件
-
安装boostrap,
npm i boostrap --save-dev
-
在入口文件main.js引入boostrap,
import 'bootstrap/dist/css/bootstrap.css'
-
在webpack.config.js的module中添加
{ test: /\.(ttf|eot|svg|woff|woff2)$/, use: 'url-loader' },
-
-
-
当文件中出现es6以上的语法时使用babel来解析
-
es7语法例子
class Person{ static info = {name:'tom',age:17}} console.log(Person.info)
-
安装babel包
npm i babel-core babel-loader babel-plugin-transform-runtime -D npm i babel-preset-env babel-preset-stage-0 -D
-
在webpack.config.js中进行配置
{ test:/\.js$/, use: 'babel-loader', exclude:/node_modules/ }
-
创建.babelrc文件并写入如下内容
{ "presets": ["env", "stage-0"], "plugins": ["transform-runtime"] }
-
21.2.webpack结合vue
-
在webpack中使用vue原来的方式写代码时可进行如下两种配置
-
安装vue
npm i vue -S npm i vue-loader vue-template-compiler -D
-
在入口文件中引入vue,
import Vue from '../node_modules/vue/dist/vue.js'
-
或者在webpack.config.js文件中配置
resolve: { alias: { // 修改 Vue 被导入时候的包的路径 "vue$": "vue/dist/vue.js" } }
-
-
webpack中使用vue中的路由
-
安装路由
vue-router
-
在入口文件中引入路由
import VueRouter from 'vue-router' Vue.use(VueRouter)
-
创建组件如
app.vue
路由的具体内容如下<template> <div> <h1>这是 App 组件</h1> <router-link to="/account">Account</router-link> <router-link to="/goodslist">Goodslist</router-link> <router-view></router-view> </div> </template> <script> export dufault {} </script> <style scoped> </style>
-
创建路由文件router.js,在该文件中引入组件
import app from './App.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
-
在入口文件main.js中添加
var vm = new Vue({ el: '#app', render: c => c(app), router // 4. 将路由对象挂载到 vm 上 })
-
22.组件渲染
-
写入html代码(占位)
<div id="app"></div>
-
创建组件
import router from './router.js' var login = { template: '<h1>这是登录组件</h1>' }
-
引入vue
var vm = new Vue({ el: '#app', data: {}, methods: {}, render: function (createElements) { // createElements 是一个 方法,调用它,能够把 指定的 组件模板,渲染为 html 结构 return createElements(login) // 注意:这里 return 的结果,会 替换页面中 el 指定的那个 容器 } });