1.初始vue小案例
一个容器对应一个实例;
{{name}}里面放的是js表达式;
容器里的东西被称为vue模板;
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<!-- 准备好一个容器 -->
<div id="root">
<h1>hello,{{name}}</h1>
</div>
<script type="text/javascript">
// 创建vue实例
new Vue({
// 用于指定当前vue实例为哪个容器服务,值通常为css选择器字符串;
el:'#root',
// data中用于存储数据,供el所选择的容器使用
data:{
name:'222'
}
})
2.模板语法
1.插值语法
{{name}}
2.指令语法
动态连接,加上:之后,后面”“里面的值就变成了js表达式;可以传入一个值;
<h1>指令语法</h1>
<a v-bind:href="url">123</a>
<a :href="url">123</a>
什么时候用他们呢?
插值语法:解析标签体;在标签体内;
指令语法:解析标签;标签属性内;
3.数据绑定
div id="root">
单向数据绑定:<input type="text" v-bind :value="name"><br/>
双向数据绑定:<input type="text" v-model: value="name">
</div>
单向数据绑定:<input type="text" :value="name"><br/>
双向数据绑定:<input type="text" v-model="name">
v-model详解
双向绑定只能用于表单类元素;当绑定的是checkbox类型,且值为布尔类型的时候,就能将值与是否选定绑定在一起;
3.组件相关
1.el和data的两种写法
el的:
// 方法一
new Vue({
el:'#root',
data:{
name:''
}
})
// 方法二,使用更加灵活一点
const v = new Vue({
data:{
name:''
}
})
v.$mount('#root')
data的:
推荐使用第二种模式;
const v = new Vue({
data:{
name:''
}
data:function(){
return{
name:''
}
}
})
4.MVVM模型
5.数据代理
Object.defineProperty方法
let number = 18
let person = {
name: '111',
sex:'12'
}
Object.defineProperty(person,'age',{
// value:18,
// // 可被枚举的
// enumerable:true,
// // 可以修改的
// writable:true,
// // 是否可以被删除
// configurable:true
get:function(){
return number
}
})
vue里的数据代理(没听懂)
6.事件代理
配置在data里面的数据会进行数据代理
<body>
<!-- 准备好一个容器 -->
<div id="root">
<h2>欢迎来到第{{day}}天</h2>
<button V-on:click = 'show'>点我一下~</button>
<button @click = 'show2($event,number)'>点我一下~</button>
</div>
</body>
<script type="text/javascript">
new Vue({
el:'#root',
data:{
day:'1'
},
methods:{
show(event){
alert('继续加油呀!')
},
show2(event,number){
alert('你已经很棒啦!')
}
}
})
事件修饰符
常见的事件修饰符;
<!-- 阻止事件的默认行为,比如跳转链接 -->
<button @click.prevent = 'show'></button>
<!-- 阻止事件冒泡 -->
<button @click.stop = 'show'></button>
<!-- 事件只能触发一次-->
<button @click.once = 'show'></button>
键盘事件
有一个特殊的键tab:
当按下的时候,就已经失去了对当前元素的焦点,所以对于tab键要用keydown绑定;
在js原生里面绑定用的是keycode获取键盘的编码,这里是在vue里面准备好的常用的几个键;
系统修饰键:CTRL,alt,shift,meta
keydown正常使用;
keyup:配合其他键一起使用,当其他键被按下时才会被触发;
<input type="text" placeholder="按下回车提示" @keyup.enter = 'show'>
7.属性
计算属性
get属性什么时候调用?初次读取full和值发生改变时;修改需要添加set属性;
计算属性必须有返回值;
computed:{
full:{
get(){
return this.first + this.last
}
}
}
简写:
full(){
return this.first + this.last
}
2.监视属性
切换天气小案例:
<body>
<div id="root">
<h2>今天天气很{{info}}</h2>
<button @click="change">点我切换天气哟~</button>
</div>
</body>
<script type="text/javascript">
new Vue({
el:'#root',
data:{
isHot:true
},
computed:{
info(){
return this.isHot ? '炎热' : '凉爽'
}
},
methods: {
change(){
this.isHot = !this.isHot
}
},
})
</script>
8.绑定样式
1.绑定class样式
字符串写法,适用于样式的类名不确定,需要动态指定;
<div id = '#root'>
<div class="basic" :class = 'mood' @click = 'changeMood'>{{name}}</div>
</div>
<script type="text/javascript">
new Vue({
el:'#root',
data:{
name:'111',
mood:'normal'
}
},
methods: {
changeMood(){
this.mood = 'happy'
}
},
)
**数组写法:**这种是类名不确定,使用个数也不确定;直接在data里面绑定;
<div class="basic" :class = 'classArr'>{{name}}</div>
</div>
<script type="text/javascript">
new Vue({
el:'#root',
data:{
name:'111',
mood:'normal',
classArr :[]
}
对象写法个数名字都确定,但是要动态绑定
<div class="basic" :class = 'classObj'>{{name}}</div>
</div>
<script type="text/javascript">
new Vue({
el:'#root',
data:{
name:'111',
mood:'normal',
classArr :[],
classObj:{
atu1:false,
atu2:false
}
总的来说就是给class绑定不一样的方法,造成不一样的效果;
2.绑定style样式(不常用)
跟上面类似;
<div class="basic" :style = 'styleObj'>{{name}}</div>
</div>
<script type="text/javascript">
new Vue({
el:'#root',
data:{
name:'111',
mood:'normal',
classArr :[],
classObj:{
atu1:false,
atu2:false
},
styleObj:{
fontSize:'40px'
}
9.渲染
条件渲染
显示样式,第二个是彻底删除;第一个是隐藏;
<h2 v-show = 'false'>12323</h2>
<h2 v-if = 'false'>12323</h2>
当第一个是的话,就不用判断接下来的语句了;
<h2 v-if = 'false'>12323</h2>
<h2 v-else-if = 'false'>12323</h2>
<h2 v-else-if = 'false'>12323</h2>
列表渲染
<ul>
<li v-for="p in personArr" ::key="p.id">{{p.name}}-{{p.age}}</li>
</ul>
</div>
<script type="text/javascript">
new Vue({
el:'#root',
data:{
personArr:[
{id:'001',name:'11',age:18},
{id:'002',name:'22',age:19},
{id:'003',name:'33',age:20}
]
}
})
v-for里面key的原理;挺重要的
用id作为key:
数据------>虚拟dom------>真实dom
当添加新的数据时,用diff算法对比一下;当有一样的数据时,会进行数据的复用,原来的就不会改了;
10.列表过滤
11.更新数据时的原理(没听懂吧)
vue如何检测对象临属性改变的?
数据代理;
1.加工数据
就是把数据里面的每一个数据都形成了get,set属性;
可以做响应式;数据变了页面也变;实现对对象里面属性的监视;
1.汇总对象中所i有属性形成一个数组,遍历
创建新的对象来做数据代理,避免自己代理自己,进入死循环;
12.vue指令
1.插入文本指令
第一个不能解析标签,第二个可以;
<div v-text = 'name'></div>
<div v-html = 'name'></div>
2.应对js阻塞情况的
<style>
[v-cloak]{
display: none;
}
</style>
</head>
<body>
<div id = "root">
<div v-cloak>{{name}}</div>
</div>
当vue托管代码时,会将这个属性移除,样式也就不会出现了;这样实现了他们的同时出现;
<h2 v-pre>123</h2>
<!-- 跳过这个的解析过程 -->
<div v-once>{{name}}</div>
<!-- 只在初次渲染时解析一次 -->
3.自定义指令(没学哦)
13.生命周期
又名生命周期回调函数;也称声明周期钩子;在关键时期调用的函数;生命周期函数中的this指向;
##0 14.组件化编程
组件就是实现应用中局部功能代码和资源的集合;
即封装的思想;
组件的意义:
1.非单文件组件
一个文件中包含多个组件;
// 创建school组件
const school = Vue.extend({
template:`
<div>
<h2>{{schoolName}}</h2>
<h2>{{address}}</h2>
<button>点我提示学校名</button>
</div>
`,
data(){
return {
schoolName :'1111',
address:'山西朔州'
}
}
})
// 创建学生组件
const student = Vue.extend({
template:`
<div>
<h2>{{studentName}}</h2>
<h2>{{age}}</h2>
</div>
`,
data(){
return {
studentName:'张三',
age:22
}
}
})
// 注册组件
new Vue({
el :'#root',
components:{
school,
student
}
})
</script>
2.组件的嵌套
const student = Vue.extends({
template:`
<div>
<h2>{{name}}</h2>
<h2>{{age}}</h2>
</div>
`,
data(){
return{
name,
age
}
}
})
// 创建学校组件
const school = Vue.extends({
template:`
<div>
<h2>{{schoolName}}</h2>
<h2>{{address}}</h2>
</div>
`,
data(){
return{
schoolName,
address
}
},
// 注册组件
components:{
student
}
})
// 创建学生组件
// 创建app组件
const app = Vue.extends({
components:{
school
}
})
// 创建vm
new Vue({
el:'#root',
components:{
app
}
})
</script>
3.Vuecomponent(不太会)
组件的本质是一个名为Vuecomponent的构造函数,是vue。extend生成的;每次调用返回的都是一个新的Vuecomponent;
4.一个重要的内置关系(好像明白了好像又没明白)
作用:让vc也能用vm身上的属性和方法;(?)
14.单文件组件
就是之前的模块化编程,多敲几遍就熟悉了;
15.脚手架
1.render
new Vue({
el:'#root',
// template:`<app></app>`,
// component:{app},2
render:h => h(app),
})
用render的时候引入的不是完整版的js,没有模板解析器,所以不能使用template配置项,需要使用render函数接收到的creatElement函数去指定具体内容;
2.ref属性
mplate>
<div>
<h1 v-text="msg" ref=""></h1>
<button @click="showDom">点我获取dom元素</button>
<school ref="sch"></school>
</div>
ref组件:
被用来给元素或者子组件注册引用信息(id的替换者);
在HTML上获取的是真实dom元素,在组件标签上是组件实例对象(vc)
3.props配置
<div>
<school name="xxx"/>
</div>
// 1.
props:['name','age','sex']
// 2.
props:{
name:String,
age:Number,
sex:String
}
// 3.
props:{
name:{
type:String,
required:true
// 是否是必须的?
},
age:{
type:Number,
default:99
// 默认值是99
}
}
功能:
让组件接受外部传来的数据;
传递数据,接收数据,
注意:
是只读的属性,如果确实可以修改,需要将数据复制到data中,修改date中的数据;
4.props详解
初步理解就是:子类想用父类的数据,但是子类不能直接访问,这个时候就需要通过props配置项来给让子类可以传到数据;单项数据流,当父类数据发生改变时,子类跟着改变,但是子类不能改变父类的数据;
mixin混入
1.局部混合
import {mixins,mixins2} from './mixin'
export default {
name:'School',
data() {
return {
schoolName:'不想上学',
addr:'随时随地'
}
},
mixins:[mixins,mixins2]
}
export const mixin = {
showName(){
alert(this.schoolName)
}
}
export const mixin2 = {
data() {
return {
x:100,
y:222
}
},
}
2.全局混合
4.插件
export default {
install(Vue){
// 全局过滤
Vue.filter()
// 定义全局指令
// 定义混入
// 给原型上添加一个方法;
}
}
import app from './app.vue'
import {mixin,mixin2} from './mixin'
import plugins from './plugins'
Vue.use(plugins)
16_scoped样式
<style scoped>
.demo{
background-color: pink;
}
</style>
局部使用,防止冲突;
17.浏览器本地存储
<button onclick="saveData()">点我保存一个本地数据</button>
<script type="text/javascript">
let p = {name:'111',age:19}
function saveData(){
localStorage.setItem('msg','hello')
localStorage.setItem('person',JSON.stringify(p))
}
</script>
18.组件自定义事件
是一种通信方式,适用于子组件给父组件传递数据;
1.绑定
2.通过父组件给子组件绑定一个自定义事件实现:
这个方法的第一步同上面那种方法,都是要先给父组件绑定一下;
第二步不太一样;
methods: {
sendStudentName(){
this.$emit('guigu',this.nmae)
}
},
3.同样是绑定,但是使用ref
ref组件:
被用来给元素或者子组件注册引用信息(id的替换者);
在HTML上获取的是真实dom元素,在组件标签上是组件实例对象(vc)
<student ref="student"/>
<!-- 通过这个可以获取student组件身上的实例对象 -->
</div>
</template>
<script>
export default {
props:[getStudentName],
methods: {
sendStudentName(){
this.$emit('guigu',this.nmae)
}
},
mounted() {
this.$refs.student.$on('guigu',this.getStudentName)
},
}
这种方法比较灵活;
上面那种绑定方法是把方法直接就绑定到student身上,但是这种方法是直接找到了他的实例对象,可以等等再绑定事件;
这样就更加灵活,可以等3秒再绑定;
mounted() {
setTimeout(()=>{
this.$refs.student.$on('guigu',this.getStudentName)
},3000)
},
2.解绑
unbind(){
this.$off('guigu')
// 只适用于解绑一个事件;
this.$off(['guigu','m1'])
// 解绑多个自定义事件
}
3.组件用原生事件
<button @click.native="show">解绑</button>
19.全局事件总线(还不是很清楚,很绕)
组件间的通信方式;
可以实现任意组件间的通信;
1.安装全局事件总线
new Vue({
el:'#app',
render: h => h(app),
beforeCreate() {
Vue.prototype.$bus = this
},
})
2.使用事件总线
mounted() {
this.$bus.$on('xxxx',this.demo)
},
提供事件的:
this.$bus.$on('xxxx',shuju)
20.消息订阅与发布(同样可以实现组件之间的通讯)
21.动画效果
如果想实现进入之间就是动画,可以加一个appear属性,同理,可以用这个方法,给h2追加一个x属性;默认不加name,样式里面就是v-
<transition name="hello" appear>
<h2 v-show = "isShow">你好</h2>
</transition>
.hello-enter-active{
animation-name: active 1s;
}
.hello-leave-active{
animation: donghua 1s reserve;
}
@keyframes active {
from{
transform: translateX(-100%);
}
to{
transform: translateX(0px);
}
}
2…过度效果
h1{
transition: 1s linear;
}
.hello-enter,.hello-leave-to{
transform: translateX(-100%);
}
.hello-enter-to,.hello-leave{
transform: translate(0);
}
/* 第二张方法 */
.hello-enter-active,.hello-leave-active{
transition: 1s;
}
3.多个元素过度
<transition-group name="hello" appear>
<h2 v-show = "isShow" key="1">你好</h2>
<h2 v-show = "isShow" key="2">你好</h2>
</transition-group>
4.集成第三方动画库;
22.配置代理
23.插槽
1.默认插槽
<div>
<h3>{{title}}</h3>
<slot></slot>
</div>
<Category title="美食" :listData="foods">
<img src="" alt="">
</Category>
<Category title="美食" :listData="foods">
<ul>
<li v-for="(item,index) in listData" key="index">{{item}}</li>
</ul>
</Category>
<Category title="美食" :listData="foods">
</Category>
2.具名插槽
五,vuex
多组件共享地址;veux不属于任何一个组件,彼此之间是双向传递的;