vue学习

第一个 Vue 应用

文档

  • 导包

官方提供了两个包

  • 开发环境版本

  • 生产环境版本

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
    <!-- 开发环境版本 -->
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>

</body>
</html>
  • 采用模板语法来声明式地将数据渲染进 DOM 的系统
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
  {{ message }}
</div>
</body>
</html>
  • 创建VUE实例
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
    <!-- 开发环境版本 -->
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
  {{ message }}
</div>
</body>
<script type="text/javascript">
var app = new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue!'
  }
})
</script>
</html>


data

基本语法

数据绑定最常见的形式就是使用“Mustache(胡子)”语法 (双大括号) 的文本插值

<span>{{ message}}</span>

Mustache 标签将会被替代为对应数据对象上message属性的值。无论何时,绑定的数据对象上message属性发生了改变,插值处的内容都会更新

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
    <!-- 开发环境版本 -->
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
  <span>{{ message }}</span> <br>
</div>
</body>
<script type="text/javascript">
var app = new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue!'
  }
})
</script>
</html>

通过chrome浏览器的快捷键ctrl+shift+i或者F12来展示调试工具

我们也可以通过改变Vue的分隔符来修改Mustache 标签

v-bind绑定元素属性

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
    <!-- 开发环境版本 -->
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
  <span>{{ message }}</span> <br>
   <span v-bind:title="ads">鼠标悬停几秒钟查看此处动态绑定的提示信息!</span> <br>
   <a v-bind:href="home" target="_blank">戳我有惊喜</a>
</div>
</body>
<script type="text/javascript">
var app = new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue!',
    ads:'页面加载于 ' + new Date().toLocaleString(),
    home:'http://www.itcast.cn/'
  }
})
</script>
</html>

v-bind: 简写 :

文档

if条件渲染

通过条件指令可以控制元素的创建(显示)或者销毁(隐藏)

  • v-if

  • v-else-if

  • v-else

  • v-show

v-if

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
    <!-- 开发环境版本 -->
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
  <span>{{ message }}</span> <br>
   <span :title="ads">鼠标悬停几秒钟查看此处动态绑定的提示信息!</span> <br>
   <a :href="home" target="_blank" title="惊喜">戳我有惊喜</a> <br>  
   <p v-if="seen">现在你看到我了</p>
</div>
</body>
<script type="text/javascript">
var app = new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue!',
    ads:'页面加载于 ' + new Date().toLocaleString(),
    home:'http://www.itcast.cn/',
    seen:true,
  }
})
</script>
</html>

效果

v-if和v-else

文档

   <a href="#" v-if="islogin">个人中心</a>
   <a href="#" v-else>登录</a>

v-else要紧跟 v-if后边

v-if,v-else-if和v-else

文档

<img src="" alt="皇帝" v-if="level === 1">
<img src="" alt="皇亲" v-else-if="level === 2">
<img src="" alt="国戚" v-else-if="level === 3">
<img src="" alt="大臣" v-else>

v-show

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
    <!-- 开发环境版本 -->
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
   <p v-if="seen" id="if">现在你看到我了</p>
   <p v-show="seen" id="show">现在你看到我了</p>
</div>
</body>
<script type="text/javascript">
var app = new Vue({
  el: '#app',
  data: {
    seen:false
  }
})
</script>
</html>

效果

v-show用法和v-if大致一样,但是它不支持v-else,它和v-if的区别是,它制作元素样式的显示和隐藏,元素一直是存在的

注意在vue中使用v-show, 原来的css代码不能设置display属性, 会导致冲突

 

for列表渲染

文档

v-for指令可以绑定数组的数据来渲染一个项目列表

v-for指令需要使用item in items形式的特殊语法,items是源数据数组并且item是数组元素迭代的别名。

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
    <!-- 开发环境版本 -->
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
  <ol>
    <li v-for="todo in todos">
      {{ todo.text }}
    </li>
  </ol>
</div>
</body>
<script type="text/javascript">
var app = new Vue({
  el: '#app',
  data: {
   todos: [
      { text: '学习 JavaScript' },
      { text: '学习 Vue' },
      { text: '整个牛X项目' }
    ]
  }
})
</script>
</html>

效果

index

<ol>
  <li v-for="(todo,index) in todos">
    {{ todo.text }}-{{index}}
  </li>
</ol>

对象

文档

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
    <!-- 开发环境版本 -->
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
  <ul>
    <li v-for="value in object">
      {{ value }}
    </li>
  </ul>
</div>
</body>
<script type="text/javascript">
var app = new Vue({
  el: '#app',
  data: {
    object: {
      title: 'How to do lists in Vue',
      author: 'Jane Doe',
      publishedAt: '2016-04-10'
    }
  }
})
</script>
</html>

效果

对象列表

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
    <!-- 开发环境版本 -->
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
   <ul>
    <li v-for="item in items">
      {{ item.title }}~~~{{item.author}}~~~{{item.publishedAt}}
    </li>
  </ul>
</div>
</body>
<script type="text/javascript">
var app = new Vue({
  el: '#app',
  data: {
    items: [
       {
        title: 'Vue',
        author: 'Jane Doe',
        publishedAt: '2016-04-10'
      },
      {
        title: 'python',
        author: 'Ricky',
        publishedAt: '2019-04-10'
      },
      {
        title: 'itcast',
        author: 'itcast',
        publishedAt: '2006-05-08'
      }
    ]
  }
})
</script>
</html>

效果

 

methods事件

文档

可以用v-on指令监听 DOM 事件,并在触发时运行一些 JavaScript 代码。

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
    <!-- 开发环境版本 -->
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
  <button v-on:click="counter += 1">Add 1</button>
  <p>The button above has been clicked {{ counter }} times.</p>
</div>
</body>
<script type="text/javascript">
var app = new Vue({
  el: '#app',
  data: {
    counter:0
  }
})
</script>
</html>

效果

事件处理方法

然而许多事件处理逻辑会更为复杂,所以直接把 JavaScript 代码写在v-on指令中是不可行的。因此v-on还可以接收一个需要调用的方法名称

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
    <!-- 开发环境版本 -->
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
  <button v-on:click="add">Add 1</button>
</div>
</body>
<script type="text/javascript">
var app = new Vue({
  el: '#app',
  data: {
    counter:0
  },
  methods:{
    add:function(){
      counter+=1
      alert(this.counter)
    }
  }
})
</script>
</html>

事件处理方法传递参数

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
    <!-- 开发环境版本 -->
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
  <button v-on:click="addnum(counter)">Add {{counter}}</button> 
</div>
</body>
<script type="text/javascript">
var app = new Vue({
  el: '#app',
  data: {
    counter:1
  },
  methods:{
    addnum:function(num){
      this.counter = num+this.counter
      alert(this.counter)
    }
  }
})
</script>
</html>

v-on: 简写 @

model表单输入绑定(双向绑定数据)

  • 单行文本框

  • 多行文本框

  • 单选框

  • 多选框
  • 下拉框

文档

可以用v-model指令在表单<input><textarea><select>元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。尽管有些神奇。它负责监听用户的输入事件以更新数据,并对一些极端场景进行一些特殊处理。

v-model会忽略所有表单元素的valuecheckedselected特性的初始值而总是将 Vue 实例的数据作为数据来源。你应该通过 JavaScript 在组件的data选项中声明初始值

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
    <!-- 开发环境版本 -->
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
    <table border="1">
      <tr><td>用 户 名</td><td><input type="text" v-model="username" @blur="checkusername"> </td></tr>
      <tr><td>密码</td><td><input type="password" v-model="password1"> </td></tr>
      <tr><td>确认密码</td><td><input type="password" v-model="password2"></td></tr>
      <tr><td>性别</td>
        <td>
          男<input type="radio" name="sex"  value="boy" v-model="sex"> 
          女 <input type="radio" name="sex" value="girl" v-model="sex"></td>
        </tr>
      <tr><td>爱好</td>
        <td>
          足球 <input type="checkbox" name="like" value="足球" v-model="like"> 
          篮球 <input type="checkbox" name="like" value="篮球" v-model="like">
          兵乓球<input type="checkbox" name="like" value="兵乓球" v-model="like"> 
        </td>
      </tr>
      <tr><td>所在城市</td>
        <td>
          <select name="city" v-model="city">
            <option value="北京">北京</option>
            <option value="上海">上海</option>
            <option value="广州">广州</option>
            <option value="深圳">深圳</option>
          </select> 
        </td>
      </tr>
      <tr><td>个人简介</td><td><textarea name="desc" v-model="desc"></textarea> </td></tr>
    </table>
    <button @click="register">注册</button>
</div>
</body>
<script type="text/javascript">
var app = new Vue({
  el: '#app',
  data: {
      username:'',
      password1:'',
      password2:'',
      sex:'',
      like:[],
      city:'',
      desc:''

  },
  methods:{
    register:function(){

        alert(this.username+this.password1+this.password2+this.sex+this.like+this.city+this.desc)
    },
    checkusername:function(){
      alert(this.username)
    }
  }
})
</script>
</html>

Todolist案例

准备工作

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
    <!-- 开发环境版本 -->
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
   <input type="text"> <button>添加</button>
   <hr/>
   <ul>
     <li>1</li>
     <li>2</li>
     <li>3</li>
   </ul>
</div>
</body>
<script type="text/javascript">
var app = new Vue({
  el: '#app',
  data: {
      items:['学习Vue','学习Django基础','学习Django前台'],
  },
  methods:{

  }
})
</script>
</html>

列表数据渲染

 <ul>
     <li v-for="item in items">{{item}}</li>
 </ul>

绑定数据能够添加到列表中

<body>
<div id="app">
   <input type="text" v-model="newitem"> <button @click="addNetItem">添加</button>
   <hr/>
   <ul>
     <li v-for="item in items">{{item}}</li>
   </ul>
</div>
</body>
<script type="text/javascript">
var app = new Vue({
  el: '#app',
  data: {
      items:['学习Vue','学习Django基础','学习Django前台'],
      newitem:'',
  },
  methods:{
      addNetItem:function(){
        this.items.push(this.newitem);
        this.newitem='';
      }
  }
})
</script>
</html>

实现删除功能

<div id="app">
   <input type="text" v-model="newitem"> <button @click="addNetItem">添加</button>
   <hr/>
   <ul>
     <li v-for="(item,index) in items">
      <span>{{item}}</span> 
      <a href="javascript:;" @click="deleteItem(index)">删除</a>
     </li>
   </ul>
</div>
</body>
<script type="text/javascript">
var app = new Vue({
  el: '#app',
  data: {
      items:['学习Vue','学习Django基础','学习Django前台'],
      newitem:'',
  },
  methods:{
      addNetItem:function(){
        this.items.push(this.newitem);
        this.newitem='';
      },
      deleteItem:function(index){
        this.items.splice(index,1)
      }
  }
})
</script>
</html>

添加移动按钮,实现移动功能

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
    <!-- 开发环境版本 -->
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
   <input type="text" v-model="newitem"> <button @click="addNetItem">添加</button>
   <hr/>
   <ul>
     <li v-for="(item,index) in items">
     <a href="javascript:;" @click="upItem(index)">↑</a>
      <span>{{item}}</span> 
      <a href="javascript:;" @click="downItem(index)">↓</a>
      <a href="javascript:;" @click="deleteItem(index)">删除</a>
     </li>
   </ul>
</div>
</body>
<script type="text/javascript">
var app = new Vue({
  el: '#app',
  data: {
      items:['学习Vue','学习Django基础','学习Django前台'],
      newitem:'',
  },
  methods:{
      addNetItem:function(){
        this.items.push(this.newitem);
        this.newitem='';
      },
      deleteItem:function(index){
        this.items.splice(index,1);
      },
      upItem:function(index){
          current=this.items[index];
          this.items.splice(index,1);
          this.items.splice(index-1,0,current);
      },
      downItem:function(index){
          current=this.items[index];
          this.items.splice(index,1);
          this.items.splice(index+1,0,current);
      }
  }
})
</script>
</html>

 

ES6语法

ES6标准入门

ES6语法介绍

ES6是JavaScript语言的新版本,它也可以叫做ES2015,之前学习的JavaScript属于ES5,ES6在它的基础上增加了一些语法,ES6是未来JavaScript的趋势,而且vue组件开发中会使用很多的ES6的语法,所以掌握这些常用的ES6语法是必须的。

变量声明

var:它是用来声明变量的。如果在方法中声明,则为局部变量;如果在全局中声明,则为全局变量。

var num=10

变量一定要在声明后使用,否则报错

let:ES6新增了let命令,用来声明变量。它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效。

{
  let a = 10;
  var b = 1;
}

上面代码在代码块之中,分别用letvar声明了两个变量。然后在代码块之外调用这两个变量,结果let声明的变量报错,var声明的变量返回了正确的值。这表明,let声明的变量只在它所在的代码块有效。

for循环的计数器,就很合适使用let命令。

for (let i = 0; i < 10; i++) {}
计数器i只在for循环体内有效,在循环体外引用就会报错。

const:const声明一个只读的常量。一旦声明,常量的值就不能改变。

const PI = 3.1415;

Javascript对象的写法

ES5的写法

var person = { 
    name:'itcast',
    age:13,
    say:function(){
        alert('hello')
    }
}

person.say()

还可以写

var person = {};
person.name='itheima';
person.age=13;
person.say = function (){alert('hello')}
person.say();

ES6的写法

需要注意的是, 实现简写,有一个前提,必须变量名属性名一致

//定义变量
var name='itcast';
var age=13;
//创建对象
var person = {
    name,
    age,
    say:function(){
        alert('hello');
    }
};
//调用
person.say()

ES6的箭头函数

作用:

  • 定义函数新的方式
  • 改变this的指向

定义函数新的方式

//无参数,无返回值
var say = ()=> {
    alert('我是无参数无返回值函数');
}
//有参数,无返回值
var eat = food => {
    alert('我喜欢吃'+food);
}
//有参数,有返回值
var total = (num1,num2) => {
    return num1+num2;
}

改变this的指向

如果层级比较深的时候, this的指向就变成了window, 这时候就可以通过箭头函数解决这个指向的问题

var person = {
    name:'itcast',
    age:13,
    say:function(){
        alert('my name is ' + this.name);
    }
}
//调用
person.say()

axios发送ajax请求

axios github

准备工程

创建一个django工程,例如 login.创建完成之后,再创建一个子应用,例如users.最后再设置一下模板文件

准备html和html显示

在模板文件中创建一个axios.html,内容如下

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
    <!-- 开发环境版本 -->
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
  <span>{{ message }}</span> <br>
  <a href="javascript:;">登录</a> <br>
</div>
</body>
<script type="text/javascript">
var app = new Vue({
    el: '#app',
    delimiters:["[[","]]"],
    data: {
        message: 'Hello Vue!',
    },
})
</script>
</html>

创建视图并加载模板的html

#url设置
from django.conf.urls import url
from users.views import ShowLoginView

urlpatterns = [
    url(r'^show/$',ShowLoginView.as_view()),
]

#视图
class ShowLoginView(View):

    def get(self,request):

        return render(request,'axios.html')

导入axios,并发送GET/POST请求

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
    <!-- 开发环境版本 -->
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <!-- 导入axios -->
  <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
<div id="app">
  <span>{{ message }}</span> <br>
  <span>[[ message ]]</span> <br>
  <a @click="login" href="javascript:;">登录-GET</a> <br>
  <a @click="login2" href="javascript:;">登录-GET2</a> <br>
  <a @click="login3" href="javascript:;">登录-POST</a> <br>
</div>
</body>
<script type="text/javascript">
var app = new Vue({
    el: '#app',
    delimiters:["[[","]]"],
    data: {
        message: 'Hello Vue!',
    },
    methods:{
        login:function(){
            let url = 'http://127.0.0.1:8000/login/?username=admin&password=123';
            axios.get(url).then(response=>{
                if(response.data.code == '200'){
                  this.message=response.data.info.username;
                }else if (response.data.code == '400') {
                  this.message=response.data.msg;
                }
            }).catch(error=>{
              console.log(error)
            })
        },
        login2:function(){
            let url = 'http://127.0.0.1:8000/login/';
            axios.get(url,{
                params:{
                    "username":"admin",
                    "password":"123"
                }
            }).then(response=>{
                if(response.data.code == '200'){
                  this.message=response.data.info.username;
                }else if (response.data.code == '400') {
                  this.message=response.data.msg;
                }
            }).catch(error=>{
              console.log(error)
            })
        },
         login3:function(){
            let url = 'http://127.0.0.1:8000/login/';
            axios.post(url,{
                "username":"admin",
                "password":"123"
            }).then(response=>{
                if(response.data.code == '200'){
                  this.message=response.data.info.username;
                }else if (response.data.code == '400') {
                  this.message=response.data.msg;
                }
            }).catch(error=>{
              console.log(error)
            })
        }
    }
})
</script>
</html>

1.因为Vue的模板变量和django的模板变量分隔符冲突,所以需要修改Vue的分隔符delimiters:["[[","]]"]

2.箭头函数解决这个指向的问题

后台代码

#定义路由
from django.conf.urls import url
from users.views import ShowLoginView, LoginView

urlpatterns = [
    url(r'^show/$',ShowLoginView.as_view()),
    url(r'^login/$',LoginView.as_view()),
]
#定义视图
class LoginView(View):
    def get(self, request):
        #获取参数
        username = request.GET.get('username')
        password = request.GET.get('password')
        #验证参数并返回相应
        if username == 'admin' and password == '123':
            return JsonResponse({'code': 200, 'msg':'ok','info': {'username': username, 'user_id': '666'}})
        else:
            return JsonResponse({'code': 400,'msg':'账号或密码错误'})

    def post(self, request):
        # 获取参数
        data = json.loads(request.body.decode())
        username = data.get('username')
        password = data.get('password')
        # 验证参数并返回相应
        if username == 'admin' and password == '123':
            return JsonResponse({'code': 200, 'msg':'ok','info': {'username': username, 'user_id': '666'}})
        else:
            return JsonResponse({'code': 400,'msg':'账号或密码错误'})

 

Vue组件

组件(Component)是Vue.js最强大的功能之一。组件可以扩展 HTML 元素,封装可重用的代码。就像是python中封装一个类,在其他类中可以继承和调用类中的属性和方法。所有的 Vue 组件同时也都是 Vue 的实例,所以可接受相同的选项对象 (除了一些根级特有的选项) 并提供相同的生命周期钩子。

组件的基本使用

  • 全局组件的使用
<!DOCTYPE html>
<html lang="en">
<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">
    <script src="https://unpkg.com/vue/dist/vue.js"></script>
    <title>Document</title>
</head>
<body>

    <div id="app"> 
         <!-- 将组件名以标签的形式添加到div中,调用组件中的内容 -->
        <zujian_all></zujian_all>   
    </div>

 <script>
    // 全局组件通过 Vue.component注册
    Vue.component(
        'zujian_all',
        {   // template指定组件显示的html内容
            template:'<div>全局组件</div>',
        }
    )

    new Vue({
        el: '#app',
    })
   </script>
</body>
</html>

Vue.component()方法中参数说明

第一个参数指定组件名

第二参数以 {} 形式传递,在里面指定组件的属性,template指定组件的要加载的内容

  • 局部组件指定
<!DOCTYPE html>
<html lang="en">
<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">
    <script src="https://unpkg.com/vue/dist/vue.js"></script>
    <title>Document</title>
</head>
<body>

    <div id="app">
        <zujian_all></zujian_all>
    </div>

 <script>
    // 局部组件注册,定义局部组件
    var zujian_a={
        template:'<div>局部组件1</div>',
     };
    // 全局组件
    Vue.component(
        'zujian_all',
        {   // 在全局中调用局部组件
            template:'<div>全局组件  <zujian_a></zujian_a>  </div>',
            // components 将局部组件注册到全局组件中
                components:{
                zujian_a
            }
           }
    )

    new Vue({
        el: '#app',
    })

    </script>
</body>
</html>
  • 多个局部组件的使用
<!DOCTYPE html>
<html lang="en">
<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">
    <script src="https://unpkg.com/vue/dist/vue.js"></script>
    <title>Document</title>
</head>
<body>

    <div id="app">
        <zujian_all></zujian_all>
    </div>

 <script>
    // 局部组件注册,定义局部组件
    var zujian_a={
        template:'<div>局部组件1</div>',
     };
     var zujian_b={
        template:'<div>局部组件2</div>',
     };
    // 全局组件
    Vue.component(
        'zujian_all',
        {   // 在全局中调用局部组件
            template:'<div>全局组件  <zujian_a></zujian_a>  <zujian_b></zujian_b>  </div>',
            // components 将局部组件注册到全局组件中
                components:{
                zujian_a,
                zujian_b
            }
           }
    )

    new Vue({
        el: '#app',
    })
    </script>
</body>
</html>
  • 组间的关系
    • 组件中可以通过components嵌套另外的组件,比如可以在组件zujian_a中嵌套组件zujian_b
<!DOCTYPE html>
<html lang="en">
<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">
    <script src="https://unpkg.com/vue/dist/vue.js"></script>
    <title>Document</title>
</head>
<body>

    <div id="app">
        <zujian_all></zujian_all>
    </div>

 <script>
    // 局部组件注册,定义局部组件
    var zujian_b={
        template:'<div>局部组件2</div>',
     };

    var zujian_a={
        template:'<div>局部组件1   <zujian_b></zujian_b> </div>',
        components:{
            zujian_b
        }
     };

    // 全局组件
    Vue.component(
        'zujian_all',
        {   // 在全局中调用局部组件
            template:'<div>全局组件  <zujian_a></zujian_a>    </div>',
            // components 将局部组件注册到全局组件中
                components:{
                zujian_a
            }
           }
    )
    new Vue({
        el: '#app',
    })

    </script>
</body>
</html>

注意:

如果要进行组件嵌套,则必须先讲嵌套的组件定义出来,否则不生效,比如在组件zujian_a中嵌套zujian_b则必须先将zujian_b定义出来

组件中数据的绑定

在vue中数据通过data属性进行绑定,如下

<!DOCTYPE html>
<html lang="en">
<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">
    <script src="https://unpkg.com/vue/dist/vue.js"></script>
    <title>Document</title>
</head>
<body>
    <div id="app">

        {{name}}
    </div>
 <script>
    new Vue({
        el: '#app',
        data: {
            name:'python'
        }
    })

    </script>
</body>
</html>

在组件中进行数据绑定虽然也是通过data属性,但是对应的值不再是{}json形式,而是一个函数方法。如下

<!DOCTYPE html>
<html lang="en">
<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">
    <script src="https://unpkg.com/vue/dist/vue.js"></script>
    <title>Document</title>
</head>
<body>

    <div id="app">
        <zujian_all></zujian_all>
    </div>

 <script>
    // 局部组件注册,定义局部组件
    var zujian_a={
        template:'<div>局部组件1</div>',
     };
    // 全局组件
    Vue.component(
        'zujian_all',
        {   // 在全局中使用绑定的数据 {{name}}
            template:'<div>全局组件  <zujian_a></zujian_a> {{name}} </div>',
            // components 将局部组件注册到全局组件中
                components:{
                zujian_a,
            },
            // data属性指定绑定的数据内容,可以在当前的组件中进行使用
            data:function(){
                return {name:'python'}
            }
           }
    )

    new Vue({
        el: '#app',
    })
    </script>
</body>
</html>

组件传值

父组件给子组件传值,组件中通过props属性传递数据,如下:

<!DOCTYPE html>
<html lang="en">
<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">
    <script src="https://unpkg.com/vue/dist/vue.js"></script>
    <title>Document</title>
</head>
<body>

    <div id="app">
        <zujian_all></zujian_all>
    </div>

 <script>
    // 局部组件注册,定义局部组件
    var zujian_a={
        template:'<div>局部组件1 {{pos}} </div>',
        // 在子组件中通过props属性定义接受值的名称
        props:['pos']
     };

    // 全局组件
    Vue.component(
        'zujian_all',
        {   // 在全局组件中调用子组件时,通过v-bind指定子组件中pos接受父组件中的哪个值
            template:'<div>全局组件  <zujian_a v-bind:pos="name"></zujian_a>  </div>',
            // components 将局部组件注册到全局组件中
                components:{
                zujian_a,
            },
            // data属性指定绑定的数据内容,可以在当前的组件中进行使用
            data:function(){
                return {name:'python'}
            }
           }
    )

    new Vue({
        el: '#app',
    })
    </script>
</body>
</html>

子组件给父组件传值,通过$emi将数据传递个父组件

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Hello Ming</title>
    <script src="https://cdn.staticfile.org/vue/2.4.2/vue.min.js"></script>
    <script src="https://cdn.staticfile.org/vue-resource/1.5.1/vue-resource.min.js"></script>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>

    <div id='app'>
        <zujian_all></zujian_all>
    </div>

    <script>
        var zujian_a={ 
            template:'<div>  局部组件A  <button v-on:click="isupload"> 上传</button>  </div>',
            methods:{
                isupload:function(){
                    this.$emit('isListen','hello') // 子元素上的点击事件成功后,通过 $emit 将事件和数据传递给父组件
                }
            }
        }

        Vue.component('zujian_all',{

            template:'<div>  全局组件   <zujian_a v-on:isListen="isShow"></zujian_a> </div>',
            components:{
                zujian_a
            },
            methods:{
                isShow:function(data){
                    alert(data)  //data参数接受子组件传递的值
                }
            }
        })

        new Vue({
            el:'#app'
        })
    </script>
</body>
</html>

单文件组件

将一个组件相关的html结构,css样式,以及交互的JavaScript代码从html文件中剥离出来,合成一个文件,这种文件就是单文件组件,相当于一个组件具有了结构、表现和行为的完整功能,方便组件之间随意组合以及组件的重用,这种文件的扩展名为“.vue”,比如:"breadcrumb.vue"。

// 使用template标签来定义html部分
<template>
    <div :class="{crumb:true,hot:isHot}" @click="isHot=!isHot">
        当前位置是:{{ pos }}
    </div>
</template>

// javascript要写成模块导出的形式:
<script>
    export default{
        props:['pos'],
        data:function(){
            return {
                isHot:false                
            }
        }
    }
</script>

// 样式中如果有scope关键字,表示这些样式是组件局部的,不会影响其他元素
<style scoped>
.crumb{
    width:90%;
    line-height:50px;
    margin:0px auto;
    border-bottom:1px solid #ddd;
}
.hot{
    color:red;
    font-weight:bold;
    text-indent:10px;
}
</style>

环境配置

单文件组件不能直接运行使用,需要依赖node项目对其进行解析打包,在使用之前需要先进行环境配置

  1. 安装node版本管理工具nvm

    1. curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.11/install.sh | bash
      // 更新配置
      source .bashrc
      
  2. 安装最新版本的node

    1. nvm install node
      
  3. 更新npm的安装源

    1. npm config set registry https://registry.npm.taobao.org
      
  4. 创建项目目录

    1. mkdir project
      
  5. 进入项目目录,初始化项目目录

    1. cd project
      npm init
      
    2. 初始化完成后在当前目录中会生成一个package.json文件,该文件指定项目所以依赖的模块

  6. 配置package.json文件

    1. {
          "name": "project",
          "version": "1.0.0",
          "description": "",
          "main": "index.js",
          "scripts": {
              "test": "echo \"Error: no test specified\" && exit 1",
              "build": "webpack"
          },
          "keywords": [],
          "author": "",
          "license": "ISC",
          "dependencies": {
              "babel-core": "^6.22.1",
              "babel-loader": "^7.1.1",
              "babel-preset-env": "^1.3.2",
              "babel-preset-stage-2": "^6.22.0",
              "babel-register": "^6.22.0",
              "css-loader": "^0.28.11",
              "element-ui": "^2.7.2",
              "file-loader": "^1.1.4",
              "lodash": "^4.17.4",
              "style-loader": "^0.23.1",
              "url-loader": "^1.1.2",
              "vue": "^2.6.10",
              "vue-loader": "^15.7.0",
              "vue-router": "^3.0.2",
              "vue-style-loader": "^3.0.1",
              "vue-template-compiler": "^2.5.2",
              "webpack": "^4.29.6",
              "webpack-cli": "^3.3.0",
              "webpack-dev-server": "^3.2.1"
          }
      }
      
    2. g该文件定义了这个项目所需要的各种模块,以及项目的配置信息(比如名称、版本、许可证等元数据)。npm install 命令根据这个配置文件,自动下载所需的模块,也就是配置项目所需的运行和开发环境。

  7. 安装项目依赖模块

    1. npm install
      
  8. 创建项目文件 main.js ,index.html, App.vue

    1. touch index.html main.js App.vue. 
      
      可以借助vscode编辑工具创建文件
      
    2. index.html文件时项目的首页文件

    3. main.js 文件定义vue及调用单文件组件,也是项目打包时所依赖的文件

    4. App.vue文件为单文件组件文件

  9. 创建webpacke打包的配置文件webpack.config.js

    1. const path = require('path')
      const VueLoaderPlugin = require('vue-loader/lib/plugin');
      
      module.exports = {
          entry: { main: "./main.js" }, //入口文件
          output: {
              filename: 'index.js', //出口文件名
              path: path.resolve(__dirname), //当前目录
              library: 'index' // 打包后模块的名称
          },
          plugins: [
              // make sure to include the plugin for the magic
              new VueLoaderPlugin()
          ],
          module: {
              rules: [ //定义不同类型的文件使用的loader
                  {
                      test: /\.vue$/,
                      loader: 'vue-loader'
                  },
                  {
                      test: /\.js$/,
                      loader: 'babel-loader'
                  },
                  {
                      test: /\.css$/,
                      loader: 'vue-style-loader',
                  },
                  {
                      test: /\.css$/,
                      loader: 'css-loader',
                      options: {
                          minimize: true //添加
                      }
                  }, 
                  {
                      test: /\.(eot|svg|ttf|woff|woff2)$/,
                      loader: 'file-loader'
                    },
              ]
          }
      }
      
    2. 在通过webpack对项目进行打包时,需要指定相应的配置文件,同过配置文件对单文件组件中的各个内容进行解析,生成一个index.js的压缩文件,在index.html只需引该文件就可进行页面加载渲染

单文件组件的使用

项目搭建完成后需要分别对 main.js , index.html , App.vue 文件进行编写代码

index.html

<!DOCTYPE html>
<html lang="en">
<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>Document</title>
</head>
<body>
    <div id='app'><App></App></div>

    <!-- 引入打包后的index.js文件。该文件的名字不是固定名字,可以在webpack.config.js的出口文件中指定 -->
    <script src="./index.js"></script>
</body>
</html>

main.js

// 引入vue和App组件
import Vue from 'vue'
import App from './App.vue'

new Vue({
    el:'#app',
    // 渲染App组件中的内容,返回给index.html文件使用
    render:function(creater){
        return creater(App)
    }
})

App.vue

<template>
    <!-- 指定html显示内容 -->
    <div>单文件组件</div>
</template>


<script>
    // 指定js内容
// export default {

// }
</script>

<style>
/* 指定css内容 */
</style>

项目打包

文件编写完成后并不能直接运行index.html产生效果,需要对项目进行打包生成一个渲染后的index.js文件进行使用

npm run build

打包后会在当前目录下生成一个index.js 文件,在index.html中引用该文件,运行index.html文件看到效果

项目调试运行

每次我们需要看到组件效果需要手动生成一个index.js文件,这是我们可以借助webpack-dev-server自动运行我们的代码

// 在项目目录下,执行下面指令可以开启前端服务,自动运行前端代码
./node_modules/.bin/webpack-dev-server

多个单文件组件使用

在project目录下创建components文件夹,然后将所有子组件放入components文件夹下

Snip20190404_2

1、多组件嵌套使用

Child1.vue

<template>
    <div>子组件1</div>
</template>

<script>
// export default {

// }
</script>

<style>

</style>

Child2.vue

<template>
    <div>子组件2</div>
</template>

<script>
// export default {

// }
</script>

<style>

</style>

App.vue

<template>
    <div>
        单文件组件
        <!-- 调用子组件 -->
        <Child1></Child1>
        <Child2></Child2>
    </div>

</template>


<script>
    //导入components目录下的子文件 Child1为指定的组件名,可以任意命名,不一定按照文件名
import Child1 from './components/Child1.vue'
import Child2 from './components/Child2.vue'

export default {
    // 将子组件添加到App.vue中
    components:{
        Child1,
        Child2,

    }
}
</script>

<style>

</style>

2、多组件路由使用

使用路由形式将多个单文件组件组合在一起

  1. 定义路由目录和路由文件

    mkdir router
    touch router.js
    
  2. 编写路由文件router.js

    1. import Vue from 'vue'
      // 导入路由插件
      import Router from 'vue-router'
      import Child1 from '../components/Child1.vue'
      import Child2 from '../components/Child2.vue'
      // 在vue中使用插件
      Vue.use(Router)
      export default new Router({
          // 定义匹配规则
         routes:[
             {
                 path:'/',  // 匹配根路径/,加载Chiled1中的内容
                 component:Child1
             },
             {
                 path:'/child2',
                 component:Child2
             }
         ]
      })
      
  3. 在main.js中使用路由

    1. import Vue from 'vue'
      import App from './App.vue'
      //导入定义好的路由
      import router from './router/router.js'
      
      new Vue({
          el:'#app',
          router,  //使用路由
          render:function(creater){
              return creater(App)
          }
      })
      
  4. 在App.vue中指定路由标签

    1. <template>
          <div>
              单文件组件
               <!-- 记载路由标签 -->
              <router-view></router-view>
          </div>
      
      </template>
      
      <script>
      </script>
      
      <style>
      </style>
      

 

 

Element-ui

单文件组件就像是一个个封装好的页面样板,我们可一把这些样板组合在一起形成一个完整的页面。就像QQ空间装扮一样,将个个样板放入QQ空间页面中组成自己风格的页面。而Element-ui就将我们需要的样式封装成单文件组件,我们可以直接集成到我们的项目中。

  1. 在main.js中将emelent-ui引入到项目中

    1. import Vue from 'vue'
      import App from './App.vue'
      import router from './router/router.js'
      // 引入ElementUI
      import ElementUI from 'element-ui'
      // 引入css
      import 'element-ui/lib/theme-chalk/index.css'
      // 使用ElementUI
      Vue.use(ElementUI)
      
      new Vue({
          el:'#app',
          router,
          render:function(creater){
              return creater(App)
          }
      })
      
  2. 在子组件中使用element-ui的代码,

    1. <template>
      <div>
        <div class="block">
          <span class="demonstration">默认</span>
          <el-slider v-model="value1"></el-slider>
        </div>
        <div class="block">
          <span class="demonstration">自定义初始值</span>
          <el-slider v-model="value2"></el-slider>
        </div>
        <div class="block">
          <span class="demonstration">隐藏 Tooltip</span>
          <el-slider v-model="value3" :show-tooltip="false"></el-slider>
        </div>
        <div class="block">
          <span class="demonstration">格式化 Tooltip</span>
          <el-slider v-model="value4" :format-tooltip="formatTooltip"></el-slider>
        </div>
        <div class="block">
          <span class="demonstration">禁用</span>
          <el-slider v-model="value5" disabled></el-slider>
        </div>
      </div>
      </template>
      
      <script>
        export default {
          data() {
            return {
              value1: 0,
              value2: 50,
              value3: 36,
              value4: 48,
              value5: 42
            }
          },
          methods: {
            formatTooltip(val) {
              return val / 100;
            }
          }
        }
      </script>
      

 

 

 

Vue-cli的使用

我们的项目文件都是手动创建出来,在实际开发中我们可以借助vue-cli创建出我们的所有项目文件

  1. 全局安装vue-cli

    1. npm install --global vue-cli
      
  2. 项目创建

    1. vue init webpack 项目名
      
  3. 运行调试项目

    1. // 进入项目目录下,执行下面指令
      npm run dev
      
  4. 项目打包

    1. npm run build
      
项目目录结构

Snip20190404_5

  • 文件夹1(src),主开发目录,要开发的单文件组件全部在这个目录下
  • 文件夹2(static),静态资源目录,所有的css,js文件放在这个文件夹
  • 文件夹3(components),组件目录,vue格式的单文件组件都存在这个目录中
  • 文件夹4(router),路由目录,在此文件夹中配置组件路由

还有node_modules目录是node的包目录,config是配置目录,build是项目打包时依赖的目录。

  • 30
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值