3.3.1 template的三种写法

template模板的编写有三种方式,分别是:

  • 字符串模板
  1. var vm = new Vue({
  2. el: '#app',
  3. template: '<div>模板字符串</div>'
  4. })
  • 选择符匹配元素的 innerHTML模板
  1. <div id="app">
  2. <div>test1</div>
  3. <script type="x-template" id="test">
  4. <p>test</p>
  5. </script>
  6. </div>
  7. var vm = new Vue({
  8. el: '#app',
  9. template: '#test'
  10. })
  • dom元素匹配元素的innerHTML模板
  1. <div id="app">
  2. <div>test1</div>
  3. <span id="test"><div class="test2">test2</div></span>
  4. </div>
  5. var vm = new Vue({
  6. el: '#app',
  7. template: document.querySelector('#test')
  8. })

模板编译的前提需要对template模板字符串的合法性进行检测,三种写法对应代码的三个不同分支。

  1. Vue.prototype.$mount = function () {
  2. ···
  3. if(!options.render) {
  4. var template = options.template;
  5. if (template) {
  6. // 针对字符串模板和选择符匹配模板
  7. if (typeof template === 'string') {
  8. // 选择符匹配模板,以'#'为前缀的选择器
  9. if (template.charAt(0) === '#') {
  10. // 获取匹配元素的innerHTML
  11. template = idToTemplate(template);
  12. /* istanbul ignore if */
  13. if (!template) {
  14. warn(
  15. ("Template element not found or is empty: " + (options.template)),
  16. this
  17. );
  18. }
  19. }
  20. // 针对dom元素匹配
  21. } else if (template.nodeType) {
  22. // 获取匹配元素的innerHTML
  23. template = template.innerHTML;
  24. } else {
  25. // 其他类型则判定为非法传入
  26. {
  27. warn('invalid template option:' + template, this);
  28. }
  29. return this
  30. }
  31. } else if (el) {
  32. // 如果没有传入template模板,则默认以el元素所属的根节点作为基础模板
  33. template = getOuterHTML(el);
  34. }
  35. }
  36. }
  37. // 判断el元素是否存在
  38. function query (el) {
  39. if (typeof el === 'string') {
  40. var selected = document.querySelector(el);
  41. if (!selected) {
  42. warn(
  43. 'Cannot find element: ' + el
  44. );
  45. return document.createElement('div')
  46. }
  47. return selected
  48. } else {
  49. return el
  50. }
  51. }
  52. var idToTemplate = cached(function (id) {
  53. var el = query(id);
  54. return el && el.innerHTML
  55. });

注意:其中X-Template模板的方式一般用于模板特别大的 demo 或极小型的应用,官方不建议在其他情形下使用,因为这会将模板和组件的其它定义分离开。