表单输入需要进行双向数据绑定,所以使用v-model。
收集value值;type=password、text、number。不接受插值语法; 单选框需要标识name,否则不会排他,手机value值; :没有配置value属性,那么收集的是checked属性(勾选 or 未勾选,是布尔值);若配置了value属性:v-model 会忽略任何表单元素上初始的 value、checked 或 selected attribute,应该在 JavaScript 中使用data 选项来声明该初始值。
v-model的三个修饰符:
过滤器:
定义:对要显示的数据进行特定格式化后再显示(适用于一些简单逻辑的处理)
注册过滤器:
Vue.filter(name, callback)全局过滤器
new Vue {filters: {}} 局部过滤器
使用过滤器:{{ xxx | 过滤器名}} 或 v-bind:属性 = "xxx | 过滤器名"

v-text:v-text会替换掉节点中的内容,;v-html:向指定节点中渲染包含html结构的内容 ,会替换掉节点中所有的内容,;v-cloak:本质是一个特殊属性,Vue实例创建完毕并接管容器后,会删掉v-cloak属性;所以可以在加载vue慢的时候使用v-cloak属性接管节点,设置该属性不可见,解决{{xx}}问题;v-once:所在节点在初次动态渲染后,就视为静态内容了,以后数据的改变不会引起v-once所在结构的更新,可以用于优化性能;v-pre:跳过v-pre所在节点的编译过程,可利用它跳过:没有使用指令语法、没有使用插值语法的节点,会加快编译自定义指令:
new Vue({
directives:{
指令名:配置对象
}
})
new Vue({
directives:{
指令名:回调函数
}
})
Vue.directive(指令名, 配置对象)
或
Vue.directive(指令名, 回调函数)
Vue.directive('fbind', {
// 指令与元素成功绑定时(一上来)
bind(element, binding) { // element就是DOM元素,binding就是要绑定的
element.value = binding.value
},
// 指令所在元素被插入页面时
inserted(element, binding) {
element.focus()
},
// 指令所在的模板被重新解析时
update(element, binding) {
element.value = binding.value
}
})

Vue 完成模板的解析并把初始的真实 DOM 元素放入页面后(挂载完毕)调用 mounted;



数据代理与数据监测:创建前、创建完毕;
虚拟DOM:将要挂载与挂载完毕;
model->view:将要更新与更新完毕;
所有:将要销毁和销毁完毕。
组件是用来实现局部功能的代码和资源的集合。
组件允许我们将 UI 划分为独立的、可重用的部分,并且可以对每个部分进行单独的思考。在实际应用中,组件常常被组织成层层嵌套的树状结构:

优点:复用编码,简化项目编码,提高运行效率。
非单文件组件:一个文件中包含有 n 个组件
单文件组件:一个文件中只包含有 1 个组件,后缀.vue
使用非单文件组件:(不推荐)
创建:
const 组件名 = Vue.extend({options})
注册:
//局部注册
new Vue({
el:'',
data:{},
components:{组件名:组件}
})
//全局注册
Vue.component('组件名',组件)

脚手架里才能处理自闭合标签。如果你是直接在 DOM 中书写模板 (例如原生 元素的内容),模板的编译需要遵从浏览器中 HTML 的解析行为,必须显式使用闭合标签。

VueComponent:
单文件组件:
<template>
<button @click="count++">You clicked me {{ count }} times.</button>
</template>
<script>
export default {
name:'组件名',
data() {
return {
count: 0
}
}
}
</script>
<script>
import ButtonCounter from './ButtonCounter.vue'
export default {
components: {
ButtonCounter
}
}
</script>
<template>
<h1>Here is a child component!</h1>
<ButtonCounter />使用
</template>
介绍一下vue项目总体结构:
APP.vue文件,调用组件;App.vue;如果main.js中不想写任何东西,可以按照如下编写:
new Vue({
template:` `,
el:'#root',
components:{App}
})

render函数(渲染函数):用js语言来构建DOM,因为vue是虚拟DOM,所以在拿到template模板时也要转译成VNode的函数,而用render函数构建DOM,vue就免去了转译的过程。当引入残缺的vue时,用render。render 函数 跟 template 一样都是创建 html 模板的,但是有些场景中用 template 实现起来代码冗长繁琐而且有大量重复,这时候就可以用 render 函数。
new Vue({
el:'#app',
// render函数功能:将App组件放入容器中
// 简写形式
render: h => h(App),
// 完整形式
// render(createElement){
// return createElement(App)
// }
})
ref属性:
或this.$refs.xxxprops配置项:
这里age前加:,通过v-bind使得里面的18是数字props: {
name: {
type: String, // 类型
required: true,// 必要性
default: 'cess'// 默认值
}
}
注:props是只读的,Vue底层会监测你对props的修改,如果进行了修改,就会发出警告,若业务需求确实需要修改,那么请复制props的内容到data中,然后去修改data中的数据。
mixin:
功能:可以把多个组件共用的配置提取成一个混入对象。
数据和方法冲突时,组件优先;生命周期钩子全要。混入对象的钩子将在组件自身钩子之前调用。
定义:
const mixin = {
data() {....},
methods: {....}
....
}
使用:
Vue.mixin(xxx)mixins:['xxx']功能:用于增强Vue
本质:包含install方法的一个对象,install的第一个参数是Vue,第二个以后的参数是插件使用者传递的数据。
可以在其中写些全局操作。
定义插件:
export default {
install(Vue,x,y,z){}
}
使用插件:Vue.use(插件名,数据)
作用:让样式在局部生效,防止冲突
写法:
WebStorage(js 本地存储)
存储内容大小一般支持 5MB 左右(不同浏览器可能还不一样)
浏览器端通过Window.sessionStorage和Window.localStorage属性来实现本地存储机制
相关API
xxxStorage.setItem(‘key’, ‘value’)该方法接受一个键和值作为参数,会把键值对添加到存储中,如果键名存在,则更新其对应的值
xxxStorage.getItem(‘key’)该方法接受一个键名作为参数,返回键名对应的值
xxxStorage.removeItem(‘key’)该方法接受一个键名作为参数,并把该键名从存储中删除
xxxStorage.clear()该方法会清空存储中的所有数据
备注
子组件想给父组件传数据,那么就要在父组件中给子组件绑定自定义事件(事件的回调在A中)。
或this.$refs.demo.$on('事件名',方法)this.$emit('事件名',数据) this.$off('事件名')父组件:
<School :getSchoolName="getSchoolName"/>
<Student @demo="m1"/>
<Student ref="student" @click.native="show"/>
<script>
import Student from './components/Student'
import School from './components/School'
export default {
name:'App',
components:{School,Student},
data() {
return {
msg:'你好啊!',
studentName:''
}
},
methods: {
getSchoolName(name){
console.log('App收到了学校名:',name)
},
m1(){
console.log('demo事件被触发了!')
},
show(){
alert(123)
}
},
mounted() {
this.$refs.student.$on('demo',this.m1) // 绑定自定义事件
// this.$refs.student.$once('demo',this.m1) // 绑定自定义事件(一次性)
},
}
script>
子组件:
<h2>当前求和为:{{number}}</h2>
<button @click="add">点我number++</button>
<button @click="unbind">解绑自定义事件</button>
<button @click="death">销毁当前Student组件的实例(vc)</button>
<script>
export default {
name:'Student',
data() {
return {
name:'张三',
sex:'男',
number:0
}
},
methods: {
add(){
//父组件中的自定义事件名与数据
this.$emit('atguigu',this.name,666,888,900)
// this.$emit('demo')
// this.$emit('click')
},
unbind(){
// 解绑
this.$off('atguigu') //解绑一个自定义事件
// this.$off(['atguigu','demo']) //解绑多个自定义事件
// this.$off() //解绑所有的自定义事件
},
death(){
// 销毁了当前Student组件的实例,销毁后所有Student实例的自定义事件全都不奏效
this.$destroy()
}
},
}
</script>
一种可以在任意组件间通信的方式,本质上就是一个对象,它必须满足以下条件:
$on $emit $off方法去绑定、触发和解绑事件使用步骤:
new Vue({
...
beforeCreate() {
Vue.prototype.$bus = this // 安装全局事件总线,$bus 就是当前应用的 vm
},
...
})
export default {
methods(){
demo(data){...}
}
...
mounted() {
this.$bus.$on('xxx',this.demo)
}
}
b:提供数据:this.$bus.$emit('xxx',data)
这是一个生命周期钩子
this.$nextTick(回调函数)在下一次DOM更新结束后执行其指定的回调
什么时候用:当改变数据后,要基于更新后的新DOM进行某些操作时,要在nextTick所指定的回调函数中执行
this.$nextTick(function () {
this.$refs.inputTitle.focus();
});
待补充
解决跨域问题:
如何配置代理服务器:
配置文件vue.config.js:
方法一:
module.exports = {
devServer:{
proxy:"http://localhost:5000"
}
}
说明
方法二:
module.exports = {
pages: {
index: {
entry: 'src/main.js',
},
},
lintOnSave:false,
//开启代理服务器(方式二)
devServer: {
proxy: {
'/api1': {//请求前缀
target: 'http://localhost:5000',
pathRewrite:{'^/api1':''},//重写,把api1去掉
// ws: true, //用于支持websocket,默认为true
// changeOrigin: true //用于控制请求头中的host值,默认值为true
},
'/api2': {
target: 'http://localhost:5001',
pathRewrite:{'^/api2':''},
}
}
}
}
插槽:让父组件可以向子组件指定位置插入html结构,也是一种组件间通信的方式,
适用于 父组件 ===> 子组件
分类:默认插槽、具名插槽、作用域插槽
默认插槽:
父组件:
<Category title="美食" >
<img src="https://s3.ax1x.com/2021/01/16/srJlq0.jpg" alt="">
Category>
子组件:
<div class="category">
<h3>{{ title }}分类h3>
<slot>我是一些默认值,当使用者没有传递具体结构时,我会出现slot>
div>
具名插槽:
父组件:
<Category title="美食" >
<img slot="conter" src="https://s3.ax1x.com/2021/01/16/srJlq0.jpg" alt="">
<a slot="footer" href="http://www.atguigu.com">更多美食a>
Category>
子组件:
<div class="category">
<h3>{{title}}分类h3>
<slot name="center">我是一些默认值,当使用者没有传递具体结构时,我会出现1slot>
<slot name="footer">我是一些默认值,当使用者没有传递具体结构时,我会出现2slot>
div>
template>
作用域插槽:数据由子组件决定,结构由父组件决定。
父组件:
<Category title="游戏">
<template scope="atguigu">
<ul>
<li v-for="(g,index) in atguigu.games" :key="index">{{g}}</li>
</ul>
</template>
</Category>
子组件:
<div class="category">
<h3>{{title}}分类</h3>
<slot :games="games" msg="hello">我是默认的一些内容</slot>
</div>