生命周期
过滤器
-
调用的格式:
{{ data|过滤器名称 }}
—>{{ msg | test }}
-
调用的语法:
vue.filter('过滤器名称',function(){ 过滤器规则 })
-
调用规则: (就近原则)如果私有/本地过滤器和全局过滤器名称一致,这时候先调用私有过滤器;
-
过滤器中的function 中的参数: 第一个参数一定是过滤器管道符’
|
'前面传递过来的数据,过滤器的传参从第二个开始接收{{ msg | test('小白', '男孩', '12岁') }}
//全局过滤器 Vue.filter('test', function (msg,arg1,arg2){ return msg + arg1 + arg2 }) //本地过滤器/私有过滤器 filters: { toDou: function (msg){ return msg > 0 ? msg : '0' + msg } }
-
复合过滤器
复合过滤器的处理方式: 从前向后过滤,将第一个过滤器过滤后的结果传递给下一个过滤器,以此类推;
//vm 中的data data:{ msg:'aaa' }
//html中调用 {{ msg | test('疯狂','123') | test2 }} ==> aaa疯狂123=====
Vue.filter('test', function(msg,arg1,arg2){
return msg + arg1+arg2
})
Vue.filter('test2',function(msg){
return msg + ‘======’
})
自定义指令
vue中的所有指令,在调用的时候都是以v-
开头
参数1: 指令的名称在定义的时候,指令的名称前面,不需要加v-前缀,系统会默认自动加,但是使用的时候必须在名称前加v- 前缀来进行调用 // v-focus
参数2: 是一个对象,身上有一些指令相关的钩子函数,这些函数可以在特定的阶段,进行操作;
全局指令:
-
//全局组件 v-focus <input v-focus> 此功能替代 autofocus 因为 autofocus在移动版Safari上不工作 Vue.directive('focus', { //绑定元素插入到DOM中时 inserted: function(el){ //聚焦元素 el.focus() } })
局部指令:
-
directives: { focus: { inserted: function(el){ el.focus() } } }
钩子函数
Vue.directive('focus',{ //在每个函数中第一个参数永远是el,表示被绑定了指令的那个元素,这个el是原生js对象 bind:function(el){ //每当指令绑定到元素身上的时候,会立即执行这个bind函数,只执行一次,此时bind的元素还没被放到dom中,这时调用 focus方法没作用,因为元素只有插入到DOM中后,才能获取焦点 el.focus() }, inserted:function(){ //表示元素插入到DOM中的时候会执行此函数,只执行一次 el.focus() //此时能用focus }, update:function(){ //当组件更新的时候执行此函数,可能会触发多次 } }); //和样式相关的都可以在bind中实现,和行为相关的都在inserted中实现;bind执行时是在内存中,而inserted执行在页面中; //函数简写:(大多数情况下代码要写到bing和update中做重复动作,不关心其他钩子函数时可以缩写) Vue.directive('color-red', function(el,binding){ el.style.backgroundColor = binding.value })
watch 的用法:
<div id="app">
<router-link to="/login" tag="span">登录</router-link> <!--tag 标签表示将现有标签改为span标签显示在页面中-->
<router-link to="/register">注册</router-link>
<router-view></router-view>
</div>
var login = {
template: '<h3>登录页面</h3>'
}
var register = {
template: '<h3>注册页面</h3>'
}
var router = new VueRouter({
routes: [
{ path: '/', redirect: '/login'},
{ path: '/login', component: login},
{ path: '/register', component: register}
]
})
var vm = new Vue({
el: '#app',
data: {},
methods: {},
router,
watch: {
'$route.path': function(newVal, oldVal){
console.log(newVal + '---' + oldVal)
if(newVal === '/login'){
alert(欢迎进入登录页面)
}else{
alert(欢迎进入注册页面)
}
}
}
})
计算属性(computed)的应用:
<div id="app">
<input type="text" v-model="firstname" /> +
<input type="text" v-model="lastname" /> =
<input type="text" v-model="fullname" />
</div>
var vm = new Vue({
el: '#app',
data: {
firstname: '',
lastname: ''
},
methods: {},
computed: { //在computed 中,可以定义一些 属性,这些属性被叫做 [计算属性],计算属性的本质就是 一个方法,只不过,我们在使用这些计算属性的时候,把他们的 名称 ,直接当做属性来使用,注意:并不会把他当做方法;
//注意: 1. 计算属性在引用的时候一定不要加 '()'去调用,直接把它当做普通属性去使用就好
//注意: 2. 只要计算属性的 function 内部所用到任何 data 中的数据发生变化,就会立即重新计算这个属性的值
//注意: 3. 计算属性的求值结果会被缓存起来,方便下次直接使用,如果计算属性方法中所依赖的任何数据都没有发生过任何变化,则不会重新对计算属性求值
'fullname': function() {
return this.firstname + '-' + this.lastname
}
}
})
watch
、computed
、methods
之间的对比
-
computed
属性的结果会被缓存,除非依赖的响应式属性变化才会重新计算.主要被当做属性来使用; -
methods
方法表示一个具体的操作,主要写业务逻辑; -
watch
一个对象,键是需要观察的表达式,值是对应的函数.主要用来监听某些特定数据的变化,从而进行某些具体的业务逻辑操作;可以看作是computed
和mehods
的合体;
webpack从零开始
借助于webpack这个前端自动化构建工具,可以完美实现资源的合并、打包、压缩、混淆等诸多功能。基于node.js开发出来的前端工具;
安装webpack: npm i webpack -g
;
项目的自定义目录结构:
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<meta http-equiv="X-UA-Compatible" content="ie=edge"/>
<title>webpack</title>
<!-- 注意: 在入口文件index.html中 不推荐使用 script:src 或 link:href 标签,因为这样还是会发起多次请求,阻碍页面加载; -->
<!-- 只引入入口js文件 ,当使用html-webpack-plugin插件之后就不用引用这个文件了,因为这个插件会自动引用,而且会将此页面生成为一个内存页面-->
<script src="/build.js"></script>
</head>
<body>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
</body>
</html>
main.js
//这是我们项目的js入口文件,在此文件中导入模块 用 import ** from ** 的es6语法
import $ from 'jquery'
$(function(){
$('li:odd').css('backgroundColor','red')
$('li:even').css('backgroundColor',function(){
return '#' + '6cf'
})
})
此时可以运行webpack来测试效果;打开cmd命令输入:
webpack .\src\main.js .\dist\build.js
其中.\src\main.js
为要打包处理的文件路径 .\dist\build.js
打包好的输出文件路径(文件名称自定义)
运行后dist文件下会生成一个名称为 build.js的文件
webpack.config.js
//node.js语法,这个配置文件,通过node中的模块操作,向外暴露一个配置对象{应配置入口和出口文件}
const path = require('path')
const webpack = require('webpack') //启用热更新的第二步
module.exports = {
entry: path.join(__dirname, './src/main.js') //入口,表示要使用webpak打包那个文件
output: {//输出文件相关的配置
path: path.join(__dirname, './dist') //指定打包好的文件存放的目录
filename: 'build.js' //指定输出文件的名称
},
module: { //这个节点用于配置所有的第三方模块加载器
rules: [ //此数组中存放所有的第三方模块的匹配规则
{ test: /\.css$/, use: ['style-loader', 'css-loader'] }, //配置处理.css文件的第三方loader(安装loader的命令 npm i style-loader css-loader -D)
{ test: /\.(jpg|png|gif|jpeg|bmp)/, use: 'url-loader?limit=3210&name=[name].[ext]'}
//这里的字符串拼接和url地址中的字符串拼接完全一致,limit表示当图片文件大于等于3210 byte(字节)的时候,则不会被转为base64格式(默认转为base64),name=[name].[ext]表示 图片显示的文件名字为原文件名([name])和后缀名([ext]),默认情况下webpack打包的时候会将图片的地址修改成网络地址,为了防止图片命名冲突;name还可以赋值为name=[hash:8]-[name].[ext] 前面的[hash:8]表示选取前8位的hash值放到图片路径之前 (hash值为32位),结果可能为url(53a478f8-风景.jpg),这样也能避免打包时将重名图片覆盖;
]
}
//如果pakage.json文件的 script中dev已经配置了(--port等)那么下面的代码可以省略
devSever: { //这是配置dev-sever 命令参数的第二种形式,相对下面的 "dev"的直接 -- 配置的话会麻烦一些
open: true, //自动打开浏览器
port: 3000, //运行的端口
contentBase: 'src', //指定托管的根目录
hot: true //启动热更新的第一步
},
plugins: [//配置插件的节点
new webpack.HotModuleReplacementPlugin() //new 一个热更新的模块对象,这是启用热更新的第三步
]
}
webpack-dev-sever 工具, 实现自动打包编译功能
-
运行
npm i webpack-dev-sever -D
把这个工具安装到目录的本地开发依赖 -
安装完毕后,这个工具的用法和
webpack
完全一致
用法: 在工程文件package.json
中的 script
标签内配置
注意: json文件中禁止写注释,会报错!!!
"script": {
"dev": "webpack-dev-server --open --port 3000 --contentBase src --hot"
// --open 是自动打开浏览器
// --port 3000 是自动设置端口
// --contentBase src 是修改访问的根目录
// --hot 热加载/热更新(只更新成小补丁更新到build.js中,不用每次重新打包完整的build.js,还可以实现浏览器无刷新重载)
}
此时再运行npm run dev
后再修改代码 就可以自动编译(实际是webpack-dev-sever
帮我们打包生成的文件并没有存放到实际的物理磁盘上;而是直接托管到了电脑的内存中,所以我们在根目录中并看不到打包好的build.js
文件,这样做的好处就是快);