一、browser-sync
- 安装
npm i browser-sync -g
- 启动
法一:browser-sync start -s -f **/*
法二:
package.json配置
"scripts": {
"start": "browser-sync start -s -f **/* --directory --watch"
}
yarn start
html组成部分:
标签、属性、子元素
html属性:
自定义属性、固有属性
二、vue
插值表达式
{{ /^abc$/.test('a') }}
{{ false ? 'success' : 'fail' }}
{{obj.x}}
{{foo()}}
{{(function(){
var x = 100
})()}}
vue实例化
<div id="root">
<div>
<input
type="text"
v-model="task"
v-on:keyup.enter="handleKeyUp"
>
</div>
<ul>
<li v-for="(task, index) of tasks">
{{task}} <button v-on:click="handleClick(index)">X</button>
</li>
</ul>
</div>
<!-- 插值表达式 -->
<!-- {{ title }} -->
// 实例化Vue
new Vue({
el: "#root", // root节点
data: { // 数据源
title: 'hello world!!',
task: '',
tasks: [
'吃饭',
'睡觉',
'打豆豆'
]
},
methods: { // 方法
handleKeyUp() {
// 操作task
this.tasks.push(this.task)
this.task = ''
},
handleClick(index) {
this.tasks.splice(index, 1)
}
},
})
指令
指令 (Directives) 是带有 v-
前缀的特殊 attribute。
v-bind简写:
用于响应式地更新 HTML attribute
<input v-bind:value="task">
<div :[urlparser]="url + '!'"></div>
const data = {
urlparser: 'url',
url: 'http://www.baidu.com'
}
v-if
<p v-if="seen">现在你看到我了</p>
v-if
指令将根据表达式 seen
的值的真假来插入/移除 <p>
元素。
v-for
<li v-for="(task, index) of tasks"></li>
v-on简写@
<input v-on:input="handleInput">
v-model
<input v-model="task">
v-once
执行一次插值,当数据改变时,插值处的内容不会更新。
目的:提高性能。
<span v-once>这个将不会改变: {{ msg }}</span>
v-html
输出真正的 HTML
<div v-html="header"></div>
const data = {
header: '<iframe src="http://www.baidu.com"/>',
}
容易导致 XSS 攻击
v-text
<div v-text="header"></div>
数据双向绑定
v-model
Vue编程特点
- 数据驱动编程,不做DOM操作
- 响应性: 必须事先在data里定义好
- 响应特性的特例:
- vm.fruits.length
- vm.fruits[0] = '' // debug: vm.$forceUpdate()
- vm.obj.y = 200 // 给对象新增属性,得不到响应 debug: vm.$set(vm.obj, 'y', 200) or Vue.set(vm.obj, 'y', 300)
- BUG原因:Object.defineProperty(),不能监测数组的变化
- vm.$set(vm.fruits, 0, '🍉')
组件
- xml: 只作为一个数据承载的方式
组件的优势可以复用
vscode snipets<ul> <div>任务列表:</div> <my-list v-for="(item, index) of tasks" v-bind:item="item" v-bind:index="index" v-bind:tasks="tasks" ></my-list> <my-list v-for="(item, index) of fruits" v-bind:item="item" v-bind:index="index" v-bind:fruits="fruits" ></my-list> </ul>
// 定义一个组件 Vue.component('my-list', { props: ['item', 'index', 'tasks', 'fruits'], template: ` <li> {{item}} <button v-on:click="handleClick(index)">X</button> </li> `, methods: { handleClick(index) { // console.log(index) this.tasks.splice(index, 1) } }, })
实例
new Vue({
el: "#root", // root节点
data: { // 数据源
title: 'hello world!!',
task: '',
tasks: [
'吃饭',
'睡觉',
'打豆豆'
],
fruits: [
'🍇',
'🍒'
]
},
methods: { // 方法
// handleInput(e) {
// this.task = e.target.value
// }
handleKeyUp() {
// 操作task
this.tasks.push(this.task)
this.task = ''
}
},
})
生命周期函数(生命周期钩子)
beforeCreate
created
beforeMount
mounted
beforeUpdate
updated
beforeDestroy
destroyed
beforeCreate
beforeCreate() {
console.log('beforeCreate')
// 使用场景
// 1、可以在这里做一个非响应性特性的初始化数据
// 2、最早调用Ajax请求的钩子
// 测试用例
console.log(this)
console.log(this.title) // 不能访问title
this.initData = 'hello'
// 访问到了未解析的模板
// console.log(document.querySelector('#root').innerHTML)
setTimeout(() => {
this.title = 'word!!!'
}, 2000)
// ajax
setTimeout(() => {
this.fetchData()
}, 0)
},
created
created() {
console.log('created')
// 使用场景
// 1、可以初始化data里的数据
// 2、可以在这里做Ajax
console.log(this)
console.log(this.title)
this.title = 'world!!!'
console.log(document.querySelector('#root').innerHTML)
this.fetchData()
},
beforeMount
beforeMount() {
// 使用场景
// 1、再给一次初始化data里的数据的机会
// 2、可以在这里做Ajax
console.log('beforeMount')
console.log(this)
console.log(this.title)
console.log(document.querySelector('#root').innerHTML)
},
mounted
mounted() {
// 已经做完了第一次的渲染,才调用的mounted
// 使用场景
// 1、在DOM第一次渲染完毕后,做事情
// 2、比较适合在这里做Ajax
console.log(this)
console.log(this.title)
console.log(document.querySelector('#root').innerHTML)
this.title = 'world!!!'
this.fetchData()
setTimeout(() => {
this.$destroy()
}, 2000)
},
beforeUpdate
beforeUpdate() {
console.log('beforeUpdate')
},
updated
updated() {
console.log('updated')
},
beforeDestroy
beforeDestroy() {
console.log('beforeDestroy')
},
destroyed
destroyed() {
console.log('destroyed')
},
var vm = new Vue({
// el: '#root',
}
vm.$mount('#root')
生命周期图示:https://cn.vuejs.org/images/l...
计算属性 computed
<div id="example">
<p>Original message: "{{ message }}"</p>
<p>Computed reversed message: "{{ reversedMessage }}"</p>
</div>
var vm = new Vue({
el: '#example',
data: {
message: 'Hello'
},
computed: {
// 计算属性的 getter
// getter函数
// 根据依赖自动返回新的值,这个值可以是响应式的
// 根据依赖缓存:依赖的值不发生变化,计算属性(函数)不调用
// 计算属性一定要有返回值
reversedMessage: function () {
// `this` 指向 vm 实例
return this.message.split('').reverse().join('')
}
}
})
vm.message
发生改变时,所有依赖 vm.reversedMessage
的绑定也会更新.
监听属性 watch
1、监听数据(data)的变化,做一件事
2、特别适合异步操作的场景
<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
}
}
})
计算属性的 setter
计算属性默认只有 getter,不过在需要时你也可以提供一个 setter:
computed: {
fullName: {
// getter
get: function () {
return this.firstName + ' ' + this.lastName
},
// setter
set: function (newValue) {
var names = newValue.split(' ')
this.firstName = names[0]
this.lastName = names[names.length - 1]
}
}
}
现在再运行 vm.fullName = 'John Doe'
时,setter
会被调用,vm.firstName
和 vm.lastName
也会相应地被更新。
立即调用的函数表达式(IIFE)= 自执行函数
计算属性会根据依赖缓存,而方法不会。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。